Orb/Doxygen/src/commentcnv.l
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /*****************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 %{
       
    19 
       
    20 #define YY_NEVER_INTERACTIVE 1
       
    21   
       
    22 #include <stdio.h>
       
    23 #include <stdlib.h>
       
    24 
       
    25 #include <qstack.h>
       
    26 #include <qregexp.h>
       
    27 #include <qtextstream.h>
       
    28 
       
    29 #include "bufstr.h"
       
    30 #include "debug.h"
       
    31 #include "message.h"
       
    32 #include "config.h"
       
    33 #include "doxygen.h"
       
    34 #include "util.h"
       
    35 
       
    36 
       
    37 #define ADDCHAR(c)    g_outBuf->addChar(c)
       
    38 #define ADDARRAY(a,s) g_outBuf->addArray(a,s)
       
    39   
       
    40 struct CondCtx
       
    41 {
       
    42   CondCtx(int line,QCString id,bool b) 
       
    43     : lineNr(line),sectionId(id), skip(b) {}
       
    44   int lineNr;
       
    45   QCString sectionId;
       
    46   bool skip;
       
    47 };
       
    48   
       
    49 static BufStr * g_inBuf;
       
    50 static BufStr * g_outBuf;
       
    51 static int      g_inBufPos;
       
    52 static int      g_col;
       
    53 static int      g_blockHeadCol;
       
    54 static bool     g_mlBrief;
       
    55 static int      g_readLineCtx;
       
    56 static bool     g_skip;
       
    57 static QCString g_fileName;
       
    58 static int      g_lineNr;
       
    59 static int      g_condCtx;
       
    60 static QStack<CondCtx> g_condStack;
       
    61 static QCString g_blockName;
       
    62 static int      g_lastCommentContext;
       
    63 static bool     g_inSpecialComment;
       
    64 static bool     g_inRoseComment;
       
    65 static int      g_javaBlock;
       
    66 static bool     g_specialComment;
       
    67 
       
    68 static QCString g_aliasString;
       
    69 static int      g_blockCount;
       
    70 static int      g_lastBlockContext;
       
    71 static bool     g_pythonDocString;
       
    72 
       
    73 
       
    74 static SrcLangExt g_lang;
       
    75 
       
    76 static void replaceCommentMarker(const char *s,int len)
       
    77 {
       
    78   const char *p=s;
       
    79   char c;
       
    80   // copy blanks
       
    81   while ((c=*p) && (c==' ' || c=='\t' || c=='\n')) 
       
    82   {
       
    83     ADDCHAR(c);
       
    84     g_lineNr += c=='\n';
       
    85     p++;
       
    86   }
       
    87   // replace start of comment marker by spaces
       
    88   while ((c=*p) && (c=='/' || c=='!' || c=='#')) 
       
    89   {
       
    90     ADDCHAR(' ');
       
    91     p++;
       
    92     if (*p=='<') // comment-after-item marker 
       
    93     { 
       
    94       ADDCHAR(' '); 
       
    95       p++; 
       
    96     }
       
    97     if (c=='!') // end after first !
       
    98     {
       
    99       break;
       
   100     }
       
   101   }
       
   102   // copy comment line to output
       
   103   ADDARRAY(p,len-(p-s));
       
   104 }
       
   105 
       
   106 static inline int computeIndent(const char *s)
       
   107 {
       
   108   int col=0;
       
   109   static int tabSize=Config_getInt("TAB_SIZE");
       
   110   const char *p=s;
       
   111   char c;
       
   112   while ((c=*p++))
       
   113   {
       
   114     if (c==' ') col++;
       
   115     else if (c=='\t') col+=tabSize-(col%tabSize); 
       
   116     else break;
       
   117   }
       
   118   return col;
       
   119 }
       
   120 
       
   121 static inline void copyToOutput(const char *s,int len)
       
   122 {
       
   123   int i;
       
   124   if (g_skip) // only add newlines.
       
   125   {
       
   126     for (i=0;i<len;i++) 
       
   127     {
       
   128       if (s[i]=='\n') 
       
   129       {
       
   130 	ADDCHAR('\n');
       
   131 	//fprintf(stderr,"---> skip %d\n",g_lineNr);
       
   132 	g_lineNr++;
       
   133       }
       
   134     }
       
   135   }
       
   136   else
       
   137   {
       
   138     ADDARRAY(s,len);
       
   139     static int tabSize=Config_getInt("TAB_SIZE");
       
   140     for (i=0;i<len;i++) 
       
   141     {
       
   142       switch (s[i])
       
   143       {
       
   144 	case '\n': g_col=0; 
       
   145 	           //fprintf(stderr,"---> copy %d\n",g_lineNr);
       
   146 		   g_lineNr++; break;
       
   147 	case '\t': g_col+=tabSize-(g_col%tabSize); break;
       
   148 	default:   g_col++; break;
       
   149       }
       
   150     }
       
   151   }
       
   152 }
       
   153 
       
   154 static void startCondSection(const char *sectId)
       
   155 {
       
   156   g_condStack.push(new CondCtx(g_lineNr,sectId,g_skip));
       
   157   if (Config_getList("ENABLED_SECTIONS").find(sectId)!=-1)
       
   158   {
       
   159     //printf("*** Section is enabled!\n");
       
   160   }
       
   161   else
       
   162   {
       
   163     //printf("*** Section is disabled!\n");
       
   164     g_skip=TRUE;
       
   165   }
       
   166 }
       
   167 
       
   168 static void endCondSection()
       
   169 {
       
   170   if (g_condStack.isEmpty())
       
   171   {
       
   172     warn(g_fileName,g_lineNr,"Found \\endcond command without matching \\cond");
       
   173     g_skip=FALSE;
       
   174   }
       
   175   else
       
   176   {
       
   177     CondCtx *ctx = g_condStack.pop();
       
   178     g_skip=ctx->skip;
       
   179   }
       
   180 }
       
   181 
       
   182 #if 0
       
   183 /** remove and executes cond and endcond commands in \a s */
       
   184 static QCString handleCondCmdInAliases(const QCString &s)
       
   185 {
       
   186   QCString result;
       
   187   //printf("handleCondCmdInAliases(%s)\n",s.data());
       
   188   static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
       
   189   int p=0,i,l;
       
   190   while ((i=cmdPat.match(s,p,&l))!=-1)
       
   191   {
       
   192     result+=s.mid(p,i-p);
       
   193     QCString cmd = s.mid(i+1,l-1);
       
   194     //printf("Found command %s\n",cmd.data());
       
   195     if (cmd=="cond")
       
   196     {
       
   197       int sp=i+l,ep;
       
   198       const char *arg=s.data()+sp;
       
   199       char c;
       
   200       // skip spaces
       
   201       while ((c=*arg) && (c==' ' || c=='\t')) arg++,sp++;
       
   202       // read argument
       
   203       if (*arg=='\n') // no arg
       
   204       {
       
   205 	startCondSection(" ");
       
   206 	ep=sp;
       
   207       }
       
   208       else // get argument
       
   209       {
       
   210 	ep=sp;
       
   211 	while ((c=*arg) && isId(c)) arg++,ep++;
       
   212 	if (ep>sp)
       
   213 	{
       
   214 	  QCString id = s.mid(sp,ep-sp);
       
   215 	  //printf("Found conditional section id %s\n",id.data());
       
   216 	  startCondSection(id);
       
   217 	}
       
   218 	else // invalid identifier
       
   219 	{
       
   220 	}
       
   221       }
       
   222       p=ep;
       
   223     }
       
   224     else if (cmd=="endcond")
       
   225     {
       
   226       endCondSection();
       
   227       p=i+l;
       
   228     }
       
   229     else
       
   230     {
       
   231       result+=s.mid(i,l);
       
   232       p=i+l;
       
   233     }
       
   234   }
       
   235   result+=s.right(s.length()-p);
       
   236   return result;
       
   237 }
       
   238 #endif
       
   239 
       
   240 /** copies string \a s with length \a len to the output, while 
       
   241  *  replacing any alias commands found in the string.
       
   242  */
       
   243 static void replaceAliases(const char *s)
       
   244 {
       
   245   QCString result = resolveAliasCmd(s);
       
   246   //printf("replaceAliases(%s)->'%s'\n",s,result.data());
       
   247   copyToOutput(result,result.length());
       
   248 }
       
   249 
       
   250 
       
   251 #undef  YY_INPUT
       
   252 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
       
   253 
       
   254 static int yyread(char *buf,int max_size)
       
   255 {
       
   256   int bytesInBuf = g_inBuf->curPos()-g_inBufPos;
       
   257   int bytesToCopy = QMIN(max_size,bytesInBuf);
       
   258   memcpy(buf,g_inBuf->data()+g_inBufPos,bytesToCopy);
       
   259   g_inBufPos+=bytesToCopy;
       
   260   return bytesToCopy;
       
   261 }
       
   262 
       
   263 void replaceComment(int offset);
       
   264 
       
   265 %}
       
   266 
       
   267 %option noyywrap
       
   268 
       
   269 %x Scan
       
   270 %x SkipString
       
   271 %x SkipChar
       
   272 %x SComment
       
   273 %x CComment
       
   274 %x Verbatim
       
   275 %x VerbatimCode
       
   276 %x ReadLine
       
   277 %x CondLine
       
   278 %x ReadAliasArgs
       
   279 
       
   280 %%
       
   281 
       
   282 <Scan>[^"'!\/\n\\#\\-]*           { /* eat anything that is not " / or \n */ 
       
   283                                      copyToOutput(yytext,yyleng); 
       
   284 				   }
       
   285 <Scan>"\"\"\""!                     { /* start of python long comment */
       
   286                                      if (g_lang!=SrcLangExt_Python)
       
   287 				     {
       
   288 				       REJECT;
       
   289 				     }
       
   290 				     else
       
   291 				     {
       
   292                                        g_pythonDocString = TRUE;
       
   293                                        copyToOutput(yytext,yyleng); 
       
   294 				       BEGIN(CComment);
       
   295 				     }
       
   296                                    }
       
   297 <Scan>"!>"			   {
       
   298   			             if (g_lang!=SrcLangExt_F90)
       
   299 				     {
       
   300 				       REJECT;
       
   301 				     }
       
   302 				     else
       
   303 				     {
       
   304                                        copyToOutput(yytext,yyleng); 
       
   305 				       BEGIN(CComment);
       
   306 				     }
       
   307                                    }
       
   308 <Scan>"\""                         { /* start of a string */ 
       
   309                                      copyToOutput(yytext,yyleng); 
       
   310 				     BEGIN(SkipString); 
       
   311                                    }
       
   312 <Scan>'				   {
       
   313                                      copyToOutput(yytext,yyleng); 
       
   314 				     BEGIN(SkipChar);
       
   315   				   }
       
   316 <Scan>\n                           { /* new line */ 
       
   317                                      copyToOutput(yytext,yyleng); 
       
   318                                    }
       
   319 <Scan>("//!"|"///").*/\n[ \t]*"//"[\/!][^\/] { /* start C++ style special comment block */
       
   320   				     if (g_mlBrief) REJECT; // bail out if we do not need to convert
       
   321   				     int i=3;
       
   322 				     if (yytext[2]=='/')
       
   323 				     {
       
   324 				       while (i<yyleng && yytext[i]=='/') i++;
       
   325 				     }
       
   326 				     g_blockHeadCol=g_col;
       
   327                                      copyToOutput("/**",3); 
       
   328 				     replaceAliases(yytext+i);
       
   329 				     g_inSpecialComment=TRUE;
       
   330 				     BEGIN(SComment); 
       
   331                                    }
       
   332 <Scan>"//##Documentation".*/\n	   { /* Start of Rational Rose ANSI C++ comment block */
       
   333                                      if (g_mlBrief) REJECT;
       
   334                                      int i=17; //=strlen("//##Documentation");
       
   335 				     g_blockHeadCol=g_col;
       
   336 				     copyToOutput("/**",3);
       
   337 				     replaceAliases(yytext+i);
       
   338 				     g_inRoseComment=TRUE;
       
   339 				     BEGIN(SComment);
       
   340   				   }
       
   341 <Scan>"//"/.*\n	                   { /* one line C++ comment */ 
       
   342   				     copyToOutput(yytext,yyleng); 
       
   343 				     g_readLineCtx=YY_START;
       
   344 				     BEGIN(ReadLine);
       
   345 				   }
       
   346 <Scan>"/*"[*!]?			   { /* start of a C comment */
       
   347   			             g_specialComment=yyleng==3;
       
   348                                      copyToOutput(yytext,yyleng); 
       
   349 				     BEGIN(CComment); 
       
   350                                    }
       
   351 <Scan>"#"("#")?		           {
       
   352                                      if (g_lang!=SrcLangExt_Python)
       
   353 				     {
       
   354 				       REJECT;
       
   355 				     }
       
   356 				     else
       
   357 				     {
       
   358                                        copyToOutput(yytext,yyleng); 
       
   359 				       BEGIN(CComment);
       
   360 				     }
       
   361   				   }
       
   362 <Scan>"--!"		           {
       
   363                                      if (g_lang!=SrcLangExt_VHDL)
       
   364 				     {
       
   365 				       REJECT;
       
   366 				     }
       
   367 				     else
       
   368 				     {
       
   369                                        copyToOutput(yytext,yyleng); 
       
   370 				       BEGIN(CComment);
       
   371 				     }
       
   372   				   }
       
   373 <CComment>"{@code"/[ \t\n]	   {
       
   374                                      copyToOutput("@code",5); 
       
   375 				     g_lastCommentContext = YY_START;
       
   376 				     g_javaBlock=1;
       
   377 				     g_blockName=&yytext[1];
       
   378                                      BEGIN(VerbatimCode);
       
   379   				   }
       
   380 <CComment,ReadLine>[\\@]("dot"|"code"|"msc")/[^a-z_A-Z0-9] { /* start of a verbatim block */
       
   381                                      copyToOutput(yytext,yyleng); 
       
   382 				     g_lastCommentContext = YY_START;
       
   383 				     g_javaBlock=0;
       
   384 				     g_blockName=&yytext[1];
       
   385                                      BEGIN(VerbatimCode);
       
   386   				   }
       
   387 <CComment,ReadLine>[\\@]("f$"|"f["|"f{"[a-z]*) {
       
   388                                      copyToOutput(yytext,yyleng); 
       
   389 				     g_blockName=&yytext[1];
       
   390 				     if (g_blockName.at(1)=='[')
       
   391 				     {
       
   392 				       g_blockName.at(1)=']';
       
   393 				     }
       
   394 				     else if (g_blockName.at(1)=='{')
       
   395 				     {
       
   396 				       g_blockName.at(1)='}';
       
   397 				     }
       
   398 				     g_lastCommentContext = YY_START;
       
   399 				     BEGIN(Verbatim);
       
   400   			           }
       
   401 <CComment,ReadLine>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] { /* start of a verbatim block */
       
   402                                      copyToOutput(yytext,yyleng); 
       
   403 				     g_blockName=&yytext[1];
       
   404 				     g_lastCommentContext = YY_START;
       
   405                                      BEGIN(Verbatim);
       
   406                                    }
       
   407 <Scan>.                            { /* any other character */
       
   408                                      copyToOutput(yytext,yyleng); 
       
   409                                    }
       
   410 <Verbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}") { /* end of verbatim block */
       
   411                                      copyToOutput(yytext,yyleng);
       
   412 				     if (yytext[1]=='f') // end of formula
       
   413 				     {
       
   414 				       BEGIN(g_lastCommentContext);
       
   415 				     }
       
   416 				     else if (&yytext[4]==g_blockName)
       
   417 				     {
       
   418 				       BEGIN(g_lastCommentContext);
       
   419 				     }
       
   420                                    }
       
   421 <VerbatimCode>"{"		   {
       
   422                                      if (g_javaBlock==0)
       
   423 				     {
       
   424 				       REJECT;
       
   425 				     }
       
   426 				     else
       
   427 				     {
       
   428 				       g_javaBlock++;
       
   429                                        copyToOutput(yytext,yyleng);
       
   430 				     }
       
   431                                    }
       
   432 <VerbatimCode>"}"		   {
       
   433                                      if (g_javaBlock==0)
       
   434 				     {
       
   435 				       REJECT;
       
   436 				     }
       
   437 				     else
       
   438 				     {
       
   439 				       g_javaBlock--;
       
   440 				       if (g_javaBlock==0)
       
   441 				       {
       
   442                                          copyToOutput(" @endcode ",10);
       
   443 				         BEGIN(g_lastCommentContext);
       
   444 				       }
       
   445 				       else
       
   446 				       {
       
   447                                          copyToOutput(yytext,yyleng);
       
   448 				       }
       
   449 				     }
       
   450   				   }
       
   451 <VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc") { /* end of verbatim block */
       
   452                                      copyToOutput(yytext,yyleng);
       
   453 				     if (&yytext[4]==g_blockName)
       
   454 				     {
       
   455 				       BEGIN(g_lastCommentContext);
       
   456 				     }
       
   457                                    }
       
   458 <VerbatimCode>^[ \t]*"//"[\!\/]?   { /* skip leading comments */
       
   459   				     if (!g_inSpecialComment)
       
   460 				     {
       
   461                                        copyToOutput(yytext,yyleng); 
       
   462 				     }
       
   463   				   }
       
   464 <Verbatim,VerbatimCode>[^@\/\\\n{}]* { /* any character not a backslash or new line or } */
       
   465                                      copyToOutput(yytext,yyleng); 
       
   466                                    }
       
   467 <Verbatim,VerbatimCode>\n	   { /* new line in verbatim block */
       
   468                                      copyToOutput(yytext,yyleng); 
       
   469                                    }
       
   470 <Verbatim,VerbatimCode>.	   { /* any other character */
       
   471                                      copyToOutput(yytext,yyleng); 
       
   472                                    }
       
   473 <SkipString>\\.                    { /* escaped character in string */
       
   474                                      copyToOutput(yytext,yyleng); 
       
   475                                    }
       
   476 <SkipString>"\""       	           { /* end of string */ 
       
   477                                      copyToOutput(yytext,yyleng); 
       
   478 				     BEGIN(Scan); 
       
   479                                    }
       
   480 <SkipString>.                      { /* any other string character */ 
       
   481                                      copyToOutput(yytext,yyleng); 
       
   482                                    }
       
   483 <SkipString>\n                     { /* new line inside string (illegal for some compilers) */ 
       
   484                                      copyToOutput(yytext,yyleng); 
       
   485                                    }
       
   486 <SkipChar>\\.		           { /* escaped character */
       
   487                                      copyToOutput(yytext,yyleng); 
       
   488                                    }
       
   489 <SkipChar>'                        { /* end of character literal */ 
       
   490                                      copyToOutput(yytext,yyleng); 
       
   491                                      BEGIN(Scan);
       
   492                                    }
       
   493 <SkipChar>.                        { /* any other string character */ 
       
   494                                      copyToOutput(yytext,yyleng); 
       
   495                                    }
       
   496 <SkipChar>\n                       { /* new line character */
       
   497                                      copyToOutput(yytext,yyleng); 
       
   498                                    }
       
   499 
       
   500 <CComment>[^\\!@*\n{]*	           { /* anything that is not a '*' or command */ 
       
   501                                      copyToOutput(yytext,yyleng); 
       
   502                                    }
       
   503 <CComment>"*"+[^*/\\@\n]*          { /* stars without slashes */
       
   504                                      copyToOutput(yytext,yyleng); 
       
   505                                    }
       
   506 <CComment>"\"\"\""                 { /* end of Python docstring */
       
   507                                      if (g_lang!=SrcLangExt_Python)
       
   508 				     {
       
   509 				       REJECT;
       
   510 				     }
       
   511 				     else
       
   512 				     {
       
   513                                        g_pythonDocString = FALSE;
       
   514 				       copyToOutput(yytext,yyleng);
       
   515 				       BEGIN(Scan);
       
   516 				     }
       
   517   				   }
       
   518 <CComment>\n                       { /* new line in comment */
       
   519                                      copyToOutput(yytext,yyleng); 
       
   520                                    }
       
   521 <CComment>"*"+"/"                  { /* end of C comment */
       
   522                                      if (g_lang==SrcLangExt_Python)
       
   523 				     {
       
   524 				       REJECT;
       
   525 				     }
       
   526 				     else
       
   527 				     {
       
   528 				       copyToOutput(yytext,yyleng);
       
   529 				       BEGIN(Scan);
       
   530 				     }
       
   531                                    }
       
   532 <CComment>"\n"/[ \t]*[^#]	   { /* end of Python comment */
       
   533                                      if (g_lang!=SrcLangExt_Python || g_pythonDocString)
       
   534 				     {
       
   535 				       REJECT;
       
   536 				     }
       
   537 				     else
       
   538 				     {
       
   539 				       copyToOutput(yytext,yyleng);
       
   540 				       BEGIN(Scan);
       
   541 				     }
       
   542   				   }
       
   543 <CComment>"\n"/[ \t]*[^\-]	   { /* end of VHDL comment */
       
   544                                      if (g_lang!=SrcLangExt_VHDL)
       
   545 				     {
       
   546 				       REJECT;
       
   547 				     }
       
   548 				     else
       
   549 				     {
       
   550 				       copyToOutput(yytext,yyleng);
       
   551 				       BEGIN(Scan);
       
   552 				     }
       
   553   				   }
       
   554 <CComment>"\n"/[ \t]*[^!]	   { /* end of Fortran comment */
       
   555   				     if (g_lang!=SrcLangExt_F90)
       
   556 				     {
       
   557 				       REJECT;
       
   558 				     }
       
   559 				     else
       
   560 				     {
       
   561 				       copyToOutput(yytext,yyleng);
       
   562 				       BEGIN(Scan);
       
   563 				     }
       
   564   				   }
       
   565 <CComment>.			   {
       
   566                                      copyToOutput(yytext,yyleng); 
       
   567   				   }
       
   568 <SComment>^[ \t]*"///"[\/]*/\n     {
       
   569   				     replaceComment(0);
       
   570   				   }
       
   571 <SComment>\n[ \t]*"///"[\/]*/\n    {
       
   572                                      replaceComment(1); 
       
   573                                    }
       
   574 <SComment>^[ \t]*"///"[^\/\n]/.*\n { 
       
   575   				     replaceComment(0);
       
   576 				     g_readLineCtx=YY_START;
       
   577 				     BEGIN(ReadLine);
       
   578   				   }
       
   579 <SComment>\n[ \t]*"///"[^\/\n]/.*\n  { 
       
   580                                      replaceComment(1); 
       
   581 				     g_readLineCtx=YY_START;
       
   582 				     BEGIN(ReadLine);
       
   583   				   }
       
   584 <SComment>^[ \t]*"//!"             |    // just //!
       
   585 <SComment>^[ \t]*"//!<"/.*\n       |    // or   //!< something
       
   586 <SComment>^[ \t]*"//!"[^<]/.*\n    {    // or   //!something
       
   587   				     replaceComment(0);
       
   588 				     g_readLineCtx=YY_START;
       
   589 				     BEGIN(ReadLine);
       
   590                                    }
       
   591 <SComment>\n[ \t]*"//!"            |
       
   592 <SComment>\n[ \t]*"//!<"/.*\n      |
       
   593 <SComment>\n[ \t]*"//!"[^<\n]/.*\n   { 
       
   594                                      replaceComment(1); 
       
   595 				     g_readLineCtx=YY_START;
       
   596 				     BEGIN(ReadLine);
       
   597                                    }
       
   598 <SComment>^[ \t]*"//##"/.*\n       {
       
   599                                      if (!g_inRoseComment)
       
   600 				     {
       
   601 				       REJECT;
       
   602 				     }
       
   603 				     else
       
   604 				     {
       
   605   				       replaceComment(0);
       
   606 				       g_readLineCtx=YY_START;
       
   607 				       BEGIN(ReadLine);
       
   608 				     }
       
   609                                    }
       
   610 <SComment>\n[ \t]*"//##"/.*\n      {
       
   611                                      if (!g_inRoseComment)
       
   612 				     {
       
   613 				       REJECT;
       
   614 				     }
       
   615 				     else
       
   616 				     {
       
   617                                        replaceComment(1); 
       
   618 				       g_readLineCtx=YY_START;
       
   619 				       BEGIN(ReadLine);
       
   620 				     }
       
   621                                    }
       
   622 <SComment>\n			   { /* end of special comment */
       
   623                                      copyToOutput(" */",3); 
       
   624 				     copyToOutput(yytext,yyleng); 
       
   625 				     g_inSpecialComment=FALSE;
       
   626 				     g_inRoseComment=FALSE;
       
   627 				     BEGIN(Scan); 
       
   628                                    }
       
   629 <ReadLine>[^\\@\n]*/\n		   {
       
   630   				     copyToOutput(yytext,yyleng);
       
   631                                      BEGIN(g_readLineCtx);
       
   632   				   }
       
   633 <CComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command
       
   634 				     copyToOutput(yytext,yyleng);
       
   635   				   }
       
   636 <CComment,ReadLine>[\\@]"cond"[ \t]+	   { // conditional section
       
   637   				     g_condCtx = YY_START; 
       
   638   				     BEGIN(CondLine);
       
   639   				   }
       
   640 <CComment,ReadLine>[\\@]"endcond"/[^a-z_A-Z0-9] { // end of conditional section
       
   641   				     bool oldSkip=g_skip;
       
   642   				     endCondSection();
       
   643 				     if (YY_START==CComment && oldSkip && !g_skip) 
       
   644     			             {
       
   645 				       //printf("** Adding start of comment!\n");
       
   646 				       if (g_lang!=SrcLangExt_Python &&
       
   647 					   g_lang!=SrcLangExt_VHDL)
       
   648 				       {
       
   649  				         ADDCHAR('/');
       
   650      				         ADDCHAR('*');
       
   651 					 if (g_specialComment)
       
   652 					 {
       
   653 					   ADDCHAR('*');
       
   654 					 }
       
   655 				       }
       
   656     				     }
       
   657 				    }
       
   658 <CondLine>[a-z_A-Z][a-z_A-Z0-9.\-]* {
       
   659   				     bool oldSkip=g_skip;
       
   660                                      startCondSection(yytext);
       
   661 				     if (g_condCtx==CComment && !oldSkip && g_skip) 
       
   662     			             {
       
   663 				       //printf("** Adding terminator for comment!\n");
       
   664 				       if (g_lang!=SrcLangExt_Python &&
       
   665 					   g_lang!=SrcLangExt_VHDL)
       
   666 				       {
       
   667  				         ADDCHAR('*');
       
   668      				         ADDCHAR('/');
       
   669 				       }
       
   670     				     }
       
   671   				     BEGIN(g_condCtx);
       
   672   				   }
       
   673 <CondLine>[ \t]*
       
   674 <CComment,ReadLine>[\\@]"cond"[ \t\r]*/\n |
       
   675 <CondLine>.			   { // forgot section id?
       
   676   				     if (YY_START!=CondLine) g_condCtx=YY_START;
       
   677   				     bool oldSkip=g_skip;
       
   678   				     startCondSection(" "); // fake section id causing the section to be hidden unconditionally
       
   679 				     if (g_condCtx==CComment && !oldSkip && g_skip) 
       
   680     			             {
       
   681 				       //printf("** Adding terminator for comment!\n");
       
   682 				       if (g_lang!=SrcLangExt_Python &&
       
   683 					   g_lang!=SrcLangExt_VHDL)
       
   684 				       {
       
   685  				         ADDCHAR('*');
       
   686      				         ADDCHAR('/');
       
   687 				       }
       
   688     				     }
       
   689 				     if (*yytext=='\n') g_lineNr++;
       
   690 				     BEGIN(g_condCtx);
       
   691   				   }
       
   692 <CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]*  { // expand alias without arguments
       
   693 				     replaceAliases(yytext);
       
   694   				   }
       
   695 <CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]*"{" { // expand alias with arguments
       
   696                                      g_lastBlockContext=YY_START;
       
   697 				     g_blockCount=1;
       
   698 				     g_aliasString=yytext;
       
   699 				     BEGIN( ReadAliasArgs );
       
   700   				   }
       
   701 <ReadAliasArgs>[^{}\n\*]+	   {
       
   702                                      g_aliasString+=yytext;
       
   703   				   }
       
   704 <ReadAliasArgs>\n		   {
       
   705                                      g_aliasString+=yytext;
       
   706                                      g_lineNr++;
       
   707   				   }
       
   708 <ReadAliasArgs>"{"		   {
       
   709                                      g_aliasString+=yytext;
       
   710                                      g_blockCount++;
       
   711                                    }
       
   712 <ReadAliasArgs>"}"		   {
       
   713                                      g_aliasString+=yytext;
       
   714                                      g_blockCount--;
       
   715 				     if (g_blockCount==0)
       
   716 				     {
       
   717 				       replaceAliases(g_aliasString);
       
   718 				       BEGIN( g_lastBlockContext );
       
   719 				     }
       
   720   			           }
       
   721 <ReadAliasArgs>.		   {
       
   722                                      g_aliasString+=yytext;
       
   723   				   }
       
   724 <ReadLine>.			   {
       
   725   				     copyToOutput(yytext,yyleng);
       
   726   				   }
       
   727 
       
   728 %%
       
   729 
       
   730 void replaceComment(int offset)                                
       
   731 {
       
   732   if (g_mlBrief)                                              
       
   733   {                                                           
       
   734     copyToOutput(yytext,yyleng); 
       
   735   }                                                           
       
   736   else                                                        
       
   737   {                                                           
       
   738     //printf("replaceComment(%s)\n",yytext);
       
   739     int i=computeIndent(&yytext[offset]);                     
       
   740     if (i==g_blockHeadCol)                                    
       
   741     {                                                         
       
   742       replaceCommentMarker(yytext,yyleng);                    
       
   743     }                                                         
       
   744     else                                                      
       
   745     {                                                         
       
   746       copyToOutput(" */",3);                                  
       
   747       int i;for (i=yyleng-1;i>=0;i--) unput(yytext[i]);       
       
   748       BEGIN(Scan);                                            
       
   749     }                                                         
       
   750   }
       
   751 }
       
   752 
       
   753 /*! This function does three things:
       
   754  *  -# It converts multi-line C++ style comment blocks (that are aligned)
       
   755  *     to C style comment blocks (if MULTILINE_CPP_IS_BRIEF is set to NO).
       
   756  *  -# It replaces aliases with their definition (see ALIASES)
       
   757  *  -# It handles conditional sections (cond...endcond blocks)
       
   758  */
       
   759 void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
       
   760 {
       
   761   //printf("convertCppComments(%s)\n",fileName);
       
   762   g_inBuf    = inBuf;
       
   763   g_outBuf   = outBuf;
       
   764   g_inBufPos = 0;
       
   765   g_col      = 0;
       
   766   g_mlBrief = Config_getBool("MULTILINE_CPP_IS_BRIEF");
       
   767   g_skip     = FALSE;
       
   768   g_fileName = fileName;
       
   769   g_lang = getLanguageFromFileName(fileName);
       
   770   g_pythonDocString = FALSE;
       
   771   g_lineNr   = 1;
       
   772   g_condStack.clear();
       
   773   g_condStack.setAutoDelete(TRUE);
       
   774   BEGIN(Scan);
       
   775   yylex();
       
   776   while (!g_condStack.isEmpty())
       
   777   {
       
   778     CondCtx *ctx = g_condStack.pop();
       
   779     QCString sectionInfo = " ";
       
   780     if (ctx->sectionId!=" ") sectionInfo.sprintf(" with label %s ",ctx->sectionId.data()); 
       
   781     warn(g_fileName,ctx->lineNr,"Conditional section%sdoes not have "
       
   782 	"a corresponding \\endcond command within this file.",sectionInfo.data());
       
   783   }
       
   784   if (Debug::isFlagSet(Debug::CommentCnv))
       
   785   {
       
   786     g_outBuf->at(g_outBuf->curPos())='\0';
       
   787     msg("-------------\n%s\n-------------\n",g_outBuf->data());
       
   788   }
       
   789 }
       
   790 
       
   791 
       
   792 //----------------------------------------------------------------------------
       
   793 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
       
   794 extern "C" { // some bogus code to keep the compiler happy
       
   795     void commentcnvYYdummy() { yy_flex_realloc(0,0); } 
       
   796 }
       
   797 #endif
       
   798