Skip to content

Commit

Permalink
Refactoring: replace QRegExp by std::regex in rtfstyle.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
doxygen committed Feb 20, 2021
1 parent 7974279 commit 58d1307
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 125 deletions.
2 changes: 1 addition & 1 deletion src/docparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ static int handleStyleArgument(DocNode *parent,DocNodeList &children,
{
static std::regex specialChar("[.,|()\\[\\]:;\\?]");
if (tok==TK_WORD && g_token->name.length()==1 &&
std::regex_match(g_token->name.str(),specialChar))
std::regex_search(g_token->name.str(),specialChar))
{
// special character that ends the markup command
return tok;
Expand Down
2 changes: 1 addition & 1 deletion src/htmlhelp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2,
static std::regex re("@[[:digit:]]+");
std::string key = level1;
if (level2) key+= std::string("?") + level2;
if (std::regex_match(key,re)) // skip anonymous stuff
if (std::regex_search(key,re)) // skip anonymous stuff
{
return;
}
Expand Down
211 changes: 90 additions & 121 deletions src/rtfstyle.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/******************************************************************************
*
*
*
*
* Copyright (C) 1997-2015 by Dimitri van Heesch.
* Copyright (C) 1997-2021 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
Expand All @@ -16,15 +13,13 @@
*
*/

#include <stdlib.h>
#include <qfile.h>
#include <qregexp.h>
#include <qtextstream.h>
#include <regex>
#include <string>
#include <fstream>

#include "rtfstyle.h"
#include "message.h"


RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels];

QCString rtf_title;
Expand All @@ -38,6 +33,21 @@ QCString rtf_documentType;
QCString rtf_documentId;
QCString rtf_keywords;

static std::map<std::string,QCString &> g_styleMap =
{
{ "Title", rtf_title },
{ "Subject", rtf_subject },
{ "Comments", rtf_comments },
{ "Company", rtf_company },
{ "LogoFilename", rtf_logoFilename },
{ "Author", rtf_author },
{ "Manager", rtf_manager },
{ "DocumentType", rtf_documentType },
{ "DocumentId", rtf_documentId },
{ "Keywords", rtf_keywords }
};


char rtf_Style_Reset[] = "\\pard\\plain ";

#define RTF_LatexToc(lvl,nest,nxt,pos,twps) \
Expand Down Expand Up @@ -224,116 +234,80 @@ Rtf_Style_Default rtf_Style_Default[] =
}
};

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

StyleData::StyleData(const char* reference, const char* definition)
StyleData::StyleData(const std::string &reference, const std::string &definition)
{
const char *ref = reference;

int start = s_clause.match(ref); ASSERT(start >= 0);
ref += start;
m_index = (int)atol(ref + 2); ASSERT(m_index > 0);

m_reference = ref;
std::smatch match;
if (regex_search(reference,match,s_clause))
{
m_index = static_cast<int>(std::stoul(match[1].str()));
}
else // error
{
m_index = 0;
}
m_reference = reference;
m_definition = definition;
}

bool StyleData::setStyle(const char* s, const char* styleName)
bool StyleData::setStyle(const std::string &command, const std::string &styleName)
{
static const QRegExp subgroup("^{[^}]*}\\s*");
static const QRegExp any_clause("^\\\\[a-z][a-z0-9-]*\\s*");

int len = 0; // length of a particular RTF formatting control
int ref_len = 0; // length of the whole formatting section of a style
int start = s_clause.match(s, 0, &len);
if (start < 0)
std::smatch match;
if (!regex_search(command,match,s_clause))
{
err("Style sheet '%s' contains no '\\s' clause.\n{%s}\n", styleName, s);
return FALSE;
}
s += start;
m_index = (int)atol(s + 2); ASSERT(m_index > 0);

// search for the end of pure formatting codes
const char* end = s + len;
ref_len = len;
bool haveNewDefinition = TRUE;
for(;;)
{
if (*end == '{')
{
// subgroups are used for \\additive
if (0 != subgroup.match(end, 0, &len))
break;
else
{
end += len;
ref_len += len;
}
}
else if (*end == '\\')
{
if (0 == qstrncmp(end, "\\snext", 6))
break;
if (0 == qstrncmp(end, "\\sbasedon", 9))
break;
if (0 != any_clause.match(end, 0, &len))
break;
end += len;
ref_len += len;
}
else if (*end == 0)
{ // no style-definition part, keep default value
haveNewDefinition = FALSE;
break;
}
else // plain name without leading \\snext
break;
err("Style sheet '%s' contains no '\\s' clause.\n{%s}", styleName.c_str(), command.c_str());
return false;
}
m_reference = s;
if (haveNewDefinition)
m_index = static_cast<int>(std::stoul(match[1].str()));

static std::regex definition_splitter("^(.*)(\\\\sbasedon[[:digit:]]+.*)$");
if (regex_match(command,match,definition_splitter))
{
m_definition = end;
m_reference = match[1].str();
m_definition = match[2].str();
}
return TRUE;

return true;
}


void loadStylesheet(const char *name, StyleDataMap& map)
{
QFile file(name);
if (!file.open(IO_ReadOnly))
std::ifstream file(name);
if (!file.is_open())
{
err("Can't open RTF style sheet file %s. Using defaults.\n",name);
err("Can't open RTF style sheet file %s. Using defaults.",name);
return;
}
msg("Loading RTF style sheet %s...\n",name);

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

while (!t.eof())
for (std::string line ; getline(file,line) ; ) // for each line
{
QCString s(4096); // string buffer of max line length
s = t.readLine().stripWhiteSpace().utf8();
if (s.isEmpty() || s.at(0)=='#') continue; // skip blanks & comments
int sepLength;
int sepStart = separator.match(s,0,&sepLength);
if (sepStart<=0) // no valid assignment statement
if (line.empty() || line[0]=='#') continue; // skip blanks & comments
static std::regex assignment_splitter("[[:space:]]*=[[:space:]]*");
std::smatch match;
if (std::regex_search(line,match,assignment_splitter))
{
warn(name,lineNr,"Assignment of style sheet name expected!\n");
continue;
std::string key = match.prefix();
std::string value = match.suffix();
auto it = map.find(key);
if (it!=map.end())
{
StyleData& styleData = it->second;
styleData.setStyle(value,key);
}
else
{
warn(name,lineNr,"Unknown style sheet name %s ignored.",key.data());
}
}
QCString key=s.left(sepStart);
auto it = map.find(key.str());
if (it==map.end()) // not a valid style sheet name
else
{
warn(name,lineNr,"Unknown style sheet name %s ignored.\n",key.data());
continue;
warn(name,lineNr,"Assignment of style sheet name expected line='%s'!",line.c_str());
}
StyleData& styleData = it->second;
s+=" "; // add command separator
styleData.setStyle(s.data() + sepStart + sepLength, key.data());
lineNr++;
}
}
Expand All @@ -342,44 +316,39 @@ StyleDataMap rtf_Style;

void loadExtensions(const char *name)
{
QFile file(name);
if (!file.open(IO_ReadOnly))
std::ifstream file(name);
if (!file.is_open())
{
err("Can't open RTF extensions file %s. Using defaults.\n",name);
err("Can't open RTF extensions file %s. Using defaults.",name);
return;
}
msg("Loading RTF extensions %s...\n",name);

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

while (!t.eof())
for (std::string line ; getline(file,line) ; ) // for each line
{
QCString s(4096); // string buffer of max line length
s = t.readLine().stripWhiteSpace().utf8();
if (s.length()==0 || s.at(0)=='#') continue; // skip blanks & comments
int sepLength;
int sepStart = separator.match(s,0,&sepLength);
if (sepStart<=0) // no valid assignment statement
if (line.empty() || line[0]=='#') continue; // skip blanks & comments
std::smatch match;
static std::regex assignment_splitter("[[:space:]]*=[[:space:]]*");
if (std::regex_search(line,match,assignment_splitter))
{
std::string key = match.prefix();
std::string value = match.suffix();
auto it = g_styleMap.find(key);
if (it!=g_styleMap.end())
{
it->second = value;
}
else
{
warn(name,lineNr,"Ignoring unknown extension key '%s'...",key.c_str());
}
}
else
{
warn(name,lineNr,"Assignment of extension field expected!\n");
continue;
warn(name,lineNr,"Assignment of style sheet name expected!");
}
QCString key=s.left(sepStart);
QCString data=s.data() + sepStart + sepLength;

if (key == "Title") rtf_title = data.data();
if (key == "Subject") rtf_subject = data.data();
if (key == "Comments") rtf_comments = data.data();
if (key == "Company") rtf_company = data.data();
if (key == "LogoFilename") rtf_logoFilename = data.data();
if (key == "Author") rtf_author = data.data();
if (key == "Manager") rtf_manager = data.data();
if (key == "DocumentType") rtf_documentType = data.data();
if (key == "DocumentId") rtf_documentId = data.data();
if (key == "Keywords") rtf_keywords = data.data();
lineNr++;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/rtfstyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ struct StyleData

public:
StyleData() = default;
StyleData(const char* reference, const char* definition);
bool setStyle(const char* s, const char* styleName);
StyleData(const std::string &reference, const std::string &definition);
bool setStyle(const std::string &command, const std::string &styleName);
const char *reference() const { return m_reference.c_str(); }
const char *definition() const { return m_definition.c_str(); }
uint index() const { return m_index; }
Expand Down

0 comments on commit 58d1307

Please sign in to comment.