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
140 else if (cc==
'\t') col+=tabSize-(col%tabSize);
144 while ((cc=*ss++) && cc!=
'\n');
151 const char *startBuf = s;
154 auto &marker = kv.second;
155 s = gotoLine(startBuf,s,lineNr,marker.lines[0]+1);
156 lineNr=marker.lines[1];
157 const char *e = gotoLine(startBuf,s,marker.lines[0]+1,lineNr);
160 int minIndent=100000;
163 int indent = lineIndent(ss);
164 if (indent<minIndent)
167 if (minIndent==0)
break;
170 marker.indent = minIndent;
205 for (
const auto &s : examplePathList)
222 err(
"included file name '%s' is ambiguous.\nPossible candidates:\n%s\n",
qPrint(file),
230 err(
"included file %s is not found. Check your EXAMPLE_PATH\n",
qPrint(file));
240 bool showLineNumbers,
242 bool stripCodeComments
245 AUTO_TRACE(
"CodeFragmentManager::parseCodeFragment({},blockId={},scopeName={},showLineNumber={},trimLeft={},stripCodeComments={}",
246 fileName, blockId, scopeName, showLineNumbers, trimLeft, stripCodeComments);
247 std::string fragmentKey=fileName.
str()+
":"+scopeName.
str();
248 std::unordered_map< std::string,std::unique_ptr<Private::FragmentInfo> >::iterator it;
249 bool inserted =
false;
252 std::lock_guard lock(
p->mutex);
253 it =
p->fragments.find(fragmentKey);
254 if (it ==
p->fragments.end())
256 it =
p->fragments.emplace(fragmentKey, std::make_unique<Private::FragmentInfo>()).first;
262 auto &codeFragment = it->second;
263 std::lock_guard lock(codeFragment->mutex);
267 FileInfo cfi( fileName.
str() );
270 intf->resetCodeParserState();
272 bool needs2PassParsing =
274 !filterSourceFiles &&
278 if (needs2PassParsing)
280 OutputCodeList devNullList;
281 devNullList.
add<DevNullCodeGenerator>();
282 intf->parseCode(devNullList,
284 codeFragment->fileContents,
291 codeFragment->findBlockMarkers();
292 if (codeFragment->fileContents.length()>0)
294 intf->parseCode(codeFragment->recorderCodeList,
296 codeFragment->fileContents,
313 auto blockKv = codeFragment->blocksById.find(blockId.
str());
314 if (blockKv != codeFragment->blocksById.end())
316 const auto &marker = blockKv->second;
317 int startLine = marker->lines[0];
318 int endLine = marker->lines[1];
319 int indent = marker->indent;
320 AUTO_TRACE_ADD(
"replay(start={},end={},indent={}) fileContentsTrimLeft.empty()={}",
321 startLine,endLine,indent,codeFragment->fileContentsTrimLeft.isEmpty());
323 recorder->replay(codeOutList,
328 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
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)
std::unique_ptr< CodeParserInterface > getCodeParser(const QCString &extension)
Gets the interface to the parser associated with a given extension.
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.
const char * qPrint(const char *s)
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.