1 /*
2     This file is part of GNU APL, a free implementation of the
3     ISO/IEC Standard 13751, "Programming Language APL, Extended"
4 
5     Copyright (C) 2008-2017  Dr. Jürgen Sauermann
6 
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 #ifndef __DOXY_HH_DEFINED__
21 #define __DOXY_HH_DEFINED__
22 
23 #include "UCS_string.hh"
24 #include "UCS_string_vector.hh"
25 #include "UTF8_string.hh"
26 
27 #include <ostream>
28 #include <vector>
29 
30 using namespace std;
31 
32 class UserFunction;
33 
34 //-----------------------------------------------------------------------------
35 /// one endge in a (directed) function call graph
36 struct fcall_edge
37 {
38    /// default constructor
fcall_edgefcall_edge39    fcall_edge()
40    : caller(0),
41      caller_name(0),
42      callee(0),
43      callee_name(0),
44      value(0)
45    {}
46 
47    /// constructor
fcall_edgefcall_edge48    fcall_edge(const UserFunction * cer, const UCS_string * cer_name,
49               const UserFunction * cee, const UCS_string * cee_name )
50    : caller(cer),
51      caller_name(cer_name),
52      callee(cee),
53      callee_name(cee_name),
54      value(0)
55    {}
56 
57    /// the calling function
58    const UserFunction * caller;
59 
60    /// the (Symbol-) name of the calling function
61    const UCS_string * caller_name;
62 
63    /// the called function
64    const UserFunction * callee;
65 
66    /// the (Symbol-) name of called function
67    const UCS_string * callee_name;
68 
69    /// some arbitrary int used in graph algorithms
70    int      value;
71 };
72 
73 typedef std::vector<fcall_edge> CallGraph;
74 
75 //-----------------------------------------------------------------------------
76 /// implementation of the ]Doxy command.
77 class Doxy
78 {
79 public:
80    /// Constructor: create (and remember) the root directory
81    Doxy(ostream & out, const UCS_string & root_dir);
82 
83    /// generate the entire documentation
84    void gen();
85 
86    /// HTML-print a table with all functions to 'page'
87    void functions_table(const std::vector<const Symbol *> & functions,
88                        ofstream & page);
89 
90    /// HTML-print a table with all variables to 'page'
91    void variables_table(const std::vector<const Symbol *> & variables,
92                         ofstream & page);
93 
94    /// HTML-print a table with the SI stack to 'page'
95    void SI_table(ofstream & page);
96 
97    /// return the number of errors that have occurred
get_errors() const98    int get_errors() const
99       { return errors; }
100 
101    /// return the directory into which all documenattion files will be written
get_root_dir() const102    const UTF8_string & get_root_dir() const
103       { return root_dir; }
104 
105 protected:
106    /// write a fixed CSS file
107    void write_css();
108 
109    /// (HTML-)print a function header with the name in bold to file of
110    void bold_name(ostream & of, const UserFunction * ufun) const;
111 
112    /// write the page for one defined function. If the define function is a
113    /// named lambda, then lambda_owner is the Symbol to which the lambda was
114    /// assigned.
115    void function_page(const UserFunction * ufun, const UCS_string & alias);
116 
117    /// create the call graph
118    void make_call_graph(const std::vector<const Symbol *> & all_funs);
119 
120    /// add one symbol to the call graph. Note that one symbol can have different
121    /// UserFunctions at different SI levels.
122    void add_fun_to_call_graph(const Symbol * sym, const UserFunction * ufun);
123 
124    /// make the call graph start from root ufun and set nodes to nodes that are
125    /// reachable from the root
126    void set_call_graph_root(const UserFunction * ufun);
127 
128    /// write the call graph (if caller == false), or else the caller graph
129    int write_call_graph(const UserFunction * ufun, const UCS_string & alias,
130                         bool caller);
131 
132    /// swap callers and callees
133    void swap_caller_calee();
134 
135    /// return the index of \b ufun in \b nodes[] or -1 if not found
136    int node_ID(const UserFunction * ufun);
137 
138    /// return an HTML-anchor for function \b name (in the output files)
139    static UCS_string fun_anchor(const UCS_string & name);
140 
141    /// convert a .gv file to a .png file using program 'dot'
142    int gv_to_png(const char * gv_filename, const char * png_filename,
143                  bool cmapx);
144 
145    /// the command output channel (COUR or CERR)
146    ostream & out;
147 
148    /// the name of the workspace (for HTML output)
149    UCS_string ws_name;
150 
151    /// the directory that shall contain all documentation files
152    UTF8_string root_dir;
153 
154    /// the nodes for the current root.
155    std::vector<const UserFunction *> nodes;
156 
157    /// the real names for the current root.
158    UCS_string_vector aliases;
159 
160    /// a directed graph telling which function calles which
161    CallGraph call_graph;
162 
163    /// the number of errors that have occurred
164    int errors;
165 };
166 //-----------------------------------------------------------------------------
167 #endif // __DOXY_HH_DEFINED__
168