summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/code.l2
-rw-r--r--src/doctokenizer.l2
-rw-r--r--src/doxygen.cpp7
-rw-r--r--src/formula.cpp99
-rw-r--r--src/scanner.l2
-rw-r--r--src/util.cpp2
6 files changed, 105 insertions, 9 deletions
diff --git a/src/code.l b/src/code.l
index 1c60fcf..ddeca01 100644
--- a/src/code.l
+++ b/src/code.l
@@ -396,7 +396,7 @@ CASTKW ("const_cast"|"dynamic_cast"|"reinterpret_cast"|"static_cast")
CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++"
ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
-LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
+LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"|"<=>"
BITOP "&"|"|"|"^"|"<<"|">>"|"~"
OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 7f3fbc9..5317de5 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -395,7 +395,7 @@ FUNCARG "("{FUNCPART}")"({BLANK}*("volatile"|"const"){BLANK})?
FUNCARG2 "("{FUNCPART}")"({BLANK}*("volatile"|"const"))?
OPNEW {BLANK}+"new"({BLANK}*"[]")?
OPDEL {BLANK}+"delete"({BLANK}*"[]")?
-OPNORM {OPNEW}|{OPDEL}|"+"|"-"|"*"|"/"|"%"|"^"|"&"|"|"|"~"|"!"|"="|"<"|">"|"+="|"-="|"*="|"/="|"%="|"^="|"&="|"|="|"<<"|">>"|"<<="|">>="|"=="|"!="|"<="|">="|"&&"|"||"|"++"|"--"|","|"->*"|"->"|"[]"|"()"
+OPNORM {OPNEW}|{OPDEL}|"+"|"-"|"*"|"/"|"%"|"^"|"&"|"|"|"~"|"!"|"="|"<"|">"|"+="|"-="|"*="|"/="|"%="|"^="|"&="|"|="|"<<"|">>"|"<<="|">>="|"=="|"!="|"<="|">="|"&&"|"||"|"++"|"--"|","|"->*"|"->"|"[]"|"()"|"<=>"
OPCAST {BLANK}+[^<(\r\n.,][^(\r\n.,]*
OPMASK ({BLANK}*{OPNORM}{FUNCARG})
OPMASKOPT ({BLANK}*{OPNORM}{FUNCARG}?)|({OPCAST}{FUNCARG})
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 0728d8f..41d7b0a 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -3018,8 +3018,13 @@ static void addMethodToClass(const Entry *root,ClassDef *cd,
else mtype=MemberType_Function;
// strip redundant template specifier for constructors
+ int j = -1;
if ((fd==0 || fd->getLanguage()==SrcLangExt_Cpp) &&
- name.left(9)!="operator " && (i=name.find('<'))!=-1 && name.find('>')!=-1)
+ name.left(9)!="operator " && // not operator
+ (i=name.find('<'))!=-1 && // containing <
+ (j=name.find('>'))!=-1 && // or >
+ (j!=i+2 || name.at(i+1)!='=') // but not the C++20 spaceship operator <=>
+ )
{
name=name.left(i);
}
diff --git a/src/formula.cpp b/src/formula.cpp
index cb28aba..ca50c9c 100644
--- a/src/formula.cpp
+++ b/src/formula.cpp
@@ -34,6 +34,8 @@
#include "doxygen.h" // for Doxygen::indexList
#include "index.h" // for Doxygen::indexList
+static int determineInkscapeVersion(QDir &thisDir);
+
// Remove the temporary files
#define RM_TMP_FILES (true)
//#define RM_TMP_FILES (false)
@@ -98,10 +100,10 @@ void FormulaManager::readFormulas(const char *dir,bool doCompare)
int w=-1,h=-1;
if (ei!=-1 && ei>hi && ei<se) // new format
{
- int xi=formName.find('x',hi);
+ int xi=formName.find('x',ei);
if (xi!=-1)
{
- w=formName.mid(hi+1,xi-hi-1).toInt();
+ w=formName.mid(ei+1,xi-ei-1).toInt();
h=formName.mid(xi+1).toInt();
}
formName = formName.left(ei);
@@ -294,22 +296,37 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c
}
Portable::sysTimerStop();
+ // if we have pdf2svg available use it to create a SVG image
if (Portable::checkForExecutable("pdf2svg"))
{
sprintf(args,"%s_tmp.pdf form_%d.svg",formBase.data(),pageNum);
Portable::sysTimerStart();
if (Portable::system("pdf2svg",args)!=0)
{
- err("Problems running pdf2svg. Check your installation!\n");
+ err("Problems running pdf2svg. Check your installation!\n");
Portable::sysTimerStop();
QDir::setCurrent(oldDir);
return;
}
Portable::sysTimerStop();
}
- else if (Portable::checkForExecutable("inkscape"))
+ else if (Portable::checkForExecutable("inkscape")) // alternative is to use inkscape
{
- sprintf(args,"-l form_%d.svg -z %s_tmp.pdf 2>%s",pageNum,formBase.data(),Portable::devNull());
+ int inkscapeVersion = determineInkscapeVersion(thisDir);
+ if (inkscapeVersion == -1)
+ {
+ err("Problems determining the version of inkscape. Check your installation!\n");
+ QDir::setCurrent(oldDir);
+ return;
+ }
+ else if (inkscapeVersion == 0)
+ {
+ sprintf(args,"-l form_%d.svg -z %s_tmp.pdf 2>%s",pageNum,formBase.data(),Portable::devNull());
+ }
+ else // inkscapeVersion >= 1
+ {
+ sprintf(args,"--export-type=svg --export-filename=form_%d.svg %s_tmp.pdf 2>%s",pageNum,formBase.data(),Portable::devNull());
+ }
Portable::sysTimerStart();
if (Portable::system("inkscape",args)!=0)
{
@@ -493,3 +510,75 @@ FormulaManager::DisplaySize FormulaManager::displaySize(int formulaId) const
return p->getDisplaySize(formulaId);
}
+// helper function to detect and return the major version of inkscape.
+// return -1 if the version cannot be determined.
+static int determineInkscapeVersion(QDir &thisDir)
+{
+ // The command line interface (CLI) of Inkscape 1.0 has changed in comparison to
+ // previous versions. In order to invokine Inkscape, the used version is detected
+ // and based on the version the right syntax of the CLI is chosen.
+ static int inkscapeVersion = -2;
+ if (inkscapeVersion == -2) // initial one time version check
+ {
+ QCString inkscapeVersionFile = "inkscape_version" ;
+ inkscapeVersion = -1;
+ QCString args = "-z --version >"+inkscapeVersionFile+" 2>"+Portable::devNull();
+ Portable::sysTimerStart();
+ if (Portable::system("inkscape",args)!=0)
+ {
+ // looks like the old syntax gave problems, lets try the new syntax
+ args = " --version >"+inkscapeVersionFile+" 2>"+Portable::devNull();
+ if (Portable::system("inkscape",args)!=0)
+ {
+ Portable::sysTimerStop();
+ return -1;
+ }
+ }
+ // read version file and determine major version
+ QFile inkscapeVersionIn(inkscapeVersionFile);
+ if (inkscapeVersionIn.open(IO_ReadOnly))
+ {
+ int maxLineLen=1024;
+ while (!inkscapeVersionIn.atEnd())
+ {
+ QCString buf(maxLineLen);
+ int numBytes = inkscapeVersionIn.readLine(buf.rawData(),maxLineLen);
+ if (numBytes>0)
+ {
+ buf.resize(numBytes+1);
+ int dotPos = buf.find('.');
+ if (buf.startsWith("Inkscape ") && dotPos>0)
+ {
+ // get major version
+ bool ok;
+ int version = buf.mid(9,dotPos-9).toInt(&ok);
+ if (!ok)
+ {
+ Portable::sysTimerStop();
+ return -1;
+ }
+ inkscapeVersion = version;
+ break;
+ }
+ }
+ else
+ {
+ Portable::sysTimerStop();
+ return -1;
+ }
+ }
+ inkscapeVersionIn.close();
+ }
+ else // failed to open version file
+ {
+ Portable::sysTimerStop();
+ return -1;
+ }
+ if (RM_TMP_FILES)
+ {
+ thisDir.remove(inkscapeVersionFile);
+ }
+ Portable::sysTimerStop();
+ }
+ return inkscapeVersion;
+}
diff --git a/src/scanner.l b/src/scanner.l
index e9cad5f..f066b5b 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -249,7 +249,7 @@ RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
RAWEND ")"[^ \t\(\)\\]{0,16}\"
ARITHOP "+"|"-"|"/"|"*"|"%"|"--"|"++"
ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
-LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
+LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"|"<=>"
BITOP "&"|"|"|"^"|"<<"|">>"|"~"
OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
diff --git a/src/util.cpp b/src/util.cpp
index f16a28e..2b82afb 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -4872,6 +4872,7 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor
case '@': growBuf.addStr("_0d"); break;
case ']': growBuf.addStr("_0e"); break;
case '[': growBuf.addStr("_0f"); break;
+ case '#': growBuf.addStr("_0g"); break;
default:
if (c<0)
{
@@ -4986,6 +4987,7 @@ QCString unescapeCharsInString(const char *s)
case 'd': result+='@'; p+=2; break; // _0d -> '@'
case 'e': result+=']'; p+=2; break; // _0e -> ']'
case 'f': result+='['; p+=2; break; // _0f -> '['
+ case 'g': result+='#'; p+=2; break; // _0g -> '#'
default: // unknown escape, just pass underscore character as-is
result+=c;
break;