home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1999 mARCH
/
PCWK3A99.iso
/
Linux
/
DDD331
/
DDD-3_1_.000
/
DDD-3_1_
/
ddd-3.1.1
/
vsllib
/
flowplus.vsl
< prev
next >
Wrap
Text File
|
1998-11-23
|
8KB
|
285 lines
// $Id: flowplus.vsl,v 1.7 1998/11/23 13:53:00 zeller Exp $ --
// Drawing flowcharts with gotos and labels
// Copyright (C) 1993 Technische Universitaet Braunschweig, Germany.
// Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
//
// This file is part of the DDD Library.
//
// The DDD Library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// The DDD Library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with the DDD Library -- see the file COPYING.LIB.
// If not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// DDD is the data display debugger.
// For details, see the DDD World-Wide-Web page,
// `http://www.cs.tu-bs.de/softech/ddd/',
// or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
#include "std.vsl"
#include "slopes.vsl"
#include "arcs.vsl"
// Extended flow charts
// Version
flowplus_version() = "$Revision: 1.7 $";
#include <flow.vsl>
#include <list.vsl>
// Data structures
//
// frag = (box, connect, labels, gotos)
//
// labels = (label, labels...)
//
// gotos = (label, labels...)
//
// label = (id, pos, stuff...)
//
// We have:
//
// box - the created picture
// connect - the distance of connecting lines and left side
// labels - the list of all labels
// gotos - the list of all gotos
// id - the id of a label
// pos - the distance of a label from upper-left corner
// Helpers
// frag(box) creates a fragment from a box
frag((box, connect, labels, gotos)) = (box, connect, labels, gotos);
frag(box) = fallbackFlow(box);
// searchLabel() searches a label named ID; returns () if not found
searchLabel(_, []) = ();
searchLabel(search, [label, labels...]) =
let (id, _...) = label in
if (search = id) then label else searchLabel(search, labels) fi;
// expandLines() expands the lines of labels and gotos.
expandLines([]) = 0;
expandLines([label, labels...]) =
let (_, pos, _...) = label in
(vspace(pos) | (vfix(hrule()) ^ hspace(flow_space()))) ^ expandLines(labels);
// drawConnect() connects two positions
drawConnectDown(start, end) =
vspace(start)
| vfix(hrule())
| hspace(flow_space()) & vrule() & vspace(end - start - 1)
| vfix(hrule());
drawConnectUp(start, end) =
vspace(end)
| vfix(hrule())
| hspace(flow_space()) & vrule() & vspace(start - end - 1)
| vfix(hrule());
drawConnect(start, end) =
if (start < end)
then drawConnectDown(start, end)
else drawConnectUp(start, end)
fi;
// connectGoto() connects a goto with a label; the goto is removed
// from the list
connectGoto(frag, _, []) = frag; // Label nicht gefunden
connectGoto(frag, goto, label) =
let (box, connect, labels, gotos) = frag,
(_, gotopos, _...) = goto,
(_, labelpos, _...) = label in
(newbox, connect, labels, select(gotos, goto))
where newbox = ((box & trailer)
where trailer = drawConnect(gotopos, labelpos)
^ expandLines(labels) ^ expandLines(gotos));
// resolveGoto() searches a specific goto und attempts a connection
resolveGoto(frag, goto) =
connectGoto(frag, goto, label)
where label =
(let (gotoid, _...) = goto, (_, _, labels, _) = frag
in searchLabel(gotoid, labels));
// _resolveGotos() calls resolveGoto() for all list elements
_resolveGotos(frag, []) = frag;
_resolveGotos(frag, [goto, gotos...]) =
_resolveGotos(resolveGoto(frag, goto), gotos);
// resolveGotos() resolves all references *within a fragment*; if
// successful, the goto is removed from the list and a path to the
// label is drawn.
resolveGotos(frag) =
let (_, _, _, gotos) = frag in
_resolveGotos(frag, gotos);
// moveLabels() moves a list of references down by OFFSET
moveLabels(_, []) = [];
moveLabels(offset, [label, labels...]) =
let (id, pos, ...) = label in
[(id, vspace(pos | offset), ...), moveLabels(offset, labels)...];
// joinFragments() joins two fragments, resolving all cross references
// (goto/label pairs)
joinTwoFragments(max, sep, f1, f2) =
let frag1 = frag(f1), frag2 = frag(f2) in
let newfrag =
align(frag1, max)
| align(sep, max) & hfill()
| align(frag2, max) in
let
(box1, _, labels1, gotos1) = frag1,
(_, _, labels2, gotos2) = frag2,
(sepbox, _) = sep,
voffset = vspace(box1 | sepbox),
newlabels = labels1 :: moveLabels(voffset, labels2),
newgotos = gotos1 :: moveLabels(voffset, gotos2) in
(newfrag, max, newlabels, newgotos);
joinFragments(_, frag1) = resolveGotos(frag(frag1));
joinFragments(sep, frag1, frag2) =
resolveGotos(joinTwoFragments(max_connect(frag1, frag2), sep, frag1, frag2));
joinFragments(sep, frag1, frag2, frag3, ...) =
joinFragments(sep,
joinFragments(sep, frag1, frag2), joinFragments(sep, frag3, ...));
// showRemainingGotos() displays remaining gotos and labels
tagLabel(pos, tag) =
vspace(pos - (tag / 2)) | tag;
tagLabels([]) = 0;
tagLabels([label, labels...]) =
let (id, pos, _...) = label in
let tag = veven(vcenter(hrule() | hspace(e_arrow())) & circle(id)) in
tagLabel(pos, tag) ^ tagLabels(labels);
tagGoto(pos, tag) =
vspace(pos - (tag / 2)) | tag;
tagGotos([]) = 0;
tagGotos([goto, gotos...]) =
let (id, pos, _...) = goto in
let tag = veven(vcenter(e_arrow()) & circle(id)) in
tagGoto(pos, tag) ^ tagGotos(gotos);
showRemainingGotos(frag) =
let (box, _, labels, gotos) = frag in
((box & trailer, 0, labels, gotos)
where trailer = tagLabels(labels) ^ tagGotos(gotos));
// removeLabels() removes labels from a fragment
// (e.g. they may not be visible outside a procedure)
removeLabels((box, connect, _, gotos)) =
(box, connect, [], gotos);
// labels and gotos
labelFlow(id) = frag
where frag = (box, connect, labels, gotos)
where box = vrule() & (veven(vfix(w_arrow())) | fill()),
connect = 0,
labels = [(id, vspace(veven(w_arrow()) / 2))],
gotos = [];
gotoFlow(id) = frag
where frag = (box, connect, labels, gotos)
where box = vrule() & (hrule() | fill()),
connect = 0,
labels = [],
gotos = [(id, 0)];
// Sequential list (of fragments or whatsoever)
// Fragment separator
_fragsep() = (vspace(flow_space() | flow_space()), 0);
// Fragment connector
_fragconnect() = (vrule() & vspace(flow_space()), 0);
fragFlow() = (0, 0, [], []);
fragFlow(frag) = frag;
// Ignore goto in goto/label pair
fragFlow(gotoFlow(id1), labelFlow(id2)) =
if (id1 = id2)
then fragFlow(labelFlow(id2))
else joinFragments(_fragconnect(), gotoFlow(id1), labelFlow(id2))
fi;
// Leave space after goto
fragFlow(gotoFlow(id), frag2) =
joinFragments(_fragsep(), gotoFlow(id), frag2);
// Otherwise: connect
fragFlow(frag1, frag2) =
joinFragments(_fragconnect(), frag1, frag2);
fragFlow(frag1, gotoFlow(id), ...) =
fragFlow(frag1, fragFlow(gotoFlow(id), ...));
fragFlow(frag1, frag2, ...) =
fragFlow(fragFlow(frag1, frag2), ...);
// outputFlow() should be called before each output
// (by defining __output() accordingly)
getBox((box, _, _, _)) = box;
outputFlow((box, connect, gotos, labels)) =
getBox(showRemainingGotos((box, connect, gotos, labels)));
outputFlow(box) = box;