]>
git.proxmox.com Git - ceph.git/blob - ceph/src/zstd/contrib/gen_html/gen_html.cpp
2 * Copyright (c) 2016-present, Przemyslaw Skibinski, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
17 /* trim string at the beginning and at the end */
18 void trim(string
& s
, string characters
)
20 size_t p
= s
.find_first_not_of(characters
);
23 p
= s
.find_last_not_of(characters
);
24 if (string::npos
!= p
)
29 /* trim C++ style comments */
30 void trim_comments(string
&s
)
36 s
= s
.substr(spos
+3, epos
-(spos
+3));
40 /* get lines until a given terminator */
41 vector
<string
> get_lines(vector
<string
>& input
, int& linenum
, string terminator
)
47 while ((size_t)linenum
< input
.size()) {
48 line
= input
[linenum
];
50 if (terminator
.empty() && line
.empty()) { linenum
--; break; }
52 epos
= line
.find(terminator
);
53 if (!terminator
.empty() && epos
!=string::npos
) {
64 /* print line with ZSTDLIB_API removed and C++ comments not bold */
65 void print_line(stringstream
&sout
, string line
)
69 if (line
.substr(0,12) == "ZSTDLIB_API ") line
= line
.substr(12);
70 spos
= line
.find("/*");
71 if (spos
!=string::npos
) {
72 sout
<< line
.substr(0, spos
);
73 sout
<< "</b>" << line
.substr(spos
) << "<b>" << endl
;
75 // fprintf(stderr, "lines=%s\n", line.c_str());
81 int main(int argc
, char *argv
[]) {
83 int linenum
, chapter
= 1;
84 vector
<string
> input
, lines
, comments
, chapters
;
92 cout
<< "usage: " << argv
[0] << " [zstd_version] [input_file] [output_html]" << endl
;
96 version
= "zstd " + string(argv
[1]) + " Manual";
98 istream
.open(argv
[2], ifstream::in
);
99 if (!istream
.is_open()) {
100 cout
<< "Error opening file " << argv
[2] << endl
;
104 ostream
.open(argv
[3], ifstream::out
);
105 if (!ostream
.is_open()) {
106 cout
<< "Error opening file " << argv
[3] << endl
;
110 while (getline(istream
, line
)) {
111 input
.push_back(line
);
114 for (linenum
=0; (size_t)linenum
< input
.size(); linenum
++) {
115 line
= input
[linenum
];
117 /* typedefs are detected and included even if uncommented */
118 if (line
.substr(0,7) == "typedef" && line
.find("{")!=string::npos
) {
119 lines
= get_lines(input
, linenum
, "}");
121 for (l
=0; l
<lines
.size(); l
++) {
122 print_line(sout
, lines
[l
]);
124 sout
<< "</b></pre><BR>" << endl
;
128 /* comments of type /**< and /*!< are detected and only function declaration is highlighted (bold) */
129 if ((line
.find("/**<")!=string::npos
|| line
.find("/*!<")!=string::npos
) && line
.find("*/")!=string::npos
) {
131 print_line(sout
, line
);
132 sout
<< "</b></pre><BR>" << endl
;
136 spos
= line
.find("/**=");
137 if (spos
==string::npos
) {
138 spos
= line
.find("/*!");
139 if (spos
==string::npos
)
140 spos
= line
.find("/**");
141 if (spos
==string::npos
)
142 spos
= line
.find("/*-");
143 if (spos
==string::npos
)
144 spos
= line
.find("/*=");
145 if (spos
==string::npos
)
147 exclam
= line
[spos
+2];
151 comments
= get_lines(input
, linenum
, "*/");
152 if (!comments
.empty()) comments
[0] = line
.substr(spos
+3);
153 if (!comments
.empty()) comments
[comments
.size()-1] = comments
[comments
.size()-1].substr(0, comments
[comments
.size()-1].find("*/"));
154 for (l
=0; l
<comments
.size(); l
++) {
155 if (comments
[l
].find(" *")==0) comments
[l
] = comments
[l
].substr(2);
156 else if (comments
[l
].find(" *")==0) comments
[l
] = comments
[l
].substr(3);
157 trim(comments
[l
], "*-=");
159 while (!comments
.empty() && comments
[comments
.size()-1].empty()) comments
.pop_back(); // remove empty line at the end
160 while (!comments
.empty() && comments
[0].empty()) comments
.erase(comments
.begin()); // remove empty line at the start
162 /* comments of type /*! mean: this is a function declaration; switch comments with declarations */
164 if (!comments
.empty()) comments
.erase(comments
.begin()); /* remove first line like "ZSTD_XXX() :" */
166 lines
= get_lines(input
, linenum
, "");
169 for (l
=0; l
<lines
.size(); l
++) {
170 // fprintf(stderr, "line[%d]=%s\n", l, lines[l].c_str());
171 print_line(sout
, lines
[l
]);
174 for (l
=0; l
<comments
.size(); l
++) {
175 print_line(sout
, comments
[l
]);
177 sout
<< "</p></pre><BR>" << endl
<< endl
;
178 } else if (exclam
== '=') { /* comments of type /*= and /**= mean: use a <H3> header and show also all functions until first empty line */
179 trim(comments
[0], " ");
180 sout
<< "<h3>" << comments
[0] << "</h3><pre>";
181 for (l
=1; l
<comments
.size(); l
++) {
182 print_line(sout
, comments
[l
]);
184 sout
<< "</pre><b><pre>";
185 lines
= get_lines(input
, ++linenum
, "");
186 for (l
=0; l
<lines
.size(); l
++) {
187 print_line(sout
, lines
[l
]);
189 sout
<< "</pre></b><BR>" << endl
;
190 } else { /* comments of type /** and /*- mean: this is a comment; use a <H2> header for the first line */
191 if (comments
.empty()) continue;
193 trim(comments
[0], " ");
194 sout
<< "<a name=\"Chapter" << chapter
<< "\"></a><h2>" << comments
[0] << "</h2><pre>";
195 chapters
.push_back(comments
[0]);
198 for (l
=1; l
<comments
.size(); l
++) {
199 print_line(sout
, comments
[l
]);
201 if (comments
.size() > 1)
202 sout
<< "<BR></pre>" << endl
<< endl
;
204 sout
<< "</pre>" << endl
<< endl
;
208 ostream
<< "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n<title>" << version
<< "</title>\n</head>\n<body>" << endl
;
209 ostream
<< "<h1>" << version
<< "</h1>\n";
211 ostream
<< "<hr>\n<a name=\"Contents\"></a><h2>Contents</h2>\n<ol>\n";
212 for (size_t i
=0; i
<chapters
.size(); i
++)
213 ostream
<< "<li><a href=\"#Chapter" << i
+1 << "\">" << chapters
[i
].c_str() << "</a></li>\n";
214 ostream
<< "</ol>\n<hr>\n";
216 ostream
<< sout
.str();
217 ostream
<< "</html>" << endl
<< "</body>" << endl
;