1 /*
2 * (C) Copyright 2008-2015 Diomidis Spinellis
3 *
4 * This file is part of CScout.
5 *
6 * CScout is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CScout is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CScout. If not, see <http://www.gnu.org/licenses/>.
18 *
19 *
20 * HTML utility functions
21 *
22 */
23
24 #include <map>
25 #include <string>
26 #include <deque>
27 #include <vector>
28 #include <stack>
29 #include <iterator>
30 #include <iostream>
31 #include <fstream>
32 #include <list>
33 #include <set>
34 #include <utility>
35 #include <functional>
36 #include <algorithm> // set_difference
37 #include <cctype>
38 #include <sstream> // ostringstream
39 #include <cstdio> // perror, rename
40 #include <cstdlib> // atoi
41 #include <cerrno> // errno
42
43 #include "swill.h"
44 #include "getopt.h"
45
46 #include "cpp.h"
47 #include "debug.h"
48 #include "error.h"
49 #include "parse.tab.h"
50 #include "attr.h"
51 #include "metrics.h"
52 #include "fileid.h"
53 #include "tokid.h"
54 #include "token.h"
55 #include "ptoken.h"
56 #include "fchar.h"
57 #include "pltoken.h"
58 #include "macro.h"
59 #include "pdtoken.h"
60 #include "eclass.h"
61 #include "ctoken.h"
62 #include "type.h"
63 #include "stab.h"
64 #include "fdep.h"
65 #include "version.h"
66 #include "call.h"
67 #include "html.h"
68 #include "fileutils.h"
69 #include "option.h"
70
71 /*
72 * Return as a C string the HTML equivalent of character c
73 * Handles tab-stop expansion provided all output is processed through this
74 * function
75 */
76 const char *
html(char c)77 html(char c)
78 {
79 static char str[2];
80 static int column = 0;
81 static vector<string> spaces(0);
82 int space_idx;
83
84 switch (c) {
85 case '&': column++; return "&";
86 case '<': column++; return "<";
87 case '>': column++; return ">";
88 case '"': column++; return """;
89 case ' ': column++; return " ";
90 case '\t':
91 if ((int)(spaces.size()) != Option::tab_width->get()) {
92 spaces.resize(Option::tab_width->get());
93 for (int i = 0; i < Option::tab_width->get(); i++) {
94 string t;
95 for (int j = 0; j < Option::tab_width->get() - i; j++)
96 t += " ";
97 spaces[i] = t;
98 }
99 }
100 space_idx = column % Option::tab_width->get();
101 if (DP())
102 cout << "Tab; " << " column before:" << column << " space_idx: " << space_idx << endl;
103 column += 8 - space_idx;
104 return spaces[space_idx].c_str();
105 case '\n':
106 column = 0;
107 return "<br>\n";
108 case '\r':
109 column = 0;
110 return "";
111 case '\f':
112 column = 0;
113 return "<br><hr><br>\n";
114 default:
115 column++;
116 str[0] = c;
117 return str;
118 }
119 }
120
121 // HTML-encode the given string
122 string
html(const string & s)123 html(const string &s)
124 {
125 string r;
126
127 for (string::const_iterator i = s.begin(); i != s.end(); i++)
128 r += html(*i);
129 return r;
130 }
131
132 // Output s as HTML in of
133 void
html_string(FILE * of,string s)134 html_string(FILE *of, string s)
135 {
136 for (string::const_iterator i = s.begin(); i != s.end(); i++)
137 fputs(html(*i), of);
138 }
139
140
141 // Create a new HTML file with a given filename and title
142 // The heading, if not given, will be the same as the title
143 void
html_head(FILE * of,const string fname,const string title,const char * heading)144 html_head(FILE *of, const string fname, const string title, const char *heading)
145 {
146 swill_title(title.c_str());
147 if (DP())
148 cerr << "Write to " << fname << endl;
149 fprintf(of,
150 "<!doctype html public \"-//IETF//DTD HTML//EN\">\n"
151 "<html>\n"
152 "<head>\n"
153 "<meta name=\"GENERATOR\" content=\"CScout %s - %s\">\n",
154 Version::get_revision().c_str(),
155 Version::get_date().c_str());
156 fputs(
157 "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\">"
158 "<style type=\"text/css\" >"
159 "<!--\n", of);
160
161 ifstream in;
162 string css_fname;
163 if (cscout_input_file("style.css", in, css_fname)) {
164 int val;
165 while ((val = in.get()) != EOF)
166 putc(val, of);
167 } else
168 fputs(
169 #include "css.c"
170 , of);
171 fputs(
172 "-->"
173 "</style>"
174 "</head>", of);
175 fprintf(of,
176 "<title>%s</title>\n"
177 "</head>\n"
178 "<body>\n"
179 "<h1>%s</h1>\n",
180 title.c_str(),
181 heading ? heading : title.c_str());
182 }
183
184 // And an HTML file end
185 void
html_tail(FILE * of)186 html_tail(FILE *of)
187 {
188 extern Attributes::size_type current_project;
189
190 if (current_project)
191 fprintf(of, "<p> <b>Project %s is currently selected</b>\n", Project::get_projname(current_project).c_str());
192 fprintf(of,
193 "<p>"
194 "<a href=\"index.html\">Main page</a>\n"
195 " — Web: "
196 "<a href=\"http://www.spinellis.gr/cscout\">Home</a>\n"
197 "<a href=\"http://www.spinellis.gr/cscout/doc/index.html\">Manual</a>\n"
198 "<br><hr><div class=\"footer\">CScout %s — %s",
199 Version::get_revision().c_str(),
200 Version::get_date().c_str());
201 fprintf(of, " — Licensed under the GNU General Public License.");
202 fprintf(of, "</div></body></html>\n");
203 }
204
205 // Return a function's label, based on the user's preferences
206 string
file_label(Fileid f,bool hyperlink)207 file_label(Fileid f, bool hyperlink)
208 {
209 string result;
210 char buff[256];
211
212 if (hyperlink) {
213 snprintf(buff, sizeof(buff), "<a href=\"file.html?id=%d\">", f.get_id());
214 result = buff;
215 }
216 switch (Option::fgraph_show->get()) {
217 case 'p': // Show complete paths
218 result += f.get_path() + "/";
219 /* FALLTHROUGH */
220 case 'n': // Show only file names
221 result += f.get_fname();
222 break;
223 case 'e': // Show only edges
224 result += " ";
225 break;
226 }
227 if (hyperlink)
228 result += "</a>";
229 return (result);
230 }
231
232 // Return a function's label, based on the user's preferences
233 string
function_label(Call * f,bool hyperlink)234 function_label(Call *f, bool hyperlink)
235 {
236 string result;
237 char buff[256];
238
239 if (hyperlink) {
240 snprintf(buff, sizeof(buff), "<a href=\"fun.html?f=%p\">", f);
241 result = buff;
242 }
243 if (Option::show_function_type->get()) {
244 if (f->is_file_scoped())
245 result += "static:";
246 else
247 result += "public:";
248 }
249 if (Option::cgraph_show->get() == 'f') // Show files
250 result += f->get_site().get_fileid().get_fname() + ":";
251 else if (Option::cgraph_show->get() == 'p') // Show paths
252 result += f->get_site().get_fileid().get_path() + ":";
253 if (Option::cgraph_show->get() != 'e') // Empty labels
254 result += f->get_name();
255 if (hyperlink)
256 result += "</a>";
257 return (result);
258 }
259
260 // Display a system error on the HTML output.
261 void
html_perror(FILE * of,const string & user_msg,bool svg)262 html_perror(FILE *of, const string &user_msg, bool svg)
263 {
264 string error_msg(user_msg + ": " + string(strerror(errno)) + "\n");
265 fputs(error_msg.c_str(), stderr);
266 if (svg)
267 fprintf(of, "<?xml version=\"1.0\" ?>\n"
268 "<svg>\n"
269 "<text x=\"20\" y=\"50\" >%s</text>\n"
270 "</svg>\n", error_msg.c_str());
271 else {
272 fputs(error_msg.c_str(), of);
273 fputs("</p><p>The operation you requested is incomplete. "
274 "Please correct the underlying cause, and (if possible) return to the "
275 "CScout <a href=\"index.html\">main page</a> to retry the operation.</p>", of);
276 }
277 }
278
279 // Display a non-system error on the HTML output.
280 void
html_error(FILE * of,const string & error_msg)281 html_error(FILE *of, const string &error_msg)
282 {
283 fputs(error_msg.c_str(), stderr);
284 fputs(error_msg.c_str(), of);
285 fputs("</p><p>The operation you requested is incomplete. "
286 "Please correct the underlying cause, and (if possible) return to the "
287 "CScout <a href=\"index.html\">main page</a> to retry the operation.</p>", of);
288 }
289