17#include <unordered_map>
53 std::unordered_map<std::string,std::unique_ptr<FragmentInfo> >
fragments;
67 const char *foundOpen=
nullptr;
68 std::unordered_map<std::string,BlockMarker> candidates;
75 else if (foundOpen && c==
']' && foundOpen+1<s)
77 std::string key(foundOpen+1,s-foundOpen-1);
78 candidates[key].lines.push_back(lineNr);
91 for (
auto &kv : candidates)
93 auto &marker = kv.second;
94 if (marker.lines.size()==2 && marker.lines[0]+1<=marker.lines[1]-1)
96 marker.key = kv.first;
97 int startLine = marker.lines[0];
98 blocks[startLine] = marker;
105 static auto gotoLine = [](
const char *startBuf,
const char *startPos,
int startLine,
int targetLine) ->
const char *
108 if (targetLine<startLine)
111 while (startLine>=targetLine && startPos>=startBuf && (cc=*startPos--)) {
if (cc==
'\n') startLine--; }
112 if (startPos>startBuf)
127 while (startLine<targetLine && (cc=*startPos++)) {
if (cc==
'\n') startLine++; }
132 static auto lineIndent = [](
const char *&ss,
int orgCol) ->
int
140 else if (cc==
'\t') col+=tabSize-(col%tabSize);
141 else if (cc==
'\n')
return orgCol;
145 while ((cc=*ss++) && cc!=
'\n');
152 const char *startBuf = s;
155 auto &marker = kv.second;
156 s = gotoLine(startBuf,s,lineNr,marker.lines[0]+1);
157 lineNr=marker.lines[1];
158 const char *e = gotoLine(startBuf,s,marker.lines[0]+1,lineNr);
161 int minIndent=100000;
162 int indent = minIndent;
165 indent = lineIndent(ss, indent);
166 if (indent<minIndent)
169 if (minIndent==0)
break;
172 marker.indent = minIndent;
207 for (
const auto &s : examplePathList)
224 err(
"included file name '{}' is ambiguous.\nPossible candidates:\n{}\n",file,
232 err(
"included file {} is not found. Check your EXAMPLE_PATH\n",file);
242 bool showLineNumbers,
244 bool stripCodeComments
247 AUTO_TRACE(
"CodeFragmentManager::parseCodeFragment({},blockId={},scopeName={},showLineNumber={},trimLeft={},stripCodeComments={}",
248 fileName, blockId, scopeName, showLineNumbers, trimLeft, stripCodeComments);
249 std::string fragmentKey=fileName.
str()+
":"+scopeName.
str();
250 std::unordered_map< std::string,std::unique_ptr<Private::FragmentInfo> >::iterator it;
251 bool inserted =
false;
254 std::lock_guard lock(
p->mutex);
255 it =
p->fragments.find(fragmentKey);
256 if (it ==
p->fragments.end())
258 it =
p->fragments.emplace(fragmentKey, std::make_unique<Private::FragmentInfo>()).first;
264 auto &codeFragment = it->second;
265 std::lock_guard lock(codeFragment->mutex);
272 intf->resetCodeParserState();
274 bool needs2PassParsing =
276 !filterSourceFiles &&
280 if (needs2PassParsing)
284 intf->parseCode(devNullList,
286 codeFragment->fileContents,
293 codeFragment->findBlockMarkers();
294 if (codeFragment->fileContents.length()>0)
296 intf->parseCode(codeFragment->recorderCodeList,
298 codeFragment->fileContents,
315 auto blockKv = codeFragment->blocksById.find(blockId.
str());
316 if (blockKv != codeFragment->blocksById.end())
318 const auto &marker = blockKv->second;
319 int startLine = marker->lines[0];
320 int endLine = marker->lines[1];
321 int indent = marker->indent;
322 AUTO_TRACE_ADD(
"replay(start={},end={},indent={}) fileContentsTrimLeft.empty()={}",
323 startLine,endLine,indent,codeFragment->fileContentsTrimLeft.isEmpty());
325 recorder->
replay(codeOutList,
330 trimLeft ?
static_cast<size_t>(indent) : 0
void parseCodeFragment(OutputCodeList &codeOutList, const QCString &fileName, const QCString &blockId, const QCString &scopeName, bool showLineNumbers, bool trimLeft, bool stripCodeComments)
static CodeFragmentManager & instance()
std::unique_ptr< Private > p
Class implementing OutputCodeIntf by throwing away everything.
static bool parseSourcesNeeded
static ParserManager * parserManager
static FileNameLinkedMap * exampleNameLinkedMap
A model of a file symbol.
virtual QCString absFilePath() const =0
Minimal replacement for QFileInfo.
std::string fileName() const
std::string dirPath(bool absPath=true) const
Class representing a list of different code generators.
void add(OutputCodeIntfPtr &&p)
Implementation that allows capturing calls made to the code interface to later invoke them on a Outpu...
void replay(OutputCodeList &ol, int startLine, int endLine, bool showLineNumbers, bool stripComment, size_t stripIndentAmount)
This is an alternative implementation of QCString.
bool isEmpty() const
Returns TRUE iff the string is empty.
const std::string & str() const
static QCString readTextFileByName(const QCString &file)
#define Config_getInt(name)
#define Config_getList(name)
#define Config_getBool(name)
std::vector< std::string > StringVector
#define AUTO_TRACE_ADD(...)
std::unique_ptr< FileDef > createFileDef(const QCString &p, const QCString &n, const QCString &ref, const QCString &dn)
bool isAbsolutePath(const QCString &fileName)
Portable versions of functions that are platform dependent.
OutputCodeList recorderCodeList
QCString fileContentsTrimLeft
std::map< std::string, const BlockMarker * > blocksById
std::map< int, BlockMarker > blocks
std::unordered_map< std::string, std::unique_ptr< FragmentInfo > > fragments
SrcLangExt
Language as given by extension.
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
QCString showFileDefMatches(const FileNameLinkedMap *fnMap, const QCString &n)
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
QCString getFileFilter(const QCString &name, bool isSourceCode)
QCString getFileNameExtension(const QCString &fn)
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
A bunch of utility functions.