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