/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under both the BSD-style license (found in the * LICENSE file in the root directory of this source tree) and the GPLv2 (found * in the COPYING file in the root directory of this source tree). */ #include #include #include #include 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 get_lines(vector& input, int& linenum, string terminator) { vector out; string line; size_t epos; while ((size_t)linenum < input.size()) { line = input[linenum]; if (terminator.empty() && line.empty()) { linenum--; break; } 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 ZSTDLIB_API removed and C++ comments not bold */ void print_line(stringstream &sout, string line) { size_t spos; if (line.substr(0,12) == "ZSTDLIB_API ") line = line.substr(12); spos = line.find("/*"); if (spos!=string::npos) { sout << line.substr(0, spos); sout << "" << line.substr(spos) << "" << endl; } else { // fprintf(stderr, "lines=%s\n", line.c_str()); sout << line << endl; } } int main(int argc, char *argv[]) { char exclam; int linenum, chapter = 1; vector input, lines, comments, chapters; string line, version; size_t spos, l; stringstream sout; ifstream istream; ofstream ostream; if (argc < 4) { cout << "usage: " << argv[0] << " [zstd_version] [input_file] [output_html]" << endl; return 1; } version = "zstd " + 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 << "
";
            for (l=0; l

" << 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 << "
";
            print_line(sout, line);
            sout << "

" << 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"; for (l=0; l

"; for (l=0; l
" << endl << endl; } else if (exclam == '=') { /* comments of type /*= and /**= mean: use a

header and show also all functions until first empty line */ trim(comments[0], " "); sout << "

" << comments[0] << "

";
            for (l=1; l
";
            lines = get_lines(input, ++linenum, "");
            for (l=0; l
" << endl; } else { /* comments of type /** and /*- mean: this is a comment; use a

header for the first line */ if (comments.empty()) continue; trim(comments[0], " "); sout << "

" << comments[0] << "

";
            chapters.push_back(comments[0]);
            chapter++;

            for (l=1; l 1)
                sout << "
" << endl << endl; else sout << "
" << endl << endl; } } ostream << "\n\n\n" << version << "\n\n" << endl; ostream << "

" << version << "

\n"; ostream << "
\n

Contents

\n
    \n"; for (size_t i=0; i" << chapters[i].c_str() << "\n"; ostream << "
\n
\n"; ostream << sout.str(); ostream << "" << endl << "" << endl; return 0; }