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)
225 err(
"included file name '{}' is ambiguous.\nPossible candidates:\n{}\n",file,
234 err(
"included file {} is not found. Check your EXAMPLE_PATH\n",file);
244 bool showLineNumbers,
246 bool stripCodeComments
249 AUTO_TRACE(
"CodeFragmentManager::parseCodeFragment({},blockId={},scopeName={},showLineNumber={},trimLeft={},stripCodeComments={}",
250 fileName, blockId, scopeName, showLineNumbers, trimLeft, stripCodeComments);
251 std::string fragmentKey=fileName.
str()+
":"+scopeName.
str();
252 std::unordered_map< std::string,std::unique_ptr<Private::FragmentInfo> >::iterator it;
253 bool inserted =
false;
256 std::lock_guard lock(
p->mutex);
257 it =
p->fragments.find(fragmentKey);
258 if (it ==
p->fragments.end())
260 it =
p->fragments.emplace(fragmentKey, std::make_unique<Private::FragmentInfo>()).first;
266 auto &codeFragment = it->second;
267 std::lock_guard lock(codeFragment->mutex);
274 intf->resetCodeParserState();
276 bool needs2PassParsing =
278 !filterSourceFiles &&
282 if (needs2PassParsing)
286 intf->parseCode(devNullList,
288 codeFragment->fileContents,
295 codeFragment->findBlockMarkers();
296 if (codeFragment->fileContents.length()>0)
298 intf->parseCode(codeFragment->recorderCodeList,
300 codeFragment->fileContents,
317 auto blockKv = codeFragment->blocksById.find(blockId.
str());
318 if (blockKv != codeFragment->blocksById.end())
320 const auto &marker = blockKv->second;
321 int startLine = marker->lines[0];
322 int endLine = marker->lines[1];
323 int indent = marker->indent;
324 AUTO_TRACE_ADD(
"replay(start={},end={},indent={}) fileContentsTrimLeft.empty()={}",
325 startLine,endLine,indent,codeFragment->fileContentsTrimLeft.isEmpty());
327 recorder->
replay(codeOutList,
332 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 getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
QCString showFileDefMatches(const FileNameLinkedMap *fnMap, const QCString &n)
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
QCString detab(const QCString &s, size_t &refIndent)
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.