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
- Separate content from presentation
- Modularize
- Declare new elements
- Put documents under revision control
- Use build tools
- Automatically extract content from source code
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 |
FID | INTEGER | File key (references FILES) |
FOFFSET | INTEGER | Offset within the file |
STRING | CHARACTER VARYING | The string, including its delimiters |
Table LINEPOS
Line number offsets within each file.
Field name |
Field type |
Value description |
FID | INTEGER | File key (references FILES) |
FOFFSET | INTEGER | Offset within the file |
LNUM | INTEGER | Line number (starts at 1) |
Table PROJECTS
Project details.
Field name |
Field type |
Value description |
PID | INTEGER | Unique project key |
NAME | CHARACTER VARYING | Project name |
Table FCALLS
Function calls.
Field name |
Field type |
Value description |
SOURCEID | INTEGER | Calling function identifier key (references FUNCTIONS) |
DESTID | INTEGER | Called function identifier key (references FUNCTIONS) |
Graph and Diagram Types
- Metrics
- Call graphs
- Class hierarchies
- Concrete object instances
- Data structures (trees, lists, and so on)
- Bit fields and corresponding masks in bit-mapped registers
- State transition diagrams
- Strings or arrays and corresponding indices or pointers
- Entity-relationship diagrams
Declarative Drawing Tools
UMLGraph Class Diagram
class Person {
String Name;
}
class Employee extends Person {}
class Client extends Person {}
Detailed 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);
|
|
Directory Hierarchies with dot
(Generated with a 50-line Perl script)
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
Memory Fragmentation Example
(Postscript generated by a Perl script and a custom new
operator.)
Stack Usage Example
(GNU Plot data generated by a custom function prologue.)
Map Example
(Generated by mining data from the CVS repository.)