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

Public Member Functions

 FragmentInfo ()
void findBlockMarkers ()

Public Attributes

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

Detailed Description

Definition at line 45 of file codefragment.cpp.

Constructor & Destructor Documentation

◆ FragmentInfo()

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

Definition at line 49 of file codefragment.cpp.

49{ recorderCodeList.add<OutputCodeRecorder>(); }
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:192

References OutputCodeList::add(), and recorderCodeList.

Member Function Documentation

◆ findBlockMarkers()

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

Definition at line 61 of file codefragment.cpp.

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

References AUTO_TRACE, AUTO_TRACE_ADD, blocks, blocksById, Config_getInt, DString::data(), DString::empty(), fileContents, and DString::size().

Member Data Documentation

◆ blocks

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

Definition at line 52 of file codefragment.cpp.

Referenced by findBlockMarkers().

◆ blocksById

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

Definition at line 53 of file codefragment.cpp.

Referenced by findBlockMarkers().

◆ fileContents

DString CodeFragmentManager::Private::FragmentInfo::fileContents

Definition at line 47 of file codefragment.cpp.

Referenced by findBlockMarkers().

◆ fileContentsTrimLeft

DString CodeFragmentManager::Private::FragmentInfo::fileContentsTrimLeft

Definition at line 48 of file codefragment.cpp.

◆ mutex

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

Definition at line 54 of file codefragment.cpp.

◆ recorderCodeList

OutputCodeList CodeFragmentManager::Private::FragmentInfo::recorderCodeList

Definition at line 51 of file codefragment.cpp.

Referenced by FragmentInfo().


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