From df2512b5c4161fbf31751478c81c9effd2715a6a Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Tue, 16 Feb 2021 21:02:45 +0100 Subject: Refactoring: replace QRegExp by std::regex in doxygen.cpp --- src/doxygen.cpp | 172 ++++++++++++++++++++++++++------------------------------ 1 file changed, 81 insertions(+), 91 deletions(-) diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 744db35..f7849a3 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -32,6 +31,7 @@ #include #include #include +#include #include "version.h" #include "doxygen.h" @@ -2220,12 +2220,12 @@ static MemberDef *addVariableToFile( { ttype.stripPrefix("struct "); ttype.stripPrefix("union "); - static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); - int l,s; - s = re.match(ttype,0,&l); - if (s>=0) + static std::regex re("[:alpha:]_][:alnum:]_]*"); + std::smatch match; + std::string typ = ttype.str(); + if (std::regex_search(typ,match,re)) { - QCString typeValue = ttype.mid(s,l); + QCString typeValue = match.str(); ClassDefMutable *cd = getClassMutable(typeValue); if (cd) { @@ -2432,27 +2432,36 @@ static MemberDef *addVariableToFile( * \returns -1 if this is not a function pointer variable or * the index at which the closing brace of (...*name) was found. */ -static int findFunctionPtr(const QCString &type,int lang, int *pLength=0) +static int findFunctionPtr(const std::string &type,SrcLangExt lang, int *pLength=0) { if (lang == SrcLangExt_Fortran || lang == SrcLangExt_VHDL) { return -1; // Fortran and VHDL do not have function pointers } - static const QRegExp re("([^)]*[\\*\\^][^)]*)"); - int i=-1,l; - int bb=type.find('<'); - int be=type.findRev('>'); - if (!type.isEmpty() && // return type is non-empty - (i=re.match(type,0,&l))!=-1 && // contains (...*...) - type.find("operator")==-1 && // not an operator - (type.find(")(")==-1 || type.find("typedef ")!=-1) && - // not a function pointer return type + + static std::regex re("\\([^)]*[*\\^][^)]*\\)"); + std::smatch match; + size_t i=std::string::npos; + size_t l=0; + if (std::regex_search(type,match,re)) // contains (...*...) + { + i = match.position(); + l = match.length(); + } + size_t bb=type.find('<'); + size_t be=type.rfind('>'); + + if (!type.empty() && // return type is non-empty + i!=std::string::npos && // contains (...*...) + type.find("operator")==std::string::npos && // not an operator + (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) && + // not a function pointer return type !(bb type" as a function pointer ) { - if (pLength) *pLength=l; - //printf("findFunctionPtr=%d\n",i); - return i; + if (pLength) *pLength=(int)l; + //printf("findFunctionPtr=%d\n",(int)i); + return (int)i; } else { @@ -2467,8 +2476,6 @@ static int findFunctionPtr(const QCString &type,int lang, int *pLength=0) */ static bool isVarWithConstructor(const Entry *root) { - static QRegExp initChars("[0-9\"'&*!^]+"); - static QRegExp idChars("[a-z_A-Z][a-z_A-Z0-9]*"); bool result=FALSE; bool typeIsClass = false; bool typePtrType = false; @@ -2525,9 +2532,12 @@ static bool isVarWithConstructor(const Entry *root) } for (const Argument &a : root->argList) { + static std::regex initChars("[0-9\"'&*!^]+"); + std::smatch match; if (!a.name.isEmpty() || !a.defval.isEmpty()) { - if (a.name.find(initChars)==0) + std::string name = a.name.str(); + if (std::regex_search(name,match,initChars) && match.position()==0) { result=TRUE; } @@ -2556,17 +2566,18 @@ static bool isVarWithConstructor(const Entry *root) result=FALSE; // argument is a typedef goto done; } - if (a.type.find(initChars)==0) + std::string atype = a.type.str(); + if (std::regex_search(atype,match,initChars) && match.position()==0) { result=TRUE; // argument type starts with typical initializer char goto done; } - QCString resType=resolveTypeDef(ctx,a.type); - if (resType.isEmpty()) resType=a.type; - int len; - if (idChars.match(resType,0,&len)==0) // resType starts with identifier + std::string resType=resolveTypeDef(ctx,a.type).str(); + if (resType.empty()) resType=atype; + static std::regex idChars("[[:alpha:]_][[:alnum:]_]*"); + if (std::regex_search(resType,match,idChars) && match.position()==0) // resType starts with identifier { - resType=resType.left(len); + resType=match.str(); //printf("resType=%s\n",resType.data()); if (resType=="int" || resType=="long" || resType=="float" || resType=="double" || resType=="char" || resType=="signed" || @@ -2613,15 +2624,15 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) // type="" name="int *" args="(var[10])" type=name; - static const QRegExp reName("[a-z_A-Z][a-z_A-Z0-9]*"); - int l=0; - int j=0; - int i=args.isEmpty() ? -1 : reName.match(args,0,&l); - if (i!=-1) + std::string sargs = args.str(); + static const std::regex reName("[[:alpha:]_][[:alnum:]_]*"); + std::smatch match; + if (std::regex_search(sargs,match,reName)) { - name=args.mid(i,l); - j=args.find(')',i+l)-i-l; - if (j >= 0) args=args.mid(i+l,j); + name = match.str(); // e.g. 'var' in '(var[10])' + sargs = match.suffix().str(); // e.g. '[10]) in '(var[10])' + size_t j = sargs.find(')'); + if (j!=std::string::npos) args=sargs.substr(0,j); // extract, e.g '[10]' from '[10])' } //printf("new: type='%s' name='%s' args='%s'\n", // type.data(),name.data(),args.data()); @@ -2629,7 +2640,7 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) else { int i=isFuncPtr; - if (i==-1 && (root->spec&Entry::Alias)==0) i=findFunctionPtr(type,root->lang); // for typedefs isFuncPtr is not yet set + if (i==-1 && (root->spec&Entry::Alias)==0) i=findFunctionPtr(type.str(),root->lang); // for typedefs isFuncPtr is not yet set Debug::print(Debug::Variables,0," functionPtr? %s\n",i!=-1?"yes":"no"); if (i!=-1) // function pointer { @@ -2871,7 +2882,7 @@ static void buildVarList(const Entry *root) (root->section==Entry::VARIABLE_SEC // it's a variable ) || (root->section==Entry::FUNCTION_SEC && // or maybe a function pointer variable - (isFuncPtr=findFunctionPtr(root->type,root->lang))!=-1 + (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1 ) || (root->section==Entry::FUNCTION_SEC && // class variable initialized by constructor isVarWithConstructor(root) @@ -3036,24 +3047,8 @@ static void addMethodToClass(const Entry *root,ClassDefMutable *cd, { FileDef *fd=root->fileDef(); - int l; - static QRegExp re("([a-z_A-Z0-9: ]*[ &*]+[ ]*"); QCString type = rtype; QCString args = rargs; - int ts=type.find('<'); - int te=type.findRev('>'); - int i=re.match(type,0,&l); - if (i!=-1 && ts!=-1 && ts, see bug 677315 - { - i=-1; - } - - if (cd->getLanguage()==SrcLangExt_Cpp && // only C has pointers - !type.isEmpty() && (root->spec&Entry::Alias)==0 && i!=-1) // function variable - { - args+=type.right(type.length()-i-l); - type=type.left(i+l); - } QCString name=removeRedundantWhiteSpace(rname); if (name.left(2)=="::") name=name.right(name.length()-2); @@ -3066,6 +3061,7 @@ static void addMethodToClass(const Entry *root,ClassDefMutable *cd, else mtype=MemberType_Function; // strip redundant template specifier for constructors + int i = -1; int j = -1; if ((fd==0 || fd->getLanguage()==SrcLangExt_Cpp) && name.left(9)!="operator " && // not operator @@ -3373,21 +3369,9 @@ static void buildFunctionList(const Entry *root) } } - static QRegExp re("([a-z_A-Z0-9: ]*[ &*]+[ ]*"); - int ts=root->type.find('<'); - int te=root->type.findRev('>'); - int ti; if (!root->parent()->name.isEmpty() && (root->parent()->section & Entry::COMPOUND_MASK) && - cd && - // do some fuzzy things to exclude function pointers - (root->type.isEmpty() || - ((ti=root->type.find(re,0))==-1 || // type does not contain ..(..* - (ts!=-1 && ts - root->args.find(")[")!=-1) || // and args not )[.. -> function pointer - root->type.find(")(")!=-1 || root->type.find("operator")!=-1 || // type contains ..)(.. and not "operator" - cd->getLanguage()!=SrcLangExt_Cpp // language other than C - ) + cd ) { Debug::print(Debug::Functions,0," --> member %s of class %s!\n", @@ -3826,25 +3810,26 @@ static void transferRelatedFunctionDocumentation() * Example: A template class A with template arguments * that inherits from B will have T and S in the dictionary. */ -static TemplateNameMap getTemplateArgumentsInName(const ArgumentList &templateArguments,const QCString &name) +static TemplateNameMap getTemplateArgumentsInName(const ArgumentList &templateArguments,const std::string &name) { std::map templateNames; - static QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); int count=0; for (const Argument &arg : templateArguments) { - int i,p=0,l; - while ((i=re.match(name,p,&l))!=-1) + static std::regex re("[[:alpha:]_][[:alnum:]_:]*"); + std::sregex_iterator it(name.begin(),name.end(),re); + std::sregex_iterator end; + for (; it!=end ; ++it) { - QCString n = name.mid(i,l); + const auto &match = *it; + std::string n = match.str(); if (n==arg.name) { - if (templateNames.find(n.str())==templateNames.end()) + if (templateNames.find(n)==templateNames.end()) { - templateNames.insert(std::make_pair(n.str(),count)); + templateNames.insert(std::make_pair(n,count)); } } - p=i+l; } } return templateNames; @@ -3947,7 +3932,7 @@ static void findUsedClassesForClass(const Entry *root, TemplateNameMap formTemplateNames; if (templateNames.empty()) { - formTemplateNames = getTemplateArgumentsInName(formalArgs,usedName); + formTemplateNames = getTemplateArgumentsInName(formalArgs,usedName.str()); } BaseInfo bi(usedName,Public,Normal); findClassRelation(root,context,instanceCd,&bi,formTemplateNames,TemplateInstances,isArtificial); @@ -4073,7 +4058,7 @@ static void findBaseClassesForClass( TemplateNameMap formTemplateNames; if (templateNames.empty()) { - formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name); + formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str()); } BaseInfo tbi = bi; tbi.name = substituteTemplateArgumentsInString(bi.name.str(),formalArgs,actualArgs); @@ -4793,7 +4778,7 @@ static void computeTemplateClassRelations() if (!tl.empty()) { TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames(); - TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name); + TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str()); // for each template name that we inherit from we need to // substitute the formal with the actual arguments TemplateNameMap actualTemplateNames; @@ -5336,18 +5321,23 @@ static bool scopeIsTemplate(const Definition *d) static QCString substituteTemplatesInString( const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, - const QCString &src + const std::string &src ) { - QCString dst; - QRegExp re( "[A-Za-z_][A-Za-z_0-9]*"); + std::string dst; + static const std::regex re("[[:alpha:]_][[:alnum:]_]*"); + std::sregex_iterator it(src.begin(),src.end(),re); + std::sregex_iterator end; //printf("type=%s\n",sa->type.data()); - int i,p=0,l; - while ((i=re.match(src,p,&l))!=-1) // for each word in srcType + size_t p=0; + for (; it!=end ; ++it) // for each word in srcType { + const auto &match = *it; + size_t i = match.position(); + size_t l = match.length(); bool found=FALSE; - dst+=src.mid(p,i-p); - QCString name=src.mid(i,l); + dst+=src.substr(p,i-p); + std::string name=match.str(); auto srcIt = srcTempArgLists.begin(); auto dstIt = dstTempArgLists.begin(); @@ -5390,7 +5380,7 @@ static QCString substituteTemplatesInString( } if (!tdaName.isEmpty()) { - name=tdaName; // substitute + name=tdaName.str(); // substitute found=TRUE; } } @@ -5406,7 +5396,7 @@ static QCString substituteTemplatesInString( dst+=name; p=i+l; } - dst+=src.right(src.length()-p); + dst+=src.substr(p); //printf(" substituteTemplatesInString(%s)=%s\n", // src.data(),dst.data()); return dst; @@ -5422,8 +5412,8 @@ static void substituteTemplatesInArgList( auto dstIt = dst.begin(); for (const Argument &sa : src) { - QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type); - QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array); + QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str()); + QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str()); if (dstIt == dst.end()) { Argument da = sa; @@ -5445,7 +5435,7 @@ static void substituteTemplatesInArgList( dst.setPureSpecifier(src.pureSpecifier()); dst.setTrailingReturnType(substituteTemplatesInString( srcTempArgLists,dstTempArgLists, - src.trailingReturnType())); + src.trailingReturnType().str())); //printf("substituteTemplatesInArgList: replacing %s with %s\n", // argListToString(src).data(),argListToString(dst).data() // ); @@ -6647,7 +6637,7 @@ static void filterMemberDocumentation(const Entry *root,const QCString relates) QCString type = root->type; QCString args = root->args; if ( // detect func variable/typedef to func ptr - (i=findFunctionPtr(type,root->lang,&l))!=-1 + (i=findFunctionPtr(type.str(),root->lang,&l))!=-1 ) { //printf("Fixing function pointer!\n"); -- cgit v0.12