📄 pre.l
字号:
while (k<d.length() && d.at(k)>='0' && d.at(k)<='9') key+=d.at(k++); if (!hash) { // search for ## forward l=k; if (l<(int)d.length() && d.at(l)=='"') l++; while (l<(int)d.length() && d.at(l)==' ') l++; if (l<(int)d.length()-1 && d.at(l)=='#' && d.at(l+1)=='#') hash=TRUE; } //printf("request key %s result %s\n",key.data(),argTable[key]->data()); if (key.length()>1 && (subst=argTable[key])) { QCString substArg=*subst; //printf("substArg=`%s'\n",substArg.data()); // only if no ## operator is before or after the argument // marker we do macro expansion. if (!hash) expandExpression(substArg,0,0); if (inString) { //printf("`%s'=stringize(`%s')\n",stringize(*subst).data(),subst->data()); // if the marker is inside a string (because a # was put // before the macro name) we must escape " and \ characters resExpr+=stringize(substArg); } else { if (g_nospaces) { resExpr+=substArg; } else { resExpr+=" "+substArg+" "; } } } } } else // no marker, just copy { if (!inString && d.at(k)=='\"') { inString=TRUE; // entering a literal string } else if (inString && d.at(k)=='\"' && d.at(k-1)!='\\') { inString=FALSE; // leaving a literal string } resExpr+=d.at(k++); } } len=j-pos; result=resExpr; //printf("result after substitution `%s' expr=`%s'\n", // result.data(),expr.mid(pos,len).data()); return TRUE; } else { return FALSE; }}/*! returns the next identifier in string \a expr by starting at position \a p. * The position of the identifier is returned (or -1 if nothing is found) * and \a l is its length. Any quoted strings are skipping during the search. */static int getNextId(const QCString &expr,int p,int *l){ int n; while (p<(int)expr.length()) { char c=expr.at(p++); if (isalpha(c) || c=='_') // read id { n=p-1; while (p<(int)expr.length() && isId(expr.at(p)) ) p++; *l=p-n; return n; } else if (c=='"') // skip string { char pc=c; if (p<(int)expr.length()) c=expr.at(p); while (p<(int)expr.length() && (c!='"' || pc=='\\')) { pc=c; c=expr.at(p); p++; } } } return -1;}/*! preforms recursive macro expansion on the string \a expr * starting at position \a pos. * May read additional characters from the input while re-scanning! * If \a expandAll is \c TRUE then all macros in the expression are * expanded, otherwise only the first is expanded. */static void expandExpression(QCString &expr,QCString *rest,int pos){ //printf("expandExpression(%s,%s)\n",expr.data(),rest ? rest->data() : 0); QCString macroName; QCString expMacro; int i=pos,l,p,len; while ((p=getNextId(expr,i,&l))!=-1) // search for an macro name { bool replaced=FALSE; macroName=expr.mid(p,l); //printf("macroName %s found\n",macroName.data()); if (p<2 || !(expr.at(p-2)=='@' && expr.at(p-1)=='-')) // no-rescan marker? { if (g_expandedDict->find(macroName)==0) // expand macro { Define *def=isDefined(macroName); if (def && def->nargs==-1) // simple macro { // substitute the definition of the macro //printf("macro `%s'->`%s'\n",macroName.data(),def->definition.data()); if (g_nospaces) { expMacro=def->definition.stripWhiteSpace(); } else { expMacro=" "+def->definition.stripWhiteSpace()+" "; } //expMacro=def->definition.stripWhiteSpace(); replaced=TRUE; len=l; //printf("simple macro expansion=`%s'->`%s'\n",macroName.data(),expMacro.data()); } else if (def && def->nargs>=0) // function macro { replaced=replaceFunctionMacro(expr,rest,p+l,len,def,expMacro); len+=l; } if (replaced) // expand the macro and rescan the expression { //printf("replacing `%s'->`%s'\n",expr.mid(p,len).data(),expMacro.data()); QCString resultExpr=expMacro; QCString restExpr=expr.right(expr.length()-len-p); processConcatOperators(resultExpr); if (!def->nonRecursive) { g_expandedDict->insert(macroName,def); expandExpression(resultExpr,&restExpr,0); g_expandedDict->remove(macroName); } expr=expr.left(p)+resultExpr+restExpr; i=p; //printf("new expression: %s\n",expr.data()); } else // move to the next macro name { //printf("moving to the next macro old=%d new=%d\n",i,p+l); i=p+l; } } else // move to the next macro name { expr=expr.left(p)+"@-"+expr.right(expr.length()-p); //printf("macro already expanded, moving to the next macro expr=%s\n",expr.data()); i=p+l+2; //i=p+l; } } else // no re-scan marker found, skip the macro name { //printf("skipping marked macro\n"); i=p+l; } }}/*! replaces all occurrences of @@ in \a s by @ * All identifiers found are replaced by 0L * \par assumption: * \a s only contains pairs of @@'s. */QCString removeIdsAndMarkers(const char *s){ //printf("removeIdsAndMarkers(%s)\n",s); const char *p=s; char c; bool inNum=FALSE; QCString result; if (p) { while ((c=*p)) { if (c=='@') // replace @@ with @ { if (*(p+1)=='@') { result+=c; } p+=2; } else if (isdigit(c)) // number { result+=c; p++; inNum=TRUE; } else if (c=='d') // identifier starting with a `d' { if (strncmp(p,"defined ",8)==0 || strncmp(p,"defined(",8)==0) // defined keyword { p+=7; // skip defined } else { result+="0L"; p++; while ((c=*p) && isId(c)) p++; } } else if ((isalpha(c) || c=='_') && !inNum) // replace identifier with 0L { result+="0L"; p++; while ((c=*p) && isId(c)) p++; } else { result+=c; char lc=tolower(c); if (lc!='l' && lc!='u') inNum=FALSE; p++; } } } return result;}/*! replaces all occurrences of @@ in \a s by @ * \par assumption: * \a s only contains pairs of @@'s */QCString removeMarkers(const char *s){ const char *p=s; char c; QCString result; if (p) { while ((c=*p)) { if (c=='@') // replace @@ with @ { if (*(p+1)=='@') { result+=c; } p+=2; } else { result+=c; p++; } } } return result;}/*! compute the value of the expression in string \a expr. * If needed the function may read additional characters from the input. */bool computeExpression(const QCString &expr){ QCString e=expr; expandExpression(e,0,0); //printf("after expansion `%s'\n",e.data()); e = removeIdsAndMarkers(e); if (e.isEmpty()) return FALSE; //printf("parsing `%s'\n",e.data()); return parseCppExpression(g_yyFileName,g_yyLineNr,e);}/*! expands the macro definition in \a name * If needed the function may read additional characters from the input */QCString expandMacro(const QCString &name){ QCString n=name; expandExpression(n,0,0); n=removeMarkers(n); //printf("expandMacro `%s'->`%s'\n",name.data(),n.data()); return n;}Define *newDefine(){ Define *def=new Define; def->name = g_defName; def->definition = g_defText.stripWhiteSpace(); def->nargs = g_defArgs; def->fileName = g_yyFileName; def->lineNr = g_yyLineNr; def->varArgs = g_defVarArgs; //printf("newDefine: `%s'->`%s'\n",def->name.data(),def->definition.data()); if (!def->name.isEmpty() && Doxygen::expandAsDefinedDict[def->name]) { def->isPredefined=TRUE; } return def;}void addDefine(){ //printf("addDefine %s %s\n",g_defName.data(),g_defArgsStr.data()); MemberDef *md=new MemberDef( g_yyFileName,g_yyLineNr, "#define",g_defName,g_defArgsStr,0, Public,Normal,FALSE,FALSE,MemberDef::Define,0,0); if (!g_defArgsStr.isEmpty()) { ArgumentList *argList = new ArgumentList; //printf("addDefine() g_defName=`%s' g_defArgsStr=`%s'\n",g_defName.data(),g_defArgsStr.data()); stringToArgumentList(g_defArgsStr,argList); md->setArgumentList(argList); } //printf("Setting initializer for `%s' to `%s'\n",g_defName.data(),g_defText.data()); int l=g_defLitText.find('\n'); if (l>0 && g_defLitText.left(l).stripWhiteSpace()=="\\") { // strip first line if it only contains a slash g_defLitText = g_defLitText.right(g_defLitText.length()-l-1); } else if (l>0) { // align the items on the first line with the items on the second line int k=l+1; const char *p=g_defLitText.data()+k; char c; while ((c=*p++) && (c==' ' || c=='\t')) k++; g_defLitText=g_defLitText.mid(l+1,k-l-1)+g_defLitText.stripWhiteSpace(); } md->setInitializer(g_defLitText.stripWhiteSpace()); //md->setDefFile(g_yyFileName); //md->setDefLine(g_yyLineNr); md->setFileDef(g_yyFileDef); md->setDefinition("#define "+g_defName); MemberName *mn=Doxygen::functionNameSDict[g_defName]; if (mn==0) { mn = new MemberName(g_defName); //Doxygen::functionNameList.append(mn); //Doxygen::functionNameDict.insert(g_defName,mn); Doxygen::functionNameSDict.append(g_defName,mn); } mn->append(md); if (g_yyFileDef) g_yyFileDef->insertMember(md); //Define *d; //if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine()); }static inline void outputChar(char c){ if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addChar(c);} static inline void outputArray(const char *a,int len){ if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addArray(a,len);}static void readIncludeFile(const QCString &inc){ if (!Config_getBool("SEARCH_INCLUDES")) return; // do not read include files uint i=0; // find the start of the include file name while (i<inc.length() && (inc.at(i)==' ' || inc.at(i)=='"' || inc.at(i)=='<') ) i++; uint s=i; // was it a local include? bool localInclude = s>0 && inc.at(s-1)=='"'; // find the end of the include file name while (i<inc.length() && inc.at(i)!='"' && inc.at(i)!='>') i++; if (s<inc.length() && i>s) // valid include file name found { // extract include path+name QCString incFileName=inc.mid(s,i-s).stripWhiteSpace(); FILE *f; QCString oldFileName = g_yyFileName.copy(); FileDef *oldFileDef = g_yyFileDef; int oldLineNr = g_yyLineNr; //printf("Searching for `%s'\n",incFileName.data()); if ((f=findFile(incFileName,localInclude))) // see if the include file can be found { if (Debug::isFlagSet(Debug::Preprocessor)) { for (i=0;i<g_includeStack.count();i++) msg(" "); msg("#include %s: parsing...\n",incFileName.data()); } if (oldFileDef) { // add include dependency to the file in which the #include was found oldFileDef->addIncludeDependency(g_yyFileDef,incFileName,localInclude); // add included by dependency if (g_yyFileDef) { g_yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->name(),localInclude); } } FileState *fs=new FileState; fs->bufState=YY_CURRENT_BUFFER; fs->lineNr=oldLineNr; fs->fileName=oldFileName; fs->filePtr=f; // push the state on the stack g_includeStack.push(fs); // set the scanner to the include file // TODO: Enable this to deal with file changes due to // #include's within { .. } blocks //QCString lineStr; //lineStr.sprintf("# 1 \"%s\" 1\n",g_yyFileName.data()); //outputArray(lineStr.data(),lineStr.length()); preYYin=f; yy_switch_to_buffer(yy_create_buffer(preYYin, YY_BUF_SIZE)); } else { if (oldFileDef) { bool ambig; FileDef *fd = findFileDef(Doxygen::inputNameDict,incFileName,ambig); // add include dependency to the file in which the #include was found oldFileDef->addIncludeDependency(fd,incFileName,localInclude); // add included by dependency if (fd) { fd->addIncludedByDependency(oldFileDef,oldFileDef->name(),localInclude); } } if (Debug::isFlagSet(Debug::Preprocessor)) { msg("#include %s: not found! skipping...\n",incFileName.data()); //printf("Error: include file %s not found\n",yytext); } } }}/* ----------------------------------------------------------------- */#undef YY_INPUT#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);static int yyread(char *buf,int max_size){ int len = fread( buf, 1, max_size, yyin ); if (len==0 && ferror( yyin )) { yy_fatal_error( "input in flex scanner failed" ); return len; } return filterCRLF(buf,len);}/* ----------------------------------------------------------------- */%}ID [a-z_A-Z][a-z_A-Z0-9]*B [ \t]BN [ \t\r\n]%option noyywrap%x Start%x Command%x SkipCommand%x SkipLine%x CopyLine%x CopyString%x Include%x IncludeID%x DefName%x DefineArg%x DefineText%x SkipCPPBlock%x Ifdef%x Ifndef%x SkipCComment%x SkipCPPComment%x RemoveCComment%x RemoveCPPComment
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -