Skip to content

Commit 58d1307

Browse files
committed
Refactoring: replace QRegExp by std::regex in rtfstyle.cpp
1 parent 7974279 commit 58d1307

File tree

4 files changed

+94
-125
lines changed

4 files changed

+94
-125
lines changed

src/docparser.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ static int handleStyleArgument(DocNode *parent,DocNodeList &children,
876876
{
877877
static std::regex specialChar("[.,|()\\[\\]:;\\?]");
878878
if (tok==TK_WORD && g_token->name.length()==1 &&
879-
std::regex_match(g_token->name.str(),specialChar))
879+
std::regex_search(g_token->name.str(),specialChar))
880880
{
881881
// special character that ends the markup command
882882
return tok;

src/htmlhelp.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2,
157157
static std::regex re("@[[:digit:]]+");
158158
std::string key = level1;
159159
if (level2) key+= std::string("?") + level2;
160-
if (std::regex_match(key,re)) // skip anonymous stuff
160+
if (std::regex_search(key,re)) // skip anonymous stuff
161161
{
162162
return;
163163
}

src/rtfstyle.cpp

+90-121
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
/******************************************************************************
22
*
3-
*
4-
*
5-
*
6-
* Copyright (C) 1997-2015 by Dimitri van Heesch.
3+
* Copyright (C) 1997-2021 by Dimitri van Heesch.
74
*
85
* Permission to use, copy, modify, and distribute this software and its
96
* documentation under the terms of the GNU General Public License is hereby
@@ -16,15 +13,13 @@
1613
*
1714
*/
1815

19-
#include <stdlib.h>
20-
#include <qfile.h>
21-
#include <qregexp.h>
22-
#include <qtextstream.h>
16+
#include <regex>
17+
#include <string>
18+
#include <fstream>
2319

2420
#include "rtfstyle.h"
2521
#include "message.h"
2622

27-
2823
RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels];
2924

3025
QCString rtf_title;
@@ -38,6 +33,21 @@ QCString rtf_documentType;
3833
QCString rtf_documentId;
3934
QCString rtf_keywords;
4035

36+
static std::map<std::string,QCString &> g_styleMap =
37+
{
38+
{ "Title", rtf_title },
39+
{ "Subject", rtf_subject },
40+
{ "Comments", rtf_comments },
41+
{ "Company", rtf_company },
42+
{ "LogoFilename", rtf_logoFilename },
43+
{ "Author", rtf_author },
44+
{ "Manager", rtf_manager },
45+
{ "DocumentType", rtf_documentType },
46+
{ "DocumentId", rtf_documentId },
47+
{ "Keywords", rtf_keywords }
48+
};
49+
50+
4151
char rtf_Style_Reset[] = "\\pard\\plain ";
4252

4353
#define RTF_LatexToc(lvl,nest,nxt,pos,twps) \
@@ -224,116 +234,80 @@ Rtf_Style_Default rtf_Style_Default[] =
224234
}
225235
};
226236

227-
static const QRegExp s_clause("\\\\s[0-9]+\\s*");
237+
static const std::regex s_clause("\\\\s([[:digit:]]+)[[:space:]]*");
228238

229-
StyleData::StyleData(const char* reference, const char* definition)
239+
StyleData::StyleData(const std::string &reference, const std::string &definition)
230240
{
231-
const char *ref = reference;
232-
233-
int start = s_clause.match(ref); ASSERT(start >= 0);
234-
ref += start;
235-
m_index = (int)atol(ref + 2); ASSERT(m_index > 0);
236-
237-
m_reference = ref;
241+
std::smatch match;
242+
if (regex_search(reference,match,s_clause))
243+
{
244+
m_index = static_cast<int>(std::stoul(match[1].str()));
245+
}
246+
else // error
247+
{
248+
m_index = 0;
249+
}
250+
m_reference = reference;
238251
m_definition = definition;
239252
}
240253

241-
bool StyleData::setStyle(const char* s, const char* styleName)
254+
bool StyleData::setStyle(const std::string &command, const std::string &styleName)
242255
{
243-
static const QRegExp subgroup("^{[^}]*}\\s*");
244-
static const QRegExp any_clause("^\\\\[a-z][a-z0-9-]*\\s*");
245-
246-
int len = 0; // length of a particular RTF formatting control
247-
int ref_len = 0; // length of the whole formatting section of a style
248-
int start = s_clause.match(s, 0, &len);
249-
if (start < 0)
256+
std::smatch match;
257+
if (!regex_search(command,match,s_clause))
250258
{
251-
err("Style sheet '%s' contains no '\\s' clause.\n{%s}\n", styleName, s);
252-
return FALSE;
253-
}
254-
s += start;
255-
m_index = (int)atol(s + 2); ASSERT(m_index > 0);
256-
257-
// search for the end of pure formatting codes
258-
const char* end = s + len;
259-
ref_len = len;
260-
bool haveNewDefinition = TRUE;
261-
for(;;)
262-
{
263-
if (*end == '{')
264-
{
265-
// subgroups are used for \\additive
266-
if (0 != subgroup.match(end, 0, &len))
267-
break;
268-
else
269-
{
270-
end += len;
271-
ref_len += len;
272-
}
273-
}
274-
else if (*end == '\\')
275-
{
276-
if (0 == qstrncmp(end, "\\snext", 6))
277-
break;
278-
if (0 == qstrncmp(end, "\\sbasedon", 9))
279-
break;
280-
if (0 != any_clause.match(end, 0, &len))
281-
break;
282-
end += len;
283-
ref_len += len;
284-
}
285-
else if (*end == 0)
286-
{ // no style-definition part, keep default value
287-
haveNewDefinition = FALSE;
288-
break;
289-
}
290-
else // plain name without leading \\snext
291-
break;
259+
err("Style sheet '%s' contains no '\\s' clause.\n{%s}", styleName.c_str(), command.c_str());
260+
return false;
292261
}
293-
m_reference = s;
294-
if (haveNewDefinition)
262+
m_index = static_cast<int>(std::stoul(match[1].str()));
263+
264+
static std::regex definition_splitter("^(.*)(\\\\sbasedon[[:digit:]]+.*)$");
265+
if (regex_match(command,match,definition_splitter))
295266
{
296-
m_definition = end;
267+
m_reference = match[1].str();
268+
m_definition = match[2].str();
297269
}
298-
return TRUE;
270+
271+
return true;
299272
}
300273

274+
301275
void loadStylesheet(const char *name, StyleDataMap& map)
302276
{
303-
QFile file(name);
304-
if (!file.open(IO_ReadOnly))
277+
std::ifstream file(name);
278+
if (!file.is_open())
305279
{
306-
err("Can't open RTF style sheet file %s. Using defaults.\n",name);
280+
err("Can't open RTF style sheet file %s. Using defaults.",name);
307281
return;
308282
}
309283
msg("Loading RTF style sheet %s...\n",name);
310284

311-
static const QRegExp separator("[ \t]*=[ \t]*");
312285
uint lineNr=1;
313-
QTextStream t(&file);
314286

315-
while (!t.eof())
287+
for (std::string line ; getline(file,line) ; ) // for each line
316288
{
317-
QCString s(4096); // string buffer of max line length
318-
s = t.readLine().stripWhiteSpace().utf8();
319-
if (s.isEmpty() || s.at(0)=='#') continue; // skip blanks & comments
320-
int sepLength;
321-
int sepStart = separator.match(s,0,&sepLength);
322-
if (sepStart<=0) // no valid assignment statement
289+
if (line.empty() || line[0]=='#') continue; // skip blanks & comments
290+
static std::regex assignment_splitter("[[:space:]]*=[[:space:]]*");
291+
std::smatch match;
292+
if (std::regex_search(line,match,assignment_splitter))
323293
{
324-
warn(name,lineNr,"Assignment of style sheet name expected!\n");
325-
continue;
294+
std::string key = match.prefix();
295+
std::string value = match.suffix();
296+
auto it = map.find(key);
297+
if (it!=map.end())
298+
{
299+
StyleData& styleData = it->second;
300+
styleData.setStyle(value,key);
301+
}
302+
else
303+
{
304+
warn(name,lineNr,"Unknown style sheet name %s ignored.",key.data());
305+
}
326306
}
327-
QCString key=s.left(sepStart);
328-
auto it = map.find(key.str());
329-
if (it==map.end()) // not a valid style sheet name
307+
else
330308
{
331-
warn(name,lineNr,"Unknown style sheet name %s ignored.\n",key.data());
332-
continue;
309+
warn(name,lineNr,"Assignment of style sheet name expected line='%s'!",line.c_str());
333310
}
334-
StyleData& styleData = it->second;
335-
s+=" "; // add command separator
336-
styleData.setStyle(s.data() + sepStart + sepLength, key.data());
337311
lineNr++;
338312
}
339313
}
@@ -342,44 +316,39 @@ StyleDataMap rtf_Style;
342316

343317
void loadExtensions(const char *name)
344318
{
345-
QFile file(name);
346-
if (!file.open(IO_ReadOnly))
319+
std::ifstream file(name);
320+
if (!file.is_open())
347321
{
348-
err("Can't open RTF extensions file %s. Using defaults.\n",name);
322+
err("Can't open RTF extensions file %s. Using defaults.",name);
349323
return;
350324
}
351325
msg("Loading RTF extensions %s...\n",name);
352326

353-
static const QRegExp separator("[ \t]*=[ \t]*");
354327
uint lineNr=1;
355-
QTextStream t(&file);
356-
t.setEncoding(QTextStream::UnicodeUTF8);
357328

358-
while (!t.eof())
329+
for (std::string line ; getline(file,line) ; ) // for each line
359330
{
360-
QCString s(4096); // string buffer of max line length
361-
s = t.readLine().stripWhiteSpace().utf8();
362-
if (s.length()==0 || s.at(0)=='#') continue; // skip blanks & comments
363-
int sepLength;
364-
int sepStart = separator.match(s,0,&sepLength);
365-
if (sepStart<=0) // no valid assignment statement
331+
if (line.empty() || line[0]=='#') continue; // skip blanks & comments
332+
std::smatch match;
333+
static std::regex assignment_splitter("[[:space:]]*=[[:space:]]*");
334+
if (std::regex_search(line,match,assignment_splitter))
335+
{
336+
std::string key = match.prefix();
337+
std::string value = match.suffix();
338+
auto it = g_styleMap.find(key);
339+
if (it!=g_styleMap.end())
340+
{
341+
it->second = value;
342+
}
343+
else
344+
{
345+
warn(name,lineNr,"Ignoring unknown extension key '%s'...",key.c_str());
346+
}
347+
}
348+
else
366349
{
367-
warn(name,lineNr,"Assignment of extension field expected!\n");
368-
continue;
350+
warn(name,lineNr,"Assignment of style sheet name expected!");
369351
}
370-
QCString key=s.left(sepStart);
371-
QCString data=s.data() + sepStart + sepLength;
372-
373-
if (key == "Title") rtf_title = data.data();
374-
if (key == "Subject") rtf_subject = data.data();
375-
if (key == "Comments") rtf_comments = data.data();
376-
if (key == "Company") rtf_company = data.data();
377-
if (key == "LogoFilename") rtf_logoFilename = data.data();
378-
if (key == "Author") rtf_author = data.data();
379-
if (key == "Manager") rtf_manager = data.data();
380-
if (key == "DocumentType") rtf_documentType = data.data();
381-
if (key == "DocumentId") rtf_documentId = data.data();
382-
if (key == "Keywords") rtf_keywords = data.data();
383352
lineNr++;
384353
}
385354
}

src/rtfstyle.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ struct StyleData
6363

6464
public:
6565
StyleData() = default;
66-
StyleData(const char* reference, const char* definition);
67-
bool setStyle(const char* s, const char* styleName);
66+
StyleData(const std::string &reference, const std::string &definition);
67+
bool setStyle(const std::string &command, const std::string &styleName);
6868
const char *reference() const { return m_reference.c_str(); }
6969
const char *definition() const { return m_definition.c_str(); }
7070
uint index() const { return m_index; }

0 commit comments

Comments
 (0)