Skip to content

Commit 27994a7

Browse files
committed
Fix utils::renumber
1 parent 91ae698 commit 27994a7

2 files changed

Lines changed: 151 additions & 159 deletions

File tree

addons/src/renumber/utils-renumber.cpp

Lines changed: 145 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,19 @@
2828
#include "utils-renumber.h"
2929

3030

31+
#define APOSTROPHE_COMMENT_REGEXPR "\\'[^\\n\\']*[\\']?"
32+
#define GCODE_COMMENT_REGEXPR "\\([^\\n\\)]*[\\)]?"
33+
#define N_MARK_REGEXPR "^([ \\t]*N\\b[ \\t]*)"
34+
#define N_WORD_REGEXPR "([ \\t]*N([0-9 \\t]*[0-9])[ \\t]*)"
35+
#define SINUMERIK_COMMENT_REGEXPR ";[^\\n]*"
36+
37+
3138
bool Utils::renumber(QString& text, const RenumberOptions& opt, const std::function<bool(int)>& interrupt)
3239
{
3340
bool changed = false;
3441
QString result;
3542
int num = opt.startAt;
43+
int width = opt.applyWidth ? opt.width : 0;
3644
int substr_start = 0;
3745
int substr_end = 0;
3846

@@ -48,19 +56,19 @@ bool Utils::renumber(QString& text, const RenumberOptions& opt, const std::funct
4856

4957
switch (opt.mode) {
5058
case RenumberOptions::RenumberWithN:
51-
localChange = renumberWithN(line, num, opt);
59+
localChange = renumberWithN(line, num, width, opt.from, opt.to, opt.renumMarked);
5260
break;
5361

5462
case RenumberOptions::RenumberAll:
55-
localChange = renumberAll(line, num, opt);
63+
localChange = renumberAll(line, num, width, opt.renumEmpty, opt.renumComm, true);
5664
break;
5765

5866
case RenumberOptions::RemoveAll:
59-
localChange = renumberRemoveAll(line);
67+
localChange = renumberRemoveAll(line, true);
6068
break;
6169

6270
case RenumberOptions::RenumberWithoutN:
63-
localChange = renumberWithoutN(line, num, opt);
71+
localChange = renumberWithoutN(line, num, width, opt.renumEmpty);
6472
break;
6573

6674
default:
@@ -79,189 +87,171 @@ bool Utils::renumber(QString& text, const RenumberOptions& opt, const std::funct
7987
return changed;
8088
}
8189

82-
bool Utils::renumberWithoutN(QString& line, int num, const RenumberOptions& opt)
90+
bool Utils::renumberWithoutN(QString& line, int num, int width, bool renumAll)
8391
{
84-
bool changed = false;
85-
QString i_tx;
86-
QRegularExpression regex;
87-
88-
regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
89-
regex.setPattern("^[0-9]{1,9}\\s\\s");
90-
91-
i_tx = QString("%1").arg(num, opt.width);
92-
i_tx.replace(QLatin1Char(' '), QLatin1Char('0'));
93-
i_tx += " ";
94-
95-
auto match = regex.match(line);
92+
static QRegularExpression regex{
93+
"^([0-9]{1,9}[ \\t]{2,2})",
94+
QRegularExpression::CaseInsensitiveOption
95+
};
96+
QRegularExpressionMatch&& match = regex.match(line);
97+
QString n_word = QString("%1 ").arg(num, width, 10, QLatin1Char{' '});
9698

9799
if (match.hasMatch()) {
98-
line.replace(match.capturedStart(), match.capturedLength(), i_tx);
99-
changed = true;
100+
line.replace(match.capturedStart(1), match.capturedLength(1), n_word);
101+
} else if (renumAll) {
102+
line.insert(0, n_word);
100103
} else {
101-
if (opt.renumEmpty) {
102-
line.insert(0, i_tx);
103-
changed = true;
104-
}
104+
return false;
105105
}
106106

107-
return changed;
107+
return true;
108108
}
109109

110-
bool Utils::renumberWithN(QString& line, int num, const RenumberOptions& opt)
110+
bool Utils::renumberWithN(QString& line, int num, int width, int from, int to, bool renumMarked)
111111
{
112-
bool changed = false;
113-
int pos;
114-
long int i, it;
115-
QString f_tx;
116-
QRegularExpression regex;
117-
bool ok, insertSpace;
118-
119-
pos = 0;
120-
regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
121-
regex.setPattern("[N]{1,1}[0-9\\s]+|\\([^\\n\\r]*\\)|\'[^\\n\\r]*\'|;[^\\n\\r]*");
122-
auto match = regex.match(line);
123-
124-
while (match.hasMatch()) {
125-
pos = match.capturedStart();
126-
f_tx = match.captured();
127-
128-
//qDebug() << f_tx;
129-
130-
if (pos > 0)
131-
if (line[pos - 1].isLetterOrNumber()) {
132-
pos = match.capturedEnd();
133-
continue;
134-
}
135-
136-
insertSpace = true;
137-
138-
if (f_tx.endsWith(QLatin1Char(' '))) {
139-
insertSpace = false;
140-
}
141-
142-
if (!f_tx.contains(QLatin1Char(' ')) && !f_tx.contains(QLatin1Char('\n'))) {
143-
i = match.capturedLength();
144-
} else {
145-
i = match.capturedLength() - 1;
112+
static QRegularExpression check_num{
113+
N_WORD_REGEXPR // groups 1 and 2
114+
"|"
115+
N_MARK_REGEXPR // group 3
116+
"|"
117+
GCODE_COMMENT_REGEXPR
118+
"|"
119+
APOSTROPHE_COMMENT_REGEXPR
120+
"|"
121+
SINUMERIK_COMMENT_REGEXPR,
122+
QRegularExpression::CaseInsensitiveOption
123+
};
124+
QRegularExpressionMatch&& match = check_num.match(line);
125+
bool num_captured = match.capturedLength(2) > 0;
126+
bool mark_captured = match.capturedLength(3) > 0;
127+
128+
if (num_captured) {
129+
QString digits = match.captured(2);
130+
digits.remove(' ');
131+
digits.remove('\t');
132+
int current = digits.toInt();
133+
134+
if (current < from || current > to) {
135+
return false;
146136
}
147137

148-
if (!f_tx.contains(QLatin1Char('(')) && !f_tx.contains(QLatin1Char('\''))
149-
&& !f_tx.contains(QLatin1Char(';'))) {
150-
f_tx.remove(0, 1);
151-
f_tx.remove(QLatin1Char(' '));
152-
153-
if (!f_tx.isEmpty()) {
154-
it = f_tx.toInt(&ok);
155-
} else {
156-
it = 0;
157-
}
158-
159-
if (((it >= opt.from) || (opt.renumMarked && it == 0)) && (it < opt.to)) {
160-
f_tx = QString(QLatin1String("N%1")).arg(num, opt.width);
161-
f_tx.replace(QLatin1Char(' '), QLatin1Char('0'));
138+
line.remove(match.capturedStart(1), match.capturedLength(1));
139+
} else if (mark_captured && renumMarked) {
140+
line.remove(match.capturedStart(3), match.capturedLength(3));
162141

163-
if (insertSpace) {
164-
f_tx.append(QLatin1String(" "));
165-
}
166-
167-
line.replace(pos, i, f_tx);
168-
changed = true;
169-
}
142+
// The regular expression N_MARK_REGEXPR can capture the end-of-line character.
143+
if (line.isEmpty()) {
144+
line.append('\n');
170145
}
171-
172-
match = regex.match(line, match.capturedEnd());
146+
} else {
147+
return false;
173148
}
174149

175-
return changed;
150+
insertNWord(line, num, width);
151+
return true;
176152
}
177153

178-
bool Utils::renumberAll(QString& line, int num, const RenumberOptions& opt)
154+
bool Utils::renumberAll(QString& line, int num, int width, bool renumEmpty, bool renumComm, bool keepExisting)
179155
{
180-
int pos;
181-
QString f_tx, i_tx;
182-
QRegularExpression regex;
183-
184-
regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
185-
regex.setPattern("[Nn]{1,1}[0-9]+[\\s]{0,}|\\([^\\n\\r]*\\)|\'[^\\n\\r]*\'|;[^\\n\\r]*");
156+
bool changed = false;
157+
static QRegularExpression check_num{
158+
"^[ \\t]*(:|%|\\$|O|PM\\W)" // group 1
159+
"|"
160+
N_WORD_REGEXPR // groups 2 and 3
161+
"|"
162+
N_MARK_REGEXPR // group 4
163+
"|"
164+
GCODE_COMMENT_REGEXPR
165+
"|"
166+
APOSTROPHE_COMMENT_REGEXPR
167+
"|"
168+
SINUMERIK_COMMENT_REGEXPR,
169+
QRegularExpression::CaseInsensitiveOption
170+
};
171+
QRegularExpressionMatch&& match = check_num.match(line);
172+
bool stop_captured = match.capturedLength(1) > 0;
173+
bool num_captured = match.capturedLength(2) > 0;
174+
bool mark_captured = match.capturedLength(4) > 0;
175+
176+
// Exit if line start with ':', '%', '$', 'O' or 'PM'
177+
// TODO: add signatures for blocks that cannot be numbered
178+
if (stop_captured) {
179+
return false;
180+
}
186181

187-
pos = 0;
182+
if (num_captured) {
183+
line.remove(match.capturedStart(2), match.capturedLength(2));
184+
changed = true;
185+
} else if (mark_captured) {
186+
line.remove(match.capturedStart(4), match.capturedLength(4));
187+
changed = true;
188188

189-
if (line.isEmpty()) {
190-
if (!opt.renumEmpty) {
191-
return false;
189+
// The regular expression N_MARK_REGEXPR can capture the end-of-line character.
190+
if (line.isEmpty()) {
191+
line.append('\n');
192192
}
193-
194-
f_tx = QString(QLatin1String("N%1")).arg(num, opt.width);
195-
f_tx.replace(QLatin1Char(' '), QLatin1Char('0'));
196-
line.insert(0, f_tx);
197-
return true;
198193
}
199194

200-
auto match = regex.match(line, pos);
201-
202-
if (match.hasMatch() && (line.at(0) != QLatin1Char('$'))) {
203-
pos = match.capturedStart();
204-
i_tx = match.captured();
205-
i_tx.remove('\n');
206-
207-
if ((!i_tx.contains(QLatin1Char('(')) && !i_tx.contains(QLatin1Char('\''))
208-
&& !i_tx.contains(QLatin1Char(';')))) {
209-
f_tx = QString(QLatin1String("N%1")).arg(num, opt.width);
210-
f_tx.replace(QLatin1Char(' '), QLatin1Char('0'));
211-
f_tx.append(QLatin1String(" "));
212-
line.replace(i_tx, f_tx);
213-
return true;
214-
} else if (opt.renumComm) {
215-
return false;
216-
}
195+
static QRegularExpression check_empty{
196+
"([A-Z@#])" // group 1
197+
"|"
198+
"(" GCODE_COMMENT_REGEXPR ")" // group 2
199+
"|"
200+
"(" APOSTROPHE_COMMENT_REGEXPR ")" // group 3
201+
"|"
202+
"(" SINUMERIK_COMMENT_REGEXPR ")", // group 4
203+
QRegularExpression::CaseInsensitiveOption
204+
};
205+
match = check_empty.match(line);
206+
bool not_empty = match.capturedLength(1) > 0;
207+
bool comments_captured = match.capturedLength(2) > 0 || match.capturedLength(3) > 0 || match.capturedLength(4) > 0;
208+
bool insert = ((num_captured || mark_captured) && keepExisting) || not_empty || renumEmpty || (renumComm
209+
&& comments_captured);
210+
211+
if (insert) {
212+
insertNWord(line, num, width);
213+
changed = true;
217214
}
218215

219-
if ((line.at(0) == QLatin1Char('N')) && (!line.at(1).isLetter())) {
220-
f_tx = QString(QLatin1String("N%1")).arg(num, opt.width);
221-
f_tx.replace(QLatin1Char(' '), QLatin1Char('0'));
222-
f_tx.append(QLatin1String(" "));
223-
line.replace(0, 1, f_tx);
224-
return true;
225-
}
216+
return changed;
217+
}
226218

227-
if (((line.at(0) != QLatin1Char('%')) && (line.at(0) != QLatin1Char(':'))
228-
&& (line.at(0) != QLatin1Char('O')) && (line.at(0) != QLatin1Char('$')))) {
229-
f_tx = QString(QLatin1String("N%1")).arg(num, opt.width);
230-
f_tx.replace(QLatin1Char(' '), QLatin1Char('0'));
231-
f_tx.append(QLatin1String(" "));
232-
line.insert(0, f_tx);
233-
return true;
219+
bool Utils::renumberRemoveAll(QString& line, bool removeMarked)
220+
{
221+
static QRegularExpression check_num{
222+
N_WORD_REGEXPR // group 1 and 2
223+
"|"
224+
N_MARK_REGEXPR // group 3
225+
"|"
226+
GCODE_COMMENT_REGEXPR
227+
"|"
228+
APOSTROPHE_COMMENT_REGEXPR
229+
"|"
230+
SINUMERIK_COMMENT_REGEXPR,
231+
QRegularExpression::CaseInsensitiveOption
232+
};
233+
QRegularExpressionMatch&& match = check_num.match(line);
234+
bool num_captured = match.capturedLength(1) > 0;
235+
bool mark_captured = match.capturedLength(3) > 0;
236+
237+
if (num_captured) {
238+
line.remove(match.capturedStart(1), match.capturedLength(1));
239+
} else if (mark_captured && removeMarked) {
240+
line.remove(match.capturedStart(3), match.capturedLength(3));
241+
} else {
242+
return false;
234243
}
235244

236-
return false;
245+
return true;
237246
}
238247

239-
bool Utils::renumberRemoveAll(QString& line)
248+
void Utils::insertNWord(QString& line, int num, int width)
240249
{
241-
bool changed = false;
242-
QString f_tx;
243-
QRegularExpression regex;
244-
245-
regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
246-
regex.setPattern("[N]{1,1}[0-9\\s]+|\\([^\\n\\r]*\\)|\'[^\\n\\r]*\'|;[^\\n\\r]*");
247-
auto match = regex.match(line);
250+
QString n_word = QString(QLatin1String("N%1")).arg(num, width, 10, QLatin1Char{'0'});
248251

249-
while (match.hasMatch()) {
250-
int pos = match.capturedStart();
251-
f_tx = match.captured();
252-
253-
//qDebug() << f_tx;
254-
255-
if (!f_tx.contains(QLatin1Char('(')) && !f_tx.contains(QLatin1Char('\''))
256-
&& !f_tx.contains(QLatin1Char(';'))) {
257-
line.remove(pos, match.capturedLength());
258-
changed = true;
259-
} else {
260-
pos = match.capturedEnd();
261-
}
262-
263-
match = regex.match(line, pos);
252+
if (line.size() > 0 && line.at(0) != '\n') {
253+
n_word.append(' ');
264254
}
265255

266-
return changed;
256+
line.prepend(n_word);
267257
}

addons/src/renumber/utils-renumber.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ struct RenumberOptions;
3030
namespace Utils {
3131

3232
bool renumber(QString& text, const RenumberOptions& opt, const std::function<bool(int)>& interrupt);
33-
bool renumberWithoutN(QString& line, int num, const RenumberOptions& opt);
34-
bool renumberWithN(QString& line, int num, const RenumberOptions& opt);
35-
bool renumberAll(QString& line, int num, const RenumberOptions& opt);
36-
bool renumberRemoveAll(QString& line);
33+
bool renumberWithoutN(QString& line, int num, int width, bool renumAll);
34+
bool renumberWithN(QString& line, int num, int width, int from, int to, bool renumMarked);
35+
bool renumberAll(QString& line, int num, int width, bool renumEmpty, bool renumComm, bool keepExisting);
36+
bool renumberRemoveAll(QString& line, bool removeMarked);
37+
38+
void insertNWord(QString& line, int num, int width);
3739

3840
} // namespace Utils
3941

0 commit comments

Comments
 (0)