Doxygen
Loading...
Searching...
No Matches
CodeFragmentManager::Private::FragmentInfo Struct Reference
+ Collaboration diagram for CodeFragmentManager::Private::FragmentInfo:

Public Member Functions

 FragmentInfo ()
 
void findBlockMarkers ()
 

Public Attributes

QCString fileContents
 
QCString fileContentsTrimLeft
 
OutputCodeList recorderCodeList
 
std::map< int, BlockMarkerblocks
 
std::map< std::string, const BlockMarker * > blocksById
 
std::mutex mutex
 

Detailed Description

Definition at line 41 of file codefragment.cpp.

Constructor & Destructor Documentation

◆ FragmentInfo()

CodeFragmentManager::Private::FragmentInfo::FragmentInfo ( )
inline

Definition at line 45 of file codefragment.cpp.

45{ recorderCodeList.add<OutputCodeRecorder>(); }

References recorderCodeList.

Member Function Documentation

◆ findBlockMarkers()

void CodeFragmentManager::Private::FragmentInfo::findBlockMarkers ( )

Definition at line 57 of file codefragment.cpp.

58{
59 AUTO_TRACE("findBlockMarkers() size={}",fileContents.size());
60 // give fileContents and a list of candidate [XYZ] labels with/without trim left flag (from commentscan?)
61 if (fileContents.length()==0) return;
62
63 // find the potential snippet blocks (can also be other array like stuff in the file)
64 const char *s=fileContents.data();
65 int lineNr=1;
66 char c=0;
67 const char *foundOpen=nullptr;
68 std::unordered_map<std::string,BlockMarker> candidates;
69 while ((c=*s))
70 {
71 if (c=='[')
72 {
73 foundOpen=s;
74 }
75 else if (foundOpen && c==']' && foundOpen+1<s) // non-empty [...] section
76 {
77 std::string key(foundOpen+1,s-foundOpen-1);
78 candidates[key].lines.push_back(lineNr);
79 }
80 else if (c=='\n')
81 {
82 foundOpen=nullptr;
83 lineNr++;
84 }
85 s++;
86 }
87
88 // Sort the valid snippet blocks by line number, Look for blocks that appears twice,
89 // where candidate has block id as key and the start and end line as value.
90 // Store the key in marker.key
91 for (auto &kv : candidates)
92 {
93 auto &marker = kv.second;
94 if (marker.lines.size()==2 && marker.lines[0]+1<=marker.lines[1]-1)
95 {
96 marker.key = kv.first;
97 int startLine = marker.lines[0];
98 blocks[startLine] = marker;
99 blocksById["["+kv.first+"]"] = &blocks[startLine];
100 }
101 }
102
103 // determine the shared indentation for each line in each block, and store it in marker.indent
104 s=fileContents.data();
105 static auto gotoLine = [](const char *startBuf, const char *startPos, int startLine, int targetLine) -> const char *
106 {
107 char cc=0;
108 if (targetLine<startLine)
109 {
110 //printf("gotoLine(pos=%p,start=%d,target=%d) backward\n",(void*)startPos,startLine,targetLine);
111 while (startLine>=targetLine && startPos>=startBuf && (cc=*startPos--)) { if (cc=='\n') startLine--; }
112 if (startPos>startBuf)
113 {
114 // given fragment:
115 // line1\n
116 // line2\n
117 // line3
118 // and targetLine==2 then startPos ends at character '1' of line 1 before we detect that startLine<targetLine,
119 // so we need to advance startPos with 2 to be at the start of line2, unless we are already at the first line.
120 startPos+=2;
121 }
122 //printf("result=[%s]\n",qPrint(QCString(startPos).left(20)));
123 }
124 else
125 {
126 //printf("gotoLine(pos=%p,start=%d,target=%d) forward\n",(void*)startPos,startLine,targetLine);
127 while (startLine<targetLine && (cc=*startPos++)) { if (cc=='\n') startLine++; }
128 //printf("result=[%s]\n",qPrint(QCString(startPos).left(20)));
129 }
130 return startPos;
131 };
132 static auto lineIndent = [](const char *&ss) -> int
133 {
134 int tabSize=Config_getInt(TAB_SIZE);
135 int col = 0;
136 char cc = 0;
137 while ((cc=*ss++))
138 {
139 if (cc==' ') col++;
140 else if (cc=='\t') col+=tabSize-(col%tabSize);
141 else
142 {
143 // goto end of the line
144 while ((cc=*ss++) && cc!='\n');
145 break;
146 }
147 }
148 return col;
149 };
150 lineNr=1;
151 const char *startBuf = s;
152 for (auto &kv : blocks)
153 {
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);
158
159 const char *ss = s;
160 int minIndent=100000;
161 while (ss<e)
162 {
163 int indent = lineIndent(ss);
164 if (indent<minIndent)
165 {
166 minIndent=indent;
167 if (minIndent==0) break;
168 }
169 }
170 marker.indent = minIndent;
171
172 AUTO_TRACE_ADD("found snippet key='{}' range=[{}..{}] indent={}",
173 marker.key,
174 marker.lines[0]+1,
175 marker.lines[1]-1,
176 marker.indent);
177 s=e;
178 }
179}
#define Config_getInt(name)
Definition config.h:34
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:47
#define AUTO_TRACE(...)
Definition docnode.cpp:46
std::map< std::string, const BlockMarker * > blocksById
std::map< int, BlockMarker > blocks

References AUTO_TRACE, AUTO_TRACE_ADD, blocks, blocksById, Config_getInt, and fileContents.

Member Data Documentation

◆ blocks

std::map<int,BlockMarker> CodeFragmentManager::Private::FragmentInfo::blocks

Definition at line 48 of file codefragment.cpp.

Referenced by findBlockMarkers().

◆ blocksById

std::map<std::string,const BlockMarker*> CodeFragmentManager::Private::FragmentInfo::blocksById

Definition at line 49 of file codefragment.cpp.

Referenced by findBlockMarkers().

◆ fileContents

QCString CodeFragmentManager::Private::FragmentInfo::fileContents

Definition at line 43 of file codefragment.cpp.

Referenced by findBlockMarkers().

◆ fileContentsTrimLeft

QCString CodeFragmentManager::Private::FragmentInfo::fileContentsTrimLeft

Definition at line 44 of file codefragment.cpp.

◆ mutex

std::mutex CodeFragmentManager::Private::FragmentInfo::mutex

Definition at line 50 of file codefragment.cpp.

◆ recorderCodeList

OutputCodeList CodeFragmentManager::Private::FragmentInfo::recorderCodeList

Definition at line 47 of file codefragment.cpp.

Referenced by FragmentInfo().


The documentation for this struct was generated from the following file: