1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-15 14:47:13 +02:00

Major plugin refactor and cleanup.

Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
This commit is contained in:
Sandu Liviu Catalin
2021-01-30 08:51:39 +02:00
parent e0e34b4030
commit 4a6bfc086c
6219 changed files with 1209835 additions and 454916 deletions

2490
vendor/POCO/PocoDoc/src/DocWriter.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

228
vendor/POCO/PocoDoc/src/DocWriter.h vendored Normal file
View File

@ -0,0 +1,228 @@
//
// DocWriter.h
//
// Definition of the DocWriter class.
//
// Copyright (c) 2005-2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef PocoDoc_DocWriter_INCLUDED
#define PocoDoc_DocWriter_INCLUDED
#include "Poco/CppParser/NameSpace.h"
#include "Poco/Logger.h"
#include <vector>
#include <set>
#include <ostream>
namespace Poco {
namespace CppParser {
class Symbol;
class Struct;
class Function;
class TypeDef;
class Enum;
class Variable;
} } // namespace Poco::CppParser
class DocWriter
/// Given a symbol table obtained from a CppParser, this
/// class writes reference documentation in HTML format
/// to a directory.
{
public:
DocWriter(const Poco::CppParser::NameSpace::SymbolTable& symbols, const std::string& path, bool prettifyCode = true, bool noFrames = false);
/// Creates the DocWriter.
~DocWriter();
/// Destroys the DocWriter.
void write();
/// Writes all documentation files.
void writeEclipseTOC();
/// Write Eclipse Table-Of-Contents XML files.
void addPage(const std::string& path);
/// Adds a page.
protected:
enum TextState
{
TEXT_PARAGRAPH,
TEXT_LIST,
TEXT_OLIST,
TEXT_LITERAL,
TEXT_WHITESPACE
};
struct Page
{
std::string path;
std::string fileName;
std::string title;
std::string category;
};
enum
{
MAX_TITLE_LEVEL = 3,
PAGE_INDEX_COLUMNS = 2,
NAMESPACE_INDEX_COLUMNS = 4
};
struct TOCEntry
{
std::string title;
int level;
int id;
};
typedef std::vector<TOCEntry> TOC;
typedef std::map<std::string, Poco::CppParser::Function*> MethodMap;
typedef std::map<std::string, std::string> StringMap;
typedef std::map<std::string, Page> PageMap;
void writePages();
void writePage(Page& page);
void scanTOC(const std::string& text, TOC& toc);
void writeTOC(std::ostream& ostr, const TOC& toc);
void writeCategoryIndex(const std::string& category, const std::string& fileName);
void writeCategoryIndex(std::ostream& ostr, const std::string& category, const std::string& target);
void writePageIndex(std::ostream& ostr);
void writeNameSpaceIndex(std::ostream& ostr);
void writeClass(const Poco::CppParser::Struct* pStruct);
void writeNameSpace(const Poco::CppParser::NameSpace* pNameSpace);
void writeNavigation();
void writePackage(const std::string& file, const std::string& library, const std::string& package);
std::string pathFor(const std::string& file);
static std::string fileNameFor(const Poco::CppParser::Symbol* pNameSpace);
static std::string baseNameFor(const Poco::CppParser::Symbol* pNameSpace);
static std::string uriFor(const Poco::CppParser::Symbol* pSymbol);
static std::string makeFileName(const std::string& str);
static std::string headerFor(const Poco::CppParser::Symbol* pSymbol);
static std::string titleFor(const Poco::CppParser::Symbol* pSymbol);
void writeHeader(std::ostream& ostr, const std::string& title, const std::string& extraScript = "");
void writeNavigationFrame(std::ostream& ostr, const std::string& group, const std::string& item);
static void writeFooter(std::ostream& ostr);
void writeCopyright(std::ostream& ostr);
static void writeTitle(std::ostream& ostr, const std::string& category, const std::string& title);
static void writeTitle(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace, const std::string& title);
static void writeSubTitle(std::ostream& ostr, const std::string& title);
static void beginBody(std::ostream& ostr);
static void endBody(std::ostream& ostr);
static void beginContent(std::ostream& ostr);
static void endContent(std::ostream& ostr);
void writeDescription(std::ostream& ostr, const std::string& text);
void writeDescriptionLine(std::ostream& ostr, const std::string& text, TextState& state);
void writeSummary(std::ostream& ostr, const std::string& text, const std::string& uri);
static std::string htmlize(const std::string& str);
static std::string htmlize(char c);
static TextState analyzeLine(const std::string& line);
static std::string htmlizeName(const std::string& name);
void writeText(std::ostream& ostr, const std::string& text);
void writeText(std::ostream& ostr, std::string::const_iterator begin, const std::string::const_iterator& end);
void writeDecl(std::ostream& ostr, const std::string& decl);
void writeDecl(std::ostream& ostr, std::string::const_iterator begin, const std::string::const_iterator& end);
bool writeSymbol(std::ostream& ostr, std::string& token, std::string::const_iterator& begin, const std::string::const_iterator& end);
bool writeSpecial(std::ostream& ostr, std::string& token, std::string::const_iterator& begin, const std::string::const_iterator& end);
void nextToken(std::string::const_iterator& it, const std::string::const_iterator& end, std::string& token);
void writeListItem(std::ostream& ostr, const std::string& text);
void writeOrderedListItem(std::ostream& ostr, const std::string& text);
void writeLiteral(std::ostream& ostr, const std::string& text);
void writeFileInfo(std::ostream& ostr, const Poco::CppParser::Symbol* pSymbol);
void writeInheritance(std::ostream& ostr, const Poco::CppParser::Struct* pStruct);
void writeMethodSummary(std::ostream& ostr, const Poco::CppParser::Struct* pStruct);
void writeNestedClasses(std::ostream& ostr, const Poco::CppParser::Struct* pStruct);
void writeNameSpacesSummary(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeNameSpaces(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeClassesSummary(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeClasses(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeClassSummary(std::ostream& ostr, const Poco::CppParser::Struct* pStruct);
void writeTypesSummary(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeAliasesSummary(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeTypes(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeAliases(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeType(std::ostream& ostr, const Poco::CppParser::TypeDef* pType);
void writeEnums(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeEnum(std::ostream& ostr, const Poco::CppParser::Enum* pEnum);
void writeConstructors(std::ostream& ostr, const Poco::CppParser::Struct* pStruct);
void writeDestructor(std::ostream& ostr, const Poco::CppParser::Struct* pStruct);
void writeMethods(std::ostream& ostr, const Poco::CppParser::Struct* pNameSpace);
void writeFunctionsSummary(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeFunctions(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeFunction(std::ostream& ostr, const Poco::CppParser::Function* pFunc);
void writeVariables(std::ostream& ostr, const Poco::CppParser::NameSpace* pNameSpace);
void writeVariable(std::ostream& ostr, const Poco::CppParser::Variable* pVar);
static void writeNameListItem(std::ostream& ostr, const std::string& name, const Poco::CppParser::Symbol* pSymbol, const Poco::CppParser::NameSpace* pNameSpace, bool& first);
static void writeLink(std::ostream& ostr, const std::string& uri, const std::string& text);
static void writeLink(std::ostream& ostr, const Poco::CppParser::Symbol* pSymbol, const std::string& text);
static void writeLink(std::ostream& ostr, const std::string& uri, const std::string& text, const std::string& linkClass);
void writeTargetLink(std::ostream& ostr, const std::string& uri, const std::string& text, const std::string& target);
static void writeImageLink(std::ostream& ostr, const std::string& uri, const std::string& image, const std::string& alt);
static void writeImage(std::ostream& ostr, const std::string& uri, const std::string& caption);
static void writeIcon(std::ostream& ostr, const std::string& icon);
static void writeAnchor(std::ostream& ostr, const std::string& text, const Poco::CppParser::Symbol* pSymbol);
static void writeDeprecated(std::ostream& ostr, const std::string& what);
void libraries(std::set<std::string>& libs);
void packages(const std::string& lib, std::set<std::string>& packages);
Poco::CppParser::NameSpace* rootNameSpace() const;
static const std::string& tr(const std::string& id);
static void loadStrings(const std::string& language);
static void loadString(const std::string& id, const std::string& def, const std::string& language);
static std::string projectURI(const std::string& id);
static Poco::Logger& logger();
static const std::string RFC_URI;
static const std::string GITHUB_POCO_URI;
private:
bool _prettifyCode;
bool _noFrames;
bool _htmlMode;
bool _literalMode;
const Poco::CppParser::NameSpace::SymbolTable& _symbols;
std::string _path;
const Poco::CppParser::NameSpace* _pNameSpace;
PageMap _pages;
bool _pendingLine;
int _indent;
int _titleId;
static std::string _language;
static StringMap _strings;
static Poco::Logger* _pLogger;
};
//
// inlines
//
inline Poco::Logger& DocWriter::logger()
{
poco_check_ptr (_pLogger);
return *_pLogger;
}
#endif // PocoDoc_DocWriter_INCLUDED

522
vendor/POCO/PocoDoc/src/PocoDoc.cpp vendored Normal file
View File

@ -0,0 +1,522 @@
//
// PocoDoc.cpp
//
// Copyright (c) 2005-2014, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/StringTokenizer.h"
#include "Poco/Glob.h"
#include "Poco/Path.h"
#include "Poco/File.h"
#include "Poco/DirectoryIterator.h"
#include "Poco/Process.h"
#include "Poco/Pipe.h"
#include "Poco/PipeStream.h"
#include "Poco/Environment.h"
#include "Poco/NumberFormatter.h"
#include "Poco/Exception.h"
#include "Poco/Stopwatch.h"
#include "Poco/DateTime.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/Timespan.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/Util/Application.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Util/AbstractConfiguration.h"
#include "Poco/CppParser/Parser.h"
#include "Poco/CppParser/NameSpace.h"
#include "Poco/CppParser/Struct.h"
#include "Poco/CppParser/Utility.h"
#include "DocWriter.h"
#include <set>
#include <utility>
#include <memory>
#include <fstream>
#include <sstream>
#include <iostream>
#include <clocale>
using Poco::StringTokenizer;
using Poco::Glob;
using Poco::Path;
using Poco::File;
using Poco::DirectoryIterator;
using Poco::Process;
using Poco::ProcessHandle;
using Poco::Environment;
using Poco::NumberFormatter;
using Poco::Exception;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::OptionCallback;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
class Preprocessor
{
public:
Preprocessor(const ProcessHandle& proc, std::istream* pStream):
_proc(proc),
_pStream(pStream)
{
}
Preprocessor(const ProcessHandle& proc, std::istream* pStream, const std::string& file):
_proc(proc),
_pStream(pStream),
_file(file)
{
}
std::istream& stream()
{
return *_pStream;
}
~Preprocessor()
{
int c = _pStream->get();
while (c != -1) c = _pStream->get();
delete _pStream;
_proc.wait();
if (!_file.empty())
{
try
{
File f(_file);
f.remove();
}
catch (Exception&)
{
}
}
}
private:
ProcessHandle _proc;
std::istream* _pStream;
std::string _file;
};
class PocoDocApp: public Application
{
public:
PocoDocApp():
_helpRequested(false),
_writeEclipseTOC(false)
{
std::setlocale(LC_ALL, "");
}
~PocoDocApp()
{
}
protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
Application::initialize(self);
}
void uninitialize()
{
Application::uninitialize();
}
void reinitialize(Application& self)
{
Application::reinitialize(self);
}
void defineOptions(OptionSet& options)
{
Application::defineOptions(options);
options.addOption(
Option("help", "h", "Display help information on command line arguments.")
.required(false)
.repeatable(false)
.callback(OptionCallback<PocoDocApp>(this, &PocoDocApp::handleHelp)));
options.addOption(
Option("config", "f", "Load configuration data from a file.")
.required(false)
.repeatable(true)
.argument("file")
.callback(OptionCallback<PocoDocApp>(this, &PocoDocApp::handleConfig)));
options.addOption(
Option("define", "D", "Define a configuration property.")
.required(false)
.repeatable(true)
.argument("name=value")
.callback(OptionCallback<PocoDocApp>(this, &PocoDocApp::handleDefine)));
options.addOption(
Option("eclipse", "e", "Write Eclipse TOC file.")
.required(false)
.repeatable(false)
.callback(OptionCallback<PocoDocApp>(this, &PocoDocApp::handleEclipse)));
}
void handleHelp(const std::string& name, const std::string& value)
{
_helpRequested = true;
displayHelp();
stopOptionsProcessing();
}
void handleDefine(const std::string& name, const std::string& value)
{
defineProperty(value);
}
void defineProperty(const std::string& def)
{
std::string name;
std::string value;
std::string::size_type pos = def.find('=');
if (pos != std::string::npos)
{
name.assign(def, 0, pos);
value.assign(def, pos + 1, def.length() - pos);
}
else name = def;
config().setString(name, value);
}
void handleEclipse(const std::string& name, const std::string& value)
{
_writeEclipseTOC = true;
}
void handleConfig(const std::string& name, const std::string& value)
{
loadConfiguration(value, -200);
}
void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader("POCO C++ Libraries documentation builder.");
helpFormatter.format(std::cout);
}
void buildFileList(std::set<std::string>& files)
{
std::set<std::string> temp;
std::string includes = config().getString("PocoDoc.files.include");
std::string excludes = config().getString("PocoDoc.files.exclude", "");
StringTokenizer incTokenizer(includes, ",\n", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
for (StringTokenizer::Iterator it = incTokenizer.begin(); it != incTokenizer.end(); ++it)
{
Glob::glob(*it, temp);
}
StringTokenizer excTokenizer(excludes, ",\n", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
for (std::set<std::string>::const_iterator it = temp.begin(); it != temp.end(); ++it)
{
Path p(*it);
bool include = true;
for (StringTokenizer::Iterator itg = excTokenizer.begin(); itg != excTokenizer.end(); ++itg)
{
Glob glob(*itg);
if (glob.match(p.getFileName()))
include = false;
}
if (include)
files.insert(*it);
}
}
Preprocessor* preprocess(const std::string& file)
{
Path pp(file);
pp.setExtension("i");
std::string comp = "PocoDoc.compiler";
std::string platformComp(comp);
if (Environment::isWindows())
platformComp += ".windows";
else
platformComp += ".unix";
std::string exec = config().getString(platformComp + ".exec", config().getString(comp + ".exec", ""));
std::string opts = config().getString(platformComp + ".options", config().getString(comp + ".options", ""));
std::string path = config().getString(platformComp + ".path", config().getString(comp + ".path", ""));
bool usePipe = config().getBool(platformComp + ".usePipe", config().getBool(comp + ".usePipe", false));
std::string popts;
for (std::string::const_iterator it = opts.begin(); it != opts.end(); ++it)
{
if (*it == '%')
popts += pp.getBaseName();
else
popts += *it;
}
StringTokenizer tokenizer(popts, ",\n", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
std::vector<std::string> args(tokenizer.begin(), tokenizer.end());
args.push_back(file);
if (!path.empty())
{
std::string newPath(Environment::get("PATH"));
newPath += Path::pathSeparator();
newPath += path;
Environment::set("PATH", path);
}
if (usePipe)
{
Poco::Pipe inPipe;
ProcessHandle proc = Process::launch(exec, args, 0, &inPipe, 0);
return new Preprocessor(proc, new Poco::PipeInputStream(inPipe));
}
else
{
ProcessHandle proc = Process::launch(exec, args);
proc.wait();
return new Preprocessor(proc, new std::ifstream(pp.getFileName().c_str()), pp.getFileName());
}
}
void parse(const std::string& file)
{
logger().information("Preprocessing " + file);
std::unique_ptr<Preprocessor> pPreProc(preprocess(file));
logger().information("Parsing " + file);
if (pPreProc->stream().good())
{
Poco::CppParser::Parser parser(_gst, file, pPreProc->stream());
parser.parse();
}
else throw Poco::OpenFileException("cannot read from preprocessor");
}
int parseAll()
{
int errors = 0;
std::set<std::string> files;
buildFileList(files);
for (std::set<std::string>::const_iterator it = files.begin(); it != files.end(); ++it)
{
try
{
parse(*it);
}
catch (Exception& exc)
{
logger().log(exc);
++errors;
}
}
return errors;
}
void fixup()
{
logger().information("Fixing-up class hierarchies");
for (Poco::CppParser::NameSpace::SymbolTable::iterator it = _gst.begin(); it != _gst.end(); ++it)
{
Poco::CppParser::Struct* pStruct = dynamic_cast<Poco::CppParser::Struct*>(it->second);
if (pStruct)
{
pStruct->fixupBases();
}
}
}
void writeDoc()
{
logger().information("Generating documentation");
Path path(config().getString("PocoDoc.output", "doc"));
path.makeDirectory();
File file(path);
file.createDirectories();
DocWriter writer(_gst, path.toString(), config().getBool("PocoDoc.prettifyCode", false), _writeEclipseTOC);
if (config().hasProperty("PocoDoc.pages"))
{
std::string pages = config().getString("PocoDoc.pages");
StringTokenizer tokenizer(pages, ",\n", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
std::set<std::string> pageSet;
for (StringTokenizer::Iterator it = tokenizer.begin(); it != tokenizer.end(); ++it)
{
Glob::glob(*it, pageSet);
}
for (std::set<std::string>::const_iterator it = pageSet.begin(); it != pageSet.end(); ++it)
{
writer.addPage(*it);
}
}
writer.write();
if (_writeEclipseTOC)
{
writer.writeEclipseTOC();
}
}
void copyResources()
{
logger().information("Copying resources");
Path path(config().getString("PocoDoc.output", "doc"));
if (config().hasProperty("PocoDoc.resources"))
{
std::string pages = config().getString("PocoDoc.resources");
StringTokenizer tokenizer(pages, ",\n", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
std::set<std::string> pageSet;
for (StringTokenizer::Iterator it = tokenizer.begin(); it != tokenizer.end(); ++it)
{
Glob::glob(*it, pageSet);
}
for (std::set<std::string>::const_iterator it = pageSet.begin(); it != pageSet.end(); ++it)
{
try
{
copyResource(Path(*it), path);
}
catch (Poco::Exception& exc)
{
logger().log(exc);
}
}
}
}
void copyResource(const Path& source, const Path& dest)
{
logger().information(std::string("Copying resource ") + source.toString() + " to " + dest.toString());
File sf(source);
if (sf.isDirectory())
copyDirectory(source, dest);
else
copyFile(source, dest);
}
void copyFile(const Path& source, const Path& dest)
{
Path dd(dest);
dd.makeDirectory();
File df(dd);
df.createDirectories();
dd.setFileName(source.getFileName());
if (source.getExtension() == "thtml")
{
dd.setExtension("html");
std::ifstream istr(source.toString().c_str());
std::ofstream ostr(dd.toString().c_str());
while (istr.good())
{
std::string line;
std::getline(istr, line);
ostr << config().expand(line) << std::endl;
}
}
else
{
File sf(source);
sf.copyTo(dd.toString());
}
}
void copyDirectory(const Path& source, const Path& dest)
{
Path src(source);
src.makeFile();
DirectoryIterator it(src);
DirectoryIterator end;
for (; it != end; ++it)
{
Path dd(dest);
dd.makeDirectory();
dd.pushDirectory(src.getFileName());
copyResource(it.path(), dd);
}
}
int main(const std::vector<std::string>& args)
{
if (!_helpRequested)
{
Poco::DateTime now;
config().setString("PocoDoc.date", Poco::DateTimeFormatter::format(now, "%Y-%m-%d"));
config().setString("PocoDoc.year", Poco::DateTimeFormatter::format(now, "%Y"));
config().setString("PocoDoc.googleAnalyticsCode", generateGoogleAnalyticsCode());
Poco::Stopwatch sw;
int errors = 0;
try
{
sw.start();
errors = parseAll();
fixup();
writeDoc();
copyResources();
sw.stop();
}
catch (Exception& exc)
{
std::cerr << exc.displayText() << std::endl;
}
logger().information(NumberFormatter::format(errors) + " errors.");
logger().information(std::string("Time: ") + Poco::DateTimeFormatter::format(Poco::Timespan(sw.elapsed())));
}
return Application::EXIT_OK;
}
std::string generateGoogleAnalyticsCode()
{
std::stringstream ostr;
std::string googleAnalyticsId(config().getString("PocoDoc.googleAnalyticsId", ""));
if (!googleAnalyticsId.empty())
{
ostr << "<!-- Begin Google Analytics -->\n";
ostr << "<script type=\"text/javascript\">\n";
ostr << "var gaJsHost = ((\"https:\" == document.location.protocol) ? \"https://ssl.\" : \"http://www.\");\n";
ostr << "document.write(unescape(\"%3Cscript src='\" + gaJsHost + \"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E\"));\n";
ostr << "</script>\n";
ostr << "<script type=\"text/javascript\">\n";
ostr << "try {\n";
ostr << "var pageTracker = _gat._getTracker(\"" << googleAnalyticsId << "\");\n";
ostr << "pageTracker._trackPageview();\n";
ostr << "} catch(err) {}</script>\n";
ostr << "<!-- End Google Analytics -->\n";
}
return ostr.str();
}
private:
bool _helpRequested;
bool _writeEclipseTOC;
Poco::CppParser::NameSpace::SymbolTable _gst;
};
int main(int argc, char** argv)
{
PocoDocApp app;
try
{
app.init(argc, argv);
}
catch (Poco::Exception& exc)
{
app.logger().log(exc);
return Application::EXIT_CONFIG;
}
return app.run();
}