17#include <unordered_map>
54 std::unordered_map<std::string,std::unique_ptr<FragmentInfo> >
fragments;
68 const char *foundOpen=
nullptr;
69 std::unordered_map<std::string,BlockMarker> candidates;
76 else if (foundOpen && c==
']' && foundOpen+1<s)
78 std::string key(foundOpen+1,s-foundOpen-1);
79 candidates[key].lines.push_back(lineNr);
92 for (
auto &kv : candidates)
94 auto &marker = kv.second;
95 if (marker.lines.size()==2 && marker.lines[0]+1<=marker.lines[1]-1)
97 marker.key = kv.first;
98 int startLine = marker.lines[0];
99 blocks[startLine] = marker;
106 static auto gotoLine = [](
const char *startBuf,
const char *startPos,
int startLine,
int targetLine) ->
const char *
109 if (targetLine<startLine)
112 while (startLine>=targetLine && startPos>=startBuf && (cc=*startPos--)) {
if (cc==
'\n') startLine--; }
113 if (startPos>startBuf)
128 while (startLine<targetLine && (cc=*startPos++)) {
if (cc==
'\n') startLine++; }
133 static auto lineIndent = [](
const char *&ss,
size_t orgCol) ->
size_t
141 else if (cc==
'\t') col+=tabSize-(col%tabSize);
142 else if (cc==
'\n')
return orgCol;
146 while ((cc=*ss++) && cc!=
'\n');
153 const char *startBuf = s;
156 auto &marker = kv.second;
157 s = gotoLine(startBuf,s,lineNr,marker.lines[0]+1);
158 lineNr=marker.lines[1];
159 const char *e = gotoLine(startBuf,s,marker.lines[0]+1,lineNr);
162 size_t minIndent=100000;
163 size_t indent = minIndent;
166 indent = lineIndent(ss, indent);
167 if (indent<minIndent)
170 if (minIndent==0)
break;
173 marker.indent = minIndent;
209 for (
const auto &s : examplePathList)
227 err(
"included file name '{}' is ambiguous.\nPossible candidates:\n{}\n",file,
236 err(
"included file {} is not found. Check your EXAMPLE_PATH\n",file);
246 bool showLineNumbers,
248 bool stripCodeComments
251 AUTO_TRACE(
"CodeFragmentManager::parseCodeFragment({},blockId={},scopeName={},showLineNumber={},trimLeft={},stripCodeComments={}",
252 fileName, blockId, scopeName, showLineNumbers, trimLeft, stripCodeComments);
253 std::string fragmentKey=fileName.
str()+
":"+scopeName.
str();
254 std::unordered_map< std::string,std::unique_ptr<Private::FragmentInfo> >::iterator it;
255 bool inserted =
false;
258 std::lock_guard lock(
p->mutex);
259 it =
p->fragments.find(fragmentKey);
260 if (it ==
p->fragments.end())
262 it =
p->fragments.emplace(fragmentKey, std::make_unique<Private::FragmentInfo>()).first;
268 auto &codeFragment = it->second;
269 std::lock_guard lock(codeFragment->mutex);
276 intf->resetCodeParserState();
278 bool needs2PassParsing =
280 !filterSourceFiles &&
284 if (needs2PassParsing)
288 intf->parseCode(devNullList,
290 codeFragment->fileContents,
296 codeFragment->findBlockMarkers();
297 if (!codeFragment->fileContents.empty())
299 intf->parseCode(codeFragment->recorderCodeList,
301 codeFragment->fileContents,
305 .setFileDef(fd.get())
312 auto blockKv = codeFragment->blocksById.find(blockId.
str());
313 if (blockKv != codeFragment->blocksById.end())
315 const auto &marker = blockKv->second;
316 int startLine = marker->lines[0];
317 int endLine = marker->lines[1];
318 size_t indent = marker->indent;
319 AUTO_TRACE_ADD(
"replay(start={},end={},indent={}) fileContentsTrimLeft.empty()={}",
320 startLine,endLine,indent,codeFragment->fileContentsTrimLeft.empty());
322 recorder->
replay(codeOutList,
327 trimLeft ? indent : 0
static CodeFragmentManager & instance()
std::unique_ptr< Private > p
void parseCodeFragment(OutputCodeList &codeOutList, const DString &fileName, const DString &blockId, const DString &scopeName, bool showLineNumbers, bool trimLeft, bool stripCodeComments)
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
size_t size() const
Returns the length of the string, not counting the 0-terminator.
const std::string & str() const
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Class implementing OutputCodeIntf by throwing away everything.
static bool parseSourcesNeeded
static ParserManager * parserManager
static FileNameLinkedMap * exampleNameLinkedMap
A model of a file symbol.
virtual DString absFilePath() const =0
Minimal replacement for QFileInfo.
std::string fileName() const
std::string dirPath(bool absPath=true) const
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
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)
std::unique_ptr< CodeParserInterface > getCodeParser(const DString &extension)
Gets the interface to the parser associated with a given extension.
static DString readTextFileByName(const DString &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 DString &p, const DString &n, const DString &ref, const DString &dn)
bool isAbsolutePath(const DString &fileName)
Portable versions of functions that are platform dependent.
DString fileContentsTrimLeft
OutputCodeList recorderCodeList
std::map< std::string, const BlockMarker * > blocksById
std::map< int, BlockMarker > blocks
std::unordered_map< std::string, std::unique_ptr< FragmentInfo > > fragments
Options to configure the code parser.
CodeParserOptions & setInlineFragment(bool enable)
CodeParserOptions & setCollectXRefs(bool enable)
DString detab(const DString &s, size_t &refIndent)
DString getFileNameExtension(const DString &fn)
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
DString getFileFilter(const DString &name, bool isSourceCode)
DString fileToString(const DString &name, bool filter, bool isSourceCode)
A bunch of utility functions.