249 lines
8.4 KiB
C++
249 lines
8.4 KiB
C++
|
/*
|
||
|
Copyright (c) 2016-present, Przemyslaw Skibinski
|
||
|
All rights reserved.
|
||
|
|
||
|
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without
|
||
|
modification, are permitted provided that the following conditions are
|
||
|
met:
|
||
|
|
||
|
* Redistributions of source code must retain the above copyright
|
||
|
notice, this list of conditions and the following disclaimer.
|
||
|
* Redistributions in binary form must reproduce the above
|
||
|
copyright notice, this list of conditions and the following disclaimer
|
||
|
in the documentation and/or other materials provided with the
|
||
|
distribution.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
You can contact the author at :
|
||
|
- LZ4 homepage : http://www.lz4.org
|
||
|
- LZ4 source repository : https://github.com/lz4/lz4
|
||
|
*/
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <fstream>
|
||
|
#include <sstream>
|
||
|
#include <vector>
|
||
|
using namespace std;
|
||
|
|
||
|
|
||
|
/* trim string at the beginning and at the end */
|
||
|
void trim(string& s, string characters)
|
||
|
{
|
||
|
size_t p = s.find_first_not_of(characters);
|
||
|
s.erase(0, p);
|
||
|
|
||
|
p = s.find_last_not_of(characters);
|
||
|
if (string::npos != p)
|
||
|
s.erase(p+1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* trim C++ style comments */
|
||
|
void trim_comments(string &s)
|
||
|
{
|
||
|
size_t spos, epos;
|
||
|
|
||
|
spos = s.find("/*");
|
||
|
epos = s.find("*/");
|
||
|
s = s.substr(spos+3, epos-(spos+3));
|
||
|
}
|
||
|
|
||
|
|
||
|
/* get lines until a given terminator */
|
||
|
vector<string> get_lines(vector<string>& input, int& linenum, string terminator)
|
||
|
{
|
||
|
vector<string> out;
|
||
|
string line;
|
||
|
|
||
|
while ((size_t)linenum < input.size()) {
|
||
|
line = input[linenum];
|
||
|
|
||
|
if (terminator.empty() && line.empty()) { linenum--; break; }
|
||
|
|
||
|
size_t const epos = line.find(terminator);
|
||
|
if (!terminator.empty() && epos!=string::npos) {
|
||
|
out.push_back(line);
|
||
|
break;
|
||
|
}
|
||
|
out.push_back(line);
|
||
|
linenum++;
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* print line with LZ4LIB_API removed and C++ comments not bold */
|
||
|
void print_line(stringstream &sout, string line)
|
||
|
{
|
||
|
size_t spos, epos;
|
||
|
|
||
|
if (line.substr(0,11) == "LZ4LIB_API ") line = line.substr(11);
|
||
|
if (line.substr(0,12) == "LZ4FLIB_API ") line = line.substr(12);
|
||
|
spos = line.find("/*");
|
||
|
epos = line.find("*/");
|
||
|
if (spos!=string::npos && epos!=string::npos) {
|
||
|
sout << line.substr(0, spos);
|
||
|
sout << "</b>" << line.substr(spos) << "<b>" << '\n';
|
||
|
} else {
|
||
|
sout << line << '\n';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int main(int argc, char *argv[]) {
|
||
|
char exclam;
|
||
|
int linenum, chapter = 1;
|
||
|
vector<string> input, lines, comments, chapters;
|
||
|
string line, version;
|
||
|
size_t spos, l;
|
||
|
stringstream sout;
|
||
|
ifstream istream;
|
||
|
ofstream ostream;
|
||
|
|
||
|
if (argc < 4) {
|
||
|
cout << "usage: " << argv[0] << " [lz4_version] [input_file] [output_html]" << endl;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
version = string(argv[1]) + " Manual";
|
||
|
|
||
|
istream.open(argv[2], ifstream::in);
|
||
|
if (!istream.is_open()) {
|
||
|
cout << "Error opening file " << argv[2] << endl;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
ostream.open(argv[3], ifstream::out);
|
||
|
if (!ostream.is_open()) {
|
||
|
cout << "Error opening file " << argv[3] << endl;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
while (getline(istream, line)) {
|
||
|
input.push_back(line);
|
||
|
}
|
||
|
|
||
|
for (linenum=0; (size_t)linenum < input.size(); linenum++) {
|
||
|
line = input[linenum];
|
||
|
|
||
|
/* typedefs are detected and included even if uncommented */
|
||
|
if (line.substr(0,7) == "typedef" && line.find("{")!=string::npos) {
|
||
|
lines = get_lines(input, linenum, "}");
|
||
|
sout << "<pre><b>";
|
||
|
for (l=0; l<lines.size(); l++) {
|
||
|
print_line(sout, lines[l]);
|
||
|
}
|
||
|
sout << "</b></pre><BR>" << endl;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* comments of type / * * < and / * ! < are detected, and only function declaration is highlighted (bold) */
|
||
|
if ((line.find("/**<")!=string::npos || line.find("/*!<")!=string::npos)
|
||
|
&& line.find("*/")!=string::npos) {
|
||
|
sout << "<pre><b>";
|
||
|
print_line(sout, line);
|
||
|
sout << "</b></pre><BR>" << endl;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
spos = line.find("/**=");
|
||
|
if (spos==string::npos) {
|
||
|
spos = line.find("/*!");
|
||
|
if (spos==string::npos)
|
||
|
spos = line.find("/**");
|
||
|
if (spos==string::npos)
|
||
|
spos = line.find("/*-");
|
||
|
if (spos==string::npos)
|
||
|
spos = line.find("/*=");
|
||
|
if (spos==string::npos)
|
||
|
continue;
|
||
|
exclam = line[spos+2];
|
||
|
}
|
||
|
else exclam = '=';
|
||
|
|
||
|
comments = get_lines(input, linenum, "*/");
|
||
|
if (!comments.empty()) comments[0] = line.substr(spos+3);
|
||
|
if (!comments.empty())
|
||
|
comments[comments.size()-1] = comments[comments.size()-1].substr(0, comments[comments.size()-1].find("*/"));
|
||
|
for (l=0; l<comments.size(); l++) {
|
||
|
if (comments[l].compare(0, 2, " *") == 0)
|
||
|
comments[l] = comments[l].substr(2);
|
||
|
else if (comments[l].compare(0, 3, " *") == 0)
|
||
|
comments[l] = comments[l].substr(3);
|
||
|
trim(comments[l], "*-=");
|
||
|
}
|
||
|
while (!comments.empty() && comments[comments.size()-1].empty()) comments.pop_back(); // remove empty line at the end
|
||
|
while (!comments.empty() && comments[0].empty()) comments.erase(comments.begin()); // remove empty line at the start
|
||
|
|
||
|
/* comments of type / * ! mean: this is a function declaration; switch comments with declarations */
|
||
|
if (exclam == '!') {
|
||
|
if (!comments.empty()) comments.erase(comments.begin()); /* remove first line like "LZ4_XXX() :" */
|
||
|
linenum++;
|
||
|
lines = get_lines(input, linenum, "");
|
||
|
|
||
|
sout << "<pre><b>";
|
||
|
for (l=0; l<lines.size(); l++) {
|
||
|
print_line(sout, lines[l]);
|
||
|
}
|
||
|
sout << "</b><p>";
|
||
|
for (l=0; l<comments.size(); l++) {
|
||
|
print_line(sout, comments[l]);
|
||
|
}
|
||
|
sout << "</p></pre><BR>" << endl << endl;
|
||
|
} else if (exclam == '=') { /* comments of type / * = and / * * = mean: use a <H3> header and show also all functions until first empty line */
|
||
|
trim(comments[0], " ");
|
||
|
sout << "<h3>" << comments[0] << "</h3><pre>";
|
||
|
for (l=1; l<comments.size(); l++) {
|
||
|
print_line(sout, comments[l]);
|
||
|
}
|
||
|
sout << "</pre><b><pre>";
|
||
|
lines = get_lines(input, ++linenum, "");
|
||
|
for (l=0; l<lines.size(); l++) {
|
||
|
print_line(sout, lines[l]);
|
||
|
}
|
||
|
sout << "</pre></b><BR>" << endl;
|
||
|
} else { /* comments of type / * * and / * - mean: this is a comment; use a <H2> header for the first line */
|
||
|
if (comments.empty()) continue;
|
||
|
|
||
|
trim(comments[0], " ");
|
||
|
sout << "<a name=\"Chapter" << chapter << "\"></a><h2>" << comments[0] << "</h2><pre>";
|
||
|
chapters.push_back(comments[0]);
|
||
|
chapter++;
|
||
|
|
||
|
for (l=1; l<comments.size(); l++) {
|
||
|
print_line(sout, comments[l]);
|
||
|
}
|
||
|
if (comments.size() > 1)
|
||
|
sout << "<BR></pre>" << endl << endl;
|
||
|
else
|
||
|
sout << "</pre>" << endl << endl;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
ostream << "<h1>" << version << "</h1>\n";
|
||
|
|
||
|
ostream << "<hr>\n<a name=\"Contents\"></a><h2>Contents</h2>\n<ol>\n";
|
||
|
for (size_t i=0; i<chapters.size(); i++)
|
||
|
ostream << "<li><a href=\"#Chapter" << i+1 << "\">" << chapters[i].c_str() << "</a></li>\n";
|
||
|
ostream << "</ol>\n<hr>\n";
|
||
|
|
||
|
ostream << sout.str();
|
||
|
ostream << "</html>" << endl << "</body>" << endl;
|
||
|
|
||
|
return 0;
|
||
|
}
|