Imported Upstream version 1.9.5
[platform/upstream/doxygen.git] / src / commentcnv.l
1 /*****************************************************************************
2  *
3  * 
4  *
5  * Copyright (C) 1997-2015 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 %option never-interactive
18 %option prefix="commentcnvYY"
19 %option reentrant
20 %option extra-type="struct commentcnvYY_state *"
21 %top{
22 #include <stdint.h>
23 // forward declare yyscan_t to improve type safety
24 #define YY_TYPEDEF_YY_SCANNER_T
25 struct yyguts_t;
26 typedef yyguts_t *yyscan_t;
27 }
28
29 %{
30
31   
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stack>
35 #include <algorithm>
36
37 #include "bufstr.h"
38 #include "debug.h"
39 #include "message.h"
40 #include "config.h"
41 #include "doxygen.h"
42 #include "util.h"
43 #include "condparser.h"
44
45 #include <assert.h>
46
47 #define YY_NO_INPUT 1
48 #define YY_NO_UNISTD_H 1
49
50 #define ADDCHAR(c)    yyextra->outBuf->addChar(c)
51 #define ADDARRAY(a,s) yyextra->outBuf->addArray(a,s)
52
53 #define USE_STATE2STRING 0
54   
55 struct commentcnvYY_CondCtx
56 {
57   commentcnvYY_CondCtx(int line,QCString id,bool b) 
58     : lineNr(line),sectionId(id), skip(b) {}
59   int lineNr;
60   QCString sectionId;
61   bool skip;
62 };
63   
64 struct CommentCtx
65 {
66   CommentCtx(int line) 
67     : lineNr(line) {}
68   int lineNr;
69 };
70   
71 struct commentcnvYY_state
72 {
73   BufStr * inBuf = 0;
74   BufStr * outBuf = 0;
75   yy_size_t inBufPos = 0;
76   int      col = 0;
77   int      blockHeadCol = 0;
78   bool     mlBrief = FALSE;
79   int      readLineCtx = 0;
80   bool     skip = FALSE;
81   QCString fileName;
82   int      lineNr = 0;
83   int      condCtx = 0;
84   std::stack<commentcnvYY_CondCtx> condStack;
85   std::stack<int> commentStack;
86   QCString blockName;
87   int      lastCommentContext = 0;
88   bool     inSpecialComment = FALSE;
89   bool     inRoseComment= FALSE;
90   int      stringContext = 0;
91   int      charContext = 0;
92   int      javaBlock = 0;
93   bool     specialComment = FALSE;
94
95   QCString aliasString;
96   int      blockCount = 0;
97   bool     lastEscaped = FALSE;
98   int      lastBlockContext= 0;
99   bool     pythonDocString = FALSE;
100   int      nestingCount= 0;
101
102   bool     vhdl = FALSE; // for VHDL old style --! comment
103
104   SrcLangExt lang = SrcLangExt_Unknown;
105   bool       isFixedForm = FALSE; // For Fortran
106 };
107
108 #if USE_STATE2STRING
109 static const char *stateToString(int state);
110 #endif
111 static inline int computeIndent(const char *s);
112
113 static void replaceCommentMarker(yyscan_t yyscanner,const char *s,int len);
114 static inline void copyToOutput(yyscan_t yyscanner,const char *s,int len);
115 static void startCondSection(yyscan_t yyscanner,const QCString &sectId);
116 static void endCondSection(yyscan_t yyscanner);
117 static void handleCondSectionId(yyscan_t yyscanner,const char *expression);
118 static void replaceAliases(yyscan_t yyscanner,const QCString &s);
119 static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
120 static void replaceComment(yyscan_t yyscanner,int offset);
121 static void clearCommentStack(yyscan_t yyscanner);
122
123
124
125
126 #undef  YY_INPUT
127 #define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
128
129 // otherwise the filename would be the name of the converted file (*.cpp instead of *.l)
130 static inline const char *getLexerFILE() {return __FILE__;}
131 #include "doxygen_lex.h"
132
133 %}
134
135 MAILADDR   ("mailto:")?[a-z_A-Z0-9\x80-\xff.+-]+"@"[a-z_A-Z0-9\x80-\xff-]+("."[a-z_A-Z0-9\x80-\xff\-]+)+[a-z_A-Z0-9\x80-\xff\-]+
136
137 %option noyywrap
138
139 %x Scan
140 %x SkipString
141 %x SkipChar
142 %x SComment
143 %x CComment
144 %x CNComment
145 %x Verbatim
146 %x VerbatimCode
147 %x ReadLine
148 %x CondLine
149 %x ReadAliasArgs
150
151   //- start: NUMBER -------------------------------------------------------------------------
152   // Note same defines in code.l: keep in sync
153 DECIMAL_INTEGER  [1-9][0-9']*[0-9]?[uU]?[lL]?[lL]?
154 HEXADECIMAL_INTEGER  "0"[xX][0-9a-zA-Z']+[0-9a-zA-Z]?
155 OCTAL_INTEGER  "0"[0-7][0-7']+[0-7]?
156 BINARY_INTEGER  "0"[bB][01][01']*[01]?
157 INTEGER_NUMBER {DECIMAL_INTEGER}|{HEXADECIMAL_INTEGER}|{OCTAL_INTEGER}|{BINARY_INTEGER}
158
159 FP_SUF [fFlL]
160
161 DIGIT_SEQ [0-9][0-9']*[0-9]?
162 FRAC_CONST {DIGIT_SEQ}"."|{DIGIT_SEQ}?"."{DIGIT_SEQ}
163 FP_EXP [eE][+-]?{DIGIT_SEQ}
164 DEC_FP1 {FRAC_CONST}{FP_EXP}?{FP_SUF}?
165 DEC_FP2 {DIGIT_SEQ}{FP_EXP}{FP_SUF}
166
167 HEX_DIGIT_SEQ [0-9a-fA-F][0-9a-fA-F']*[0-9a-fA-F]?
168 HEX_FRAC_CONST {HEX_DIGIT_SEQ}"."|{HEX_DIGIT_SEQ}?"."{HEX_DIGIT_SEQ}
169 BIN_EXP [pP][+-]?{DIGIT_SEQ}
170 HEX_FP1 "0"[xX]{HEX_FRAC_CONST}{BIN_EXP}{FP_SUF}?
171 HEX_FP2 "0"[xX]{HEX_DIGIT_SEQ}{BIN_EXP}{FP_SUF}?
172
173 FLOAT_DECIMAL {DEC_FP1}|{DEC_FP2}
174 FLOAT_HEXADECIMAL {HEX_FP1}|{HEX_FP2}
175 FLOAT_NUMBER {FLOAT_DECIMAL}|{FLOAT_HEXADECIMAL}
176 NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
177   //- end: NUMBER ---------------------------------------------------------------------------
178
179   // C start comment 
180 CCS   "/\*"
181   // C end comment
182 CCE   "*\/"
183   // Cpp comment 
184 CPPC  "/\/"
185
186   // Optional any character
187 ANYopt .*
188
189   // Optional white space
190 WSopt [ \t\r]*
191   // readline non special
192 RLopt [^\\@\n\*\/]*
193   // Optional slash
194 SLASHopt [/]*
195
196 %%
197
198 <Scan>{NUMBER}                      { //Note similar code in code.l
199                                       if (yyextra->lang!=SrcLangExt_Cpp) REJECT;
200                                       copyToOutput(yyscanner,yytext,(int)yyleng); 
201                                     }
202 <Scan>[^"'!\/\n\\#,\-=; \t]*        { /* eat anything that is not " / , or \n */
203                                        copyToOutput(yyscanner,yytext,(int)yyleng);
204                                     }
205 <Scan>[,= ;\t]                      { /* eat , so we have a nice separator in long initialization lines */ 
206                                        copyToOutput(yyscanner,yytext,(int)yyleng);
207                                     }
208 <Scan>"\"\"\""!                     { /* start of python long comment */
209                                      if (yyextra->lang!=SrcLangExt_Python)
210                                      {
211                                        REJECT;
212                                      }
213                                      else
214                                      {
215                                        yyextra->pythonDocString = TRUE;
216                                        yyextra->nestingCount=1;
217                                        clearCommentStack(yyscanner); /*  to be on the save side */
218                                        copyToOutput(yyscanner,yytext,(int)yyleng);
219                                        BEGIN(CComment);
220                                        yyextra->commentStack.push(yyextra->lineNr);
221                                      }
222                                    }
223 <Scan>![><!]/.*\n          {
224                                      if (yyextra->lang!=SrcLangExt_Fortran)
225                                      {
226                                        REJECT;
227                                      }
228                                      else
229                                      {
230                                        copyToOutput(yyscanner,yytext,(int)yyleng); 
231                                        yyextra->nestingCount=0; // Fortran doesn't have an end comment
232                                        clearCommentStack(yyscanner); /*  to be on the save side */
233                                        BEGIN(CComment);
234                                        yyextra->commentStack.push(yyextra->lineNr);
235                                      }
236                                    }
237 <Scan>[Cc\*][><!]/.*\n     {
238                                      if (yyextra->lang!=SrcLangExt_Fortran)
239                                      {
240                                        REJECT;
241                                      }
242                                      else
243                                      {
244                                        /* check for fixed format; we might have some conditional as part of multiline if like C<5 .and. & */
245                                        if (yyextra->isFixedForm && (yyextra->col == 0))
246                                        {
247                                          copyToOutput(yyscanner,yytext,(int)yyleng); 
248                                          yyextra->nestingCount=0; // Fortran doesn't have an end comment
249                                          clearCommentStack(yyscanner); /*  to be on the save side */
250                                          BEGIN(CComment);
251                                          yyextra->commentStack.push(yyextra->lineNr);
252                                        }
253                                        else
254                                        {
255                                          REJECT;
256                                        }
257                                      }
258                                    }
259 <Scan>!.*\n                {
260                                      if (yyextra->lang!=SrcLangExt_Fortran)
261                                      {
262                                        REJECT;
263                                      }
264                                      else
265                                      {
266                                        copyToOutput(yyscanner,yytext,(int)yyleng); 
267                                      }
268                                    }
269 <Scan>[Cc\*].*\n                   {
270                                      if (yyextra->lang!=SrcLangExt_Fortran)
271                                      {
272                                        REJECT;
273                                      }
274                                      else
275                                      {
276                                        if (yyextra->col == 0)
277                                        {
278                                          copyToOutput(yyscanner,yytext,(int)yyleng); 
279                                        }
280                                        else
281                                        {
282                                          REJECT;
283                                        }
284                                      }
285                                    }
286 <Scan>"\""                         { /* start of a string */ 
287                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
288                                      yyextra->stringContext = YY_START;
289                                      BEGIN(SkipString); 
290                                    }
291 <Scan>'                            {
292                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
293                                      yyextra->charContext = YY_START;
294                                      if (yyextra->lang!=SrcLangExt_VHDL)
295                                      {
296                                        BEGIN(SkipChar);
297                                      }
298                                    }
299 <Scan>\n                           { /* new line */ 
300                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
301                                    }
302 <Scan>{CPPC}"!"/.*\n[ \t]*{CPPC}[\/!][^\/] | /* start C++ style special comment block */
303 <Scan>({CPPC}"/"[/]*)/[^/].*\n[ \t]*{CPPC}[\/!][^\/] { /* start C++ style special comment block */
304                                      if (yyextra->mlBrief) 
305                                      {
306                                        REJECT; // bail out if we do not need to convert
307                                      }
308                                      else
309                                      {
310                                        int i=3;
311                                        if (yytext[2]=='/')
312                                        {
313                                          while (i<(int)yyleng && yytext[i]=='/') i++;
314                                        }
315                                        yyextra->blockHeadCol=yyextra->col;
316                                        copyToOutput(yyscanner,"/**",3); 
317                                        replaceAliases(yyscanner,QCString(yytext+i));
318                                        yyextra->inSpecialComment=TRUE;
319                                        //BEGIN(SComment); 
320                                        yyextra->readLineCtx=SComment;
321                                        BEGIN(ReadLine);
322                                      }
323                                    }
324 <Scan>{CPPC}"##Documentation"{ANYopt}/\n           { /* Start of Rational Rose ANSI C++ comment block */
325                                      if (yyextra->mlBrief) REJECT;
326                                      int i=17; //=strlen("//##Documentation");
327                                      yyextra->blockHeadCol=yyextra->col;
328                                      copyToOutput(yyscanner,"/**",3);
329                                      replaceAliases(yyscanner,QCString(yytext+i));
330                                      yyextra->inRoseComment=TRUE;
331                                      BEGIN(SComment);
332                                    }
333 <Scan>{CPPC}[!\/]/.*\n[ \t]*{CPPC}[|\/][ \t]*[@\\]"}" { // next line contains an end marker, see bug 752712
334                                      yyextra->inSpecialComment=yytext[2]=='/' || yytext[2]=='!';
335                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
336                                      yyextra->readLineCtx=YY_START;
337                                      BEGIN(ReadLine);
338                                    }
339 <Scan>{CPPC}/.*\n                          { /* one line C++ comment */ 
340                                      yyextra->inSpecialComment=yytext[2]=='/' || yytext[2]=='!';
341                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
342                                      yyextra->readLineCtx=YY_START;
343                                      BEGIN(ReadLine);
344                                    }
345 <Scan>{CCS}{CCE}                       { /* avoid matching next rule for empty C comment, see bug 711723 */
346                                      copyToOutput(yyscanner,yytext,(int)yyleng);
347                                    }
348 <Scan>{CCS}[*!]?                           { /* start of a C comment */
349                                      if (yyextra->lang==SrcLangExt_Python)
350                                      {
351                                        REJECT;
352                                      }
353                                      yyextra->specialComment=(int)yyleng==3;
354                                      yyextra->nestingCount=1;
355                                      clearCommentStack(yyscanner); /*  to be on the save side */
356                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
357                                      if (yyextra->specialComment)
358                                        BEGIN(CComment); 
359                                      else
360                                        BEGIN(CNComment); 
361                                      yyextra->commentStack.push(yyextra->lineNr);
362                                    }
363 <Scan>"#"("#")?                    {
364                                      if (yyextra->lang!=SrcLangExt_Python)
365                                      {
366                                        REJECT;
367                                      }
368                                      else
369                                      {
370                                        copyToOutput(yyscanner,yytext,(int)yyleng); 
371                                        yyextra->nestingCount=0; // Python doesn't have an end comment for #
372                                        clearCommentStack(yyscanner); /*  to be on the save side */
373                                        BEGIN(CComment);
374                                        yyextra->commentStack.push(yyextra->lineNr);
375                                      }
376                                    }
377 <Scan>"--"[^!][^\n]*               {
378                                      if (yyextra->lang!=SrcLangExt_VHDL)
379                                      {
380                                        REJECT;
381                                      }
382                                      else
383                                      {
384                                        copyToOutput(yyscanner,yytext,(int)yyleng); 
385                                      }
386                                    }
387 <Scan>"--!"                        {
388                                      if (yyextra->lang!=SrcLangExt_VHDL)
389                                      {
390                                        REJECT;
391                                      }
392                                      else
393                                      {
394                                        yyextra->vhdl = TRUE;
395                                        copyToOutput(yyscanner,yytext,(int)yyleng); 
396                                        yyextra->nestingCount=0;  // VHDL doesn't have an end comment
397                                        clearCommentStack(yyscanner); /*  to be on the save side */
398                                        BEGIN(CComment);
399                                        yyextra->commentStack.push(yyextra->lineNr);
400                                      }
401                                    }
402 <Scan>![><!]                       {
403                                      if (yyextra->lang!=SrcLangExt_Fortran)
404                                      {
405                                        REJECT;
406                                      }
407                                      else
408                                      {
409                                        copyToOutput(yyscanner,yytext,(int)yyleng); 
410                                        yyextra->nestingCount=0;  // Fortran doesn't have an end comment
411                                        clearCommentStack(yyscanner); /*  to be on the save side */
412                                        BEGIN(CComment);
413                                        yyextra->commentStack.push(yyextra->lineNr);
414                                      }
415                                    }
416 <CComment,CNComment,ReadLine>{MAILADDR}       |
417 <CComment,CNComment,ReadLine>"<"{MAILADDR}">" { // Mail address, to prevent seeing e.g x@code-factory.org as start of a code block
418                                      copyToOutput(yyscanner,yytext,(int)yyleng);
419                                    }
420 <CComment>"{"[ \t]*"@code"/[ \t\n] {
421                                      copyToOutput(yyscanner,"@iliteral{code}",15); 
422                                      yyextra->lastCommentContext = YY_START;
423                                      yyextra->javaBlock=1;
424                                      yyextra->blockName=&yytext[1];
425                                      BEGIN(VerbatimCode);
426                                    }
427 <CComment>"{"[ \t]*"@literal"/[ \t\n] {
428                                      copyToOutput(yyscanner,"@iliteral",9); 
429                                      yyextra->lastCommentContext = YY_START;
430                                      yyextra->javaBlock=1;
431                                      yyextra->blockName=&yytext[1];
432                                      BEGIN(VerbatimCode);
433                                    }
434 <CComment,ReadLine>^[ \t]*("```"[`]*|"~~~"[~]*) { /* start of markdown code block */
435                                      if (!Config_getBool(MARKDOWN_SUPPORT))
436                                      {
437                                        REJECT;
438                                      }
439                                      copyToOutput(yyscanner,yytext,(int)yyleng);
440                                      yyextra->lastCommentContext = YY_START;
441                                      yyextra->javaBlock=0;
442                                      yyextra->blockName=QCString(yytext).stripWhiteSpace().left(3); // take the ``` or ~~~ part
443                                      BEGIN(VerbatimCode);
444                                    }
445 <CComment,ReadLine>[\\@]("dot"|"code"|"msc"|"startuml")/[^a-z_A-Z0-9] { /* start of a verbatim block */
446                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
447                                      yyextra->lastCommentContext = YY_START;
448                                      yyextra->javaBlock=0;
449                                      if (qstrcmp(&yytext[1],"startuml")==0)
450                                      {
451                                        yyextra->blockName="uml";
452                                      }
453                                      else
454                                      {
455                                        yyextra->blockName=&yytext[1];
456                                      }
457                                      BEGIN(VerbatimCode);
458                                    }
459 <CComment,ReadLine>[\\@]("f$"|"f["|"f{"|"f(") {
460                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
461                                      yyextra->blockName=&yytext[1];
462                                      if (yyextra->blockName.at(1)=='[')
463                                      {
464                                        yyextra->blockName.at(1)=']';
465                                      }
466                                      else if (yyextra->blockName.at(1)=='{')
467                                      {
468                                        yyextra->blockName.at(1)='}';
469                                      }
470                                      else if (yyextra->blockName.at(1)=='(')
471                                      {
472                                        yyextra->blockName.at(1)=')';
473                                      }
474                                      yyextra->lastCommentContext = YY_START;
475                                      BEGIN(Verbatim);
476                                    }
477 <CComment,ReadLine>[\\@]("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] { /* start of a verbatim block */
478                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
479                                      yyextra->blockName=&yytext[1];
480                                      yyextra->lastCommentContext = YY_START;
481                                      BEGIN(Verbatim);
482                                    }
483 <Scan>"\\\""                       { /* escaped double quote */
484                                      copyToOutput(yyscanner,yytext,(int)yyleng);
485                                    }
486 <Scan>"\\\\"                       { /* escaped backslash */
487                                      copyToOutput(yyscanner,yytext,(int)yyleng);
488                                    }
489 <Scan>.                            { /* any other character */
490                                      copyToOutput(yyscanner,yytext,(int)yyleng);
491                                    }
492 <Verbatim>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") { /* end of verbatim block */
493                                      copyToOutput(yyscanner,yytext,(int)yyleng);
494                                      if (&yytext[1]==yyextra->blockName) // end of formula
495                                      {
496                                        BEGIN(yyextra->lastCommentContext);
497                                      }
498                                      else if (&yytext[4]==yyextra->blockName)
499                                      {
500                                        BEGIN(yyextra->lastCommentContext);
501                                      }
502                                    }
503 <VerbatimCode>"{"                  {
504                                      if (yyextra->javaBlock==0)
505                                      {
506                                        REJECT;
507                                      }
508                                      else
509                                      {
510                                        yyextra->javaBlock++;
511                                        copyToOutput(yyscanner,yytext,(int)yyleng);
512                                      }
513                                    }
514 <VerbatimCode>"}"                  {
515                                      if (yyextra->javaBlock==0)
516                                      {
517                                        REJECT;
518                                      }
519                                      else
520                                      {
521                                        yyextra->javaBlock--;
522                                        if (yyextra->javaBlock==0)
523                                        {
524                                          copyToOutput(yyscanner," @endiliteral ",14);
525                                          BEGIN(yyextra->lastCommentContext);
526                                        }
527                                        else
528                                        {
529                                          copyToOutput(yyscanner,yytext,(int)yyleng);
530                                        }
531                                      }
532                                    }
533 <VerbatimCode>("```"[`]*|"~~~"[~]*) { /* end of markdown code block */
534                                      copyToOutput(yyscanner,yytext,(int)yyleng);
535                                      if (yytext[0]==yyextra->blockName[0])
536                                      {
537                                        BEGIN(yyextra->lastCommentContext);
538                                      }
539                                    }
540 <VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc"|"enduml") { /* end of verbatim block */
541                                      copyToOutput(yyscanner,yytext,(int)yyleng);
542                                      if (&yytext[4]==yyextra->blockName)
543                                      {
544                                        BEGIN(yyextra->lastCommentContext);
545                                      }
546                                    }
547 <VerbatimCode>^[ \t]*{CPPC}[\!\/]?   { /* skip leading comments */
548                                      if (!yyextra->inSpecialComment)
549                                      {
550                                        copyToOutput(yyscanner,yytext,(int)yyleng); 
551                                      }
552                                      else
553                                      {
554                                        int l=0;
555                                        while (yytext[l]==' ' || yytext[l]=='\t')
556                                        {
557                                          l++;
558                                        }
559                                        copyToOutput(yyscanner,yytext,l);
560                                        if (yyleng-l==3) // ends with //! or ///
561                                        {
562                                          copyToOutput(yyscanner," * ",3);
563                                        }
564                                        else // ends with //
565                                        {
566                                          copyToOutput(yyscanner,"//",2);
567                                        }
568                                      }
569                                    }
570 <Verbatim,VerbatimCode>[^`~@\/\\\n{}]* { /* any character not a backslash or new line or } */
571                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
572                                    }
573 <Verbatim,VerbatimCode>\n          { /* new line in verbatim block */
574                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
575                                    }
576 <Verbatim>^[ \t]*{CPPC}[/!]          {
577                                      if (yyextra->blockName=="dot" || yyextra->blockName=="msc" || yyextra->blockName=="uml" || yyextra->blockName.at(0)=='f')
578                                      {
579                                        // see bug 487871, strip /// from dot images and formulas.
580                                        int l=0;
581                                        while (yytext[l]==' ' || yytext[l]=='\t')
582                                        {
583                                          l++;
584                                        }
585                                        copyToOutput(yyscanner,yytext,l);
586                                        copyToOutput(yyscanner,"   ",3);
587                                      }
588                                      else // even slashes are verbatim (e.g. \verbatim, \code)
589                                      {
590                                        REJECT;
591                                      }
592                                    }
593 <Verbatim,VerbatimCode>.           { /* any other character */
594                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
595                                    }
596 <SkipString>\\.                    { /* escaped character in string */
597                                      if (yyextra->lang==SrcLangExt_Fortran || yyextra->lang==SrcLangExt_VHDL)
598                                      {
599                                        unput(yytext[1]);
600                                        copyToOutput(yyscanner,yytext,1);
601                                      }
602                                      else
603                                      {
604                                        copyToOutput(yyscanner,yytext,(int)yyleng);
605                                      }
606                                    }
607 <SkipString>"\""                   { /* end of string */ 
608                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
609                                      BEGIN(yyextra->stringContext); 
610                                    }
611 <SkipString>.                      { /* any other string character */ 
612                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
613                                    }
614 <SkipString>\n                     { /* new line inside string (illegal for some compilers) */ 
615                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
616                                    }
617 <SkipChar>\\.                      { /* escaped character */
618                                      if (yyextra->lang==SrcLangExt_Fortran || yyextra->lang==SrcLangExt_VHDL)
619                                      {
620                                        unput(yytext[1]);
621                                        copyToOutput(yyscanner,yytext,1);
622                                      }
623                                      else
624                                      {
625                                        copyToOutput(yyscanner,yytext,(int)yyleng);
626                                      }
627                                    }
628 <SkipChar>'                        { /* end of character literal */ 
629                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
630                                      BEGIN(yyextra->charContext);
631                                    }
632 <SkipChar>.                        { /* any other string character */ 
633                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
634                                    }
635 <SkipChar>\n                       { /* new line character */
636                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
637                                    }
638
639 <CComment,CNComment>[^ `~<\\!@*\n{\"\/]*     { /* anything that is not a '*' or command */ 
640                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
641                                    }
642 <CComment,CNComment>"*"+[^*\/\\@\n{\"]*      { /* stars without slashes */
643                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
644                                    }
645 <CComment>"\"\"\""                 { /* end of Python docstring */
646                                      if (yyextra->lang!=SrcLangExt_Python)
647                                      {
648                                        REJECT;
649                                      }
650                                      else
651                                      {
652                                        yyextra->nestingCount--;
653                                        yyextra->pythonDocString = FALSE;
654                                        copyToOutput(yyscanner,yytext,(int)yyleng);
655                                        BEGIN(Scan);
656                                      }
657                                    }
658 <CComment,CNComment>\n                       { /* new line in comment */
659                                      copyToOutput(yyscanner,yytext,(int)yyleng);
660                                      /* in case of Fortran always end of comment */
661                                      if (yyextra->lang==SrcLangExt_Fortran)
662                                      {
663                                        BEGIN(Scan);
664                                      }
665                                    }
666 <CComment,CNComment>"/""/"+/"*/"   { /* we are already in C-comment so not a start of a nested comment but 
667                                       * just the end of the comment (the end part is handled later). */
668                                      copyToOutput(yyscanner,yytext,(int)yyleng);
669                                    }
670 <CComment,CNComment>"/"+"*"                  { /* nested C comment */
671                                      if (yyextra->lang==SrcLangExt_Python ||
672                                          yyextra->lang==SrcLangExt_Markdown)
673                                      {
674                                        REJECT;
675                                      }
676                                      yyextra->nestingCount++;
677                                      yyextra->commentStack.push(yyextra->lineNr);
678                                      copyToOutput(yyscanner,yytext,(int)yyleng);
679                                    }
680 <CComment,CNComment>"*"+"/"                  { /* end of C comment */
681                                      if (yyextra->lang==SrcLangExt_Python ||
682                                          yyextra->lang==SrcLangExt_Markdown)
683                                      {
684                                        REJECT;
685                                      }
686                                      else
687                                      {
688                                        copyToOutput(yyscanner,yytext,(int)yyleng);
689                                        yyextra->nestingCount--;
690                                        if (yyextra->nestingCount<=0)
691                                        {
692                                          BEGIN(Scan);
693                                        }
694                                        else
695                                        {
696                                          //yyextra->nestingCount--;
697                                          yyextra->commentStack.pop();
698                                        }
699                                      }
700                                    }
701   /* Python an VHDL share CComment,CNComment, so special attention for ending comments is required */
702 <CComment,CNComment>"\n"/[ \t]*"#"         {
703                                      if (yyextra->lang!=SrcLangExt_VHDL)
704                                      {
705                                        REJECT;
706                                      }
707                                      else
708                                      {
709                                        if (yyextra->vhdl) // inside --! comment
710                                        {
711                                          yyextra->vhdl = FALSE;
712                                          copyToOutput(yyscanner,yytext,(int)yyleng);
713                                          BEGIN(Scan);
714                                        }
715                                        else // C-type comment
716                                        {
717                                          REJECT;
718                                        }
719                                      }
720                                    }
721 <CComment,CNComment>"\n"/[ \t]*"-"         {
722                                      if (yyextra->lang!=SrcLangExt_Python || yyextra->pythonDocString)
723                                      {
724                                        REJECT;
725                                      }
726                                      else
727                                      {
728                                        copyToOutput(yyscanner,yytext,(int)yyleng);
729                                        BEGIN(Scan);
730                                      }
731                                    }
732 <CComment,CNComment>"\n"/[ \t]*[^ \t#\-]           {
733                                      if (yyextra->lang==SrcLangExt_Python)
734                                      {
735                                        if (yyextra->pythonDocString)
736                                        {
737                                          REJECT;
738                                        }
739                                        else
740                                        {
741                                          copyToOutput(yyscanner,yytext,(int)yyleng);
742                                          BEGIN(Scan);
743                                        }
744                                      }
745                                      else if (yyextra->lang==SrcLangExt_VHDL)
746                                      {
747                                        if (yyextra->vhdl) // inside --! comment
748                                        {
749                                          yyextra->vhdl = FALSE;
750                                          copyToOutput(yyscanner,yytext,(int)yyleng);
751                                          BEGIN(Scan);
752                                        }
753                                        else // C-type comment
754                                        {
755                                          REJECT;
756                                        }
757                                      }
758                                      else
759                                      {
760                                        REJECT;
761                                      }
762                                    }
763    /* removed for bug 674842 (bug was introduced in rev 768)
764 <CComment,CNComment>"'"                    {
765                                      yyextra->charContext = YY_START;
766                                      copyToOutput(yyscanner,yytext,(int)yyleng);
767                                      BEGIN(SkipChar);
768                                    }
769 <CComment,CNComment>"\""                           {
770                                      yyextra->stringContext = YY_START;
771                                      copyToOutput(yyscanner,yytext,(int)yyleng);
772                                      BEGIN(SkipString);
773                                    }
774    */
775 <CComment,CNComment>.                      {
776                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
777                                    }
778 <SComment>^[ \t]*{CPPC}"/"{SLASHopt}/\n     {
779                                      replaceComment(yyscanner,0);
780                                    }
781 <SComment>\n[ \t]*{CPPC}"/"{SLASHopt}/\n    {
782                                      replaceComment(yyscanner,1); 
783                                    }
784 <SComment>^[ \t]*{CPPC}"/"[^\/\n]/.*\n { 
785                                      replaceComment(yyscanner,0);
786                                      yyextra->readLineCtx=YY_START;
787                                      BEGIN(ReadLine);
788                                    }
789 <SComment>\n[ \t]*{CPPC}[\/!]("<")?[ \t]*[\\@]"}".*\n {   
790                                      /* See Bug 752712: end the multiline comment when finding a @} or \} command */
791                                      copyToOutput(yyscanner," */",3); 
792                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
793                                      yyextra->inSpecialComment=FALSE;
794                                      yyextra->inRoseComment=FALSE;
795                                      BEGIN(Scan); 
796                                    }
797 <SComment>\n[ \t]*{CPPC}"/"[^\/\n]/.*\n  { 
798                                      replaceComment(yyscanner,1); 
799                                      yyextra->readLineCtx=YY_START;
800                                      BEGIN(ReadLine);
801                                    }
802 <SComment>^[ \t]*{CPPC}"!"             |    // just //!
803 <SComment>^[ \t]*{CPPC}"!<"/.*\n       |    // or   //!< something
804 <SComment>^[ \t]*{CPPC}"!"[^<]/.*\n    {    // or   //!something
805                                      replaceComment(yyscanner,0);
806                                      yyextra->readLineCtx=YY_START;
807                                      BEGIN(ReadLine);
808                                    }
809 <SComment>\n[ \t]*{CPPC}"!"            |
810 <SComment>\n[ \t]*{CPPC}"!<"/.*\n      |
811 <SComment>\n[ \t]*{CPPC}"!"[^<\n]/.*\n { 
812                                      replaceComment(yyscanner,1); 
813                                      yyextra->readLineCtx=YY_START;
814                                      BEGIN(ReadLine);
815                                    }
816 <SComment>^[ \t]*{CPPC}"##"/.*\n       {
817                                      if (!yyextra->inRoseComment)
818                                      {
819                                        REJECT;
820                                      }
821                                      else
822                                      {
823                                        replaceComment(yyscanner,0);
824                                        yyextra->readLineCtx=YY_START;
825                                        BEGIN(ReadLine);
826                                      }
827                                    }
828 <SComment>\n[ \t]*{CPPC}"##"/.*\n      {
829                                      if (!yyextra->inRoseComment)
830                                      {
831                                        REJECT;
832                                      }
833                                      else
834                                      {
835                                        replaceComment(yyscanner,1); 
836                                        yyextra->readLineCtx=YY_START;
837                                        BEGIN(ReadLine);
838                                      }
839                                    }
840 <SComment>\n                       { /* end of special comment */
841                                      copyToOutput(yyscanner," */",3); 
842                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
843                                      yyextra->inSpecialComment=FALSE;
844                                      yyextra->inRoseComment=FALSE;
845                                      yyextra->readLineCtx = Scan; // reset, otherwise there will be problems with:
846                                                                   //   static void handleCondSectionId
847                                      BEGIN(Scan); 
848                                    }
849 <ReadLine>{CCS}"*"                    {
850                                      copyToOutput(yyscanner,"/&zwj;**",8);
851                                    }
852 <ReadLine>{CCE}                     {
853                                      copyToOutput(yyscanner,"*&zwj;/",7);
854                                    }
855 <ReadLine>"*"                      {
856                                      copyToOutput(yyscanner,yytext,(int)yyleng);
857                                    }
858 <ReadLine>{RLopt}                  {
859                                      copyToOutput(yyscanner,yytext,(int)yyleng);
860                                    }
861 <ReadLine>{RLopt}/\n               {
862                                      copyToOutput(yyscanner,yytext,(int)yyleng);
863                                      BEGIN(yyextra->readLineCtx);
864                                    }
865 <CComment,CNComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command
866                                      copyToOutput(yyscanner,yytext,(int)yyleng);
867                                    }
868 <CComment,ReadLine>[\\@]"cond"/[^a-z_A-Z0-9]       { // conditional section
869                                      yyextra->condCtx = YY_START; 
870                                      BEGIN(CondLine);
871                                    }
872 <CComment,ReadLine>[\\@]"endcond"/[^a-z_A-Z0-9] { // end of conditional section
873                                      bool oldSkip=yyextra->skip;
874                                      endCondSection(yyscanner);
875                                      if (YY_START==CComment && oldSkip && !yyextra->skip) 
876                                      {
877                                        //printf("** Adding start of comment!\n");
878                                        if (yyextra->lang!=SrcLangExt_Python &&
879                                            yyextra->lang!=SrcLangExt_VHDL &&
880                                            yyextra->lang!=SrcLangExt_Markdown &&
881                                            yyextra->lang!=SrcLangExt_Fortran)
882                                        {
883                                          ADDCHAR('/');
884                                          ADDCHAR('*');
885                                          if (yyextra->specialComment)
886                                          {
887                                            ADDCHAR('*');
888                                          }
889                                        }
890                                      }
891                                     }
892 <CondLine>[!()&| \ta-z_A-Z0-9.\-]+ {
893                                      handleCondSectionId(yyscanner,yytext);
894                                    }
895 <CComment,ReadLine>[\\@]"cond"{WSopt}/\n {
896                                      yyextra->condCtx=YY_START;
897                                      handleCondSectionId(yyscanner," "); // fake section id causing the section to be hidden unconditionally
898                                    }
899 <CondLine>\n                       |
900 <CondLine>.                        { // forgot section id?
901                                      handleCondSectionId(yyscanner," "); // fake section id causing the section to be hidden unconditionally
902                                      if (*yytext=='\n') { yyextra->lineNr++; copyToOutput(yyscanner,"\n",1);}
903                                    }
904 <CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9-]*  { // expand alias without arguments
905                                      replaceAliases(yyscanner,QCString(yytext));
906                                    }
907 <CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9-]*"{" { // expand alias with arguments
908                                      yyextra->lastBlockContext=YY_START;
909                                      yyextra->blockCount=1;
910                                      yyextra->aliasString=yytext;
911                                      yyextra->lastEscaped=0;
912                                      BEGIN( ReadAliasArgs );
913                                    }
914 <ReadAliasArgs>^[ \t]*{CPPC}[/!]/[^\n]+   { // skip leading special comments (see bug 618079)
915                                    }
916 <ReadAliasArgs>{CCE}               { // oops, end of comment in the middle of an alias?
917                                      if (yyextra->lang==SrcLangExt_Python)
918                                      {
919                                        REJECT;
920                                      }
921                                      else // abort the alias, restart scanning
922                                      {
923                                        copyToOutput(yyscanner,yyextra->aliasString.data(),yyextra->aliasString.length());
924                                        copyToOutput(yyscanner,yytext,(int)yyleng);
925                                        BEGIN(Scan);
926                                      }
927                                    }
928 <ReadAliasArgs>[^{}\n\\\*]+        {
929                                      yyextra->aliasString+=yytext;
930                                      yyextra->lastEscaped=FALSE;
931                                    }
932 <ReadAliasArgs>"\\"                {
933                                      if (yyextra->lastEscaped)  yyextra->lastEscaped=FALSE;
934                                      else                yyextra->lastEscaped=TRUE;
935                                      yyextra->aliasString+=yytext;
936                                    }
937 <ReadAliasArgs>\n                  {
938                                      yyextra->aliasString+=yytext;
939                                      yyextra->lineNr++;
940                                      yyextra->lastEscaped=FALSE;
941                                    }
942 <ReadAliasArgs>"{"                 {
943                                      yyextra->aliasString+=yytext;
944                                      if (!yyextra->lastEscaped) yyextra->blockCount++;
945                                      yyextra->lastEscaped=FALSE;
946                                    }
947 <ReadAliasArgs>"}"                 {
948                                      yyextra->aliasString+=yytext;
949                                      if (!yyextra->lastEscaped) yyextra->blockCount--;
950                                      if (yyextra->blockCount==0)
951                                      {
952                                        replaceAliases(yyscanner,yyextra->aliasString);
953                                        BEGIN( yyextra->lastBlockContext );
954                                      }
955                                      yyextra->lastEscaped=FALSE;
956                                    }
957 <ReadAliasArgs>.                   {
958                                      yyextra->aliasString+=yytext;
959                                      yyextra->lastEscaped=FALSE;
960                                    }
961 <ReadLine>.                        {
962                                      copyToOutput(yyscanner,yytext,(int)yyleng);
963                                    }
964
965 <*>.                               {
966                                      copyToOutput(yyscanner,yytext,(int)yyleng);
967                                    }
968   /*
969 <*>\n  { fprintf(stderr,"Lex scanner %s (%s) default rule newline for state %s.\n", __FILE__, qPrint(yyextra->fileName),stateToString(YY_START));}
970   */
971 %%
972
973 static void replaceCommentMarker(yyscan_t yyscanner,const char *s,int len)
974 {
975   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
976   const char *p=s;
977   char c;
978   // copy leading blanks
979   while ((c=*p) && (c==' ' || c=='\t' || c=='\n')) 
980   {
981     ADDCHAR(c);
982     yyextra->lineNr += c=='\n';
983     p++;
984   }
985   // replace start of comment marker by blanks and the last character by a *
986   int blanks=0;
987   while ((c=*p) && (c=='/' || c=='!' || c=='#')) 
988   {
989     blanks++;
990     p++;
991     if (*p=='<') // comment-after-item marker 
992     { 
993       blanks++;
994       p++; 
995     }
996     if (c=='!') // end after first !
997     {
998       break;
999     }
1000   }
1001   if (blanks>0)
1002   {
1003     while (blanks>2)
1004     {
1005       ADDCHAR(' ');
1006       blanks--;
1007     }
1008     if (blanks>1) ADDCHAR('*');
1009     ADDCHAR(' ');
1010   }
1011   // copy comment line to output
1012   ADDARRAY(p,len-(int)(p-s));
1013 }
1014
1015 static inline int computeIndent(const char *s)
1016 {
1017   int col=0;
1018   int tabSize=Config_getInt(TAB_SIZE);
1019   const char *p=s;
1020   char c;
1021   while ((c=*p++))
1022   {
1023     if (c==' ') col++;
1024     else if (c=='\t') col+=tabSize-(col%tabSize); 
1025     else break;
1026   }
1027   return col;
1028 }
1029
1030 static inline void copyToOutput(yyscan_t yyscanner,const char *s,int len)
1031 {
1032   int tabSize=Config_getInt(TAB_SIZE);
1033   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1034   int i;
1035   if (yyextra->skip) // only add newlines.
1036   {
1037     for (i=0;i<len;i++)
1038     {
1039       switch(s[i])
1040       {
1041         case '\n':
1042           ADDCHAR('\n');
1043           yyextra->lineNr++;
1044           yyextra->col=0;
1045           break;
1046         case '\t':
1047           yyextra->col+=tabSize-(yyextra->col%tabSize);
1048           break;
1049         default:
1050           yyextra->col++;
1051           break;
1052       }
1053     }
1054   }
1055   else if (len>0)
1056   {
1057     ADDARRAY(s,len);
1058     for (i=0;i<len;i++) 
1059     {
1060       switch (s[i])
1061       {
1062         case '\n': yyextra->col=0; 
1063                    //fprintf(stderr,"---> copy %d\n",g_lineNr);
1064                    yyextra->lineNr++; break;
1065         case '\t': yyextra->col+=tabSize-(yyextra->col%tabSize); break;
1066         default:   yyextra->col++; break;
1067       }
1068     }
1069   }
1070 }
1071
1072 static void clearCommentStack(yyscan_t yyscanner)
1073 {
1074   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1075   while (!yyextra->commentStack.empty()) yyextra->commentStack.pop();
1076 }
1077
1078 static void startCondSection(yyscan_t yyscanner,const QCString &sectId)
1079 {
1080   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1081   //printf("startCondSection: skip=%d stack=%d\n",g_skip,g_condStack.count());
1082   CondParser prs;
1083   bool expResult = prs.parse(yyextra->fileName,yyextra->lineNr,sectId);
1084   yyextra->condStack.push(commentcnvYY_CondCtx(yyextra->lineNr,sectId,yyextra->skip));
1085   if (!expResult) // not enabled
1086   {
1087     yyextra->skip=TRUE;
1088   }
1089 }
1090
1091 static void endCondSection(yyscan_t yyscanner)
1092 {
1093   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1094   if (yyextra->condStack.empty())
1095   {
1096     warn(yyextra->fileName,yyextra->lineNr,"Found \\endcond command without matching \\cond");
1097     yyextra->skip=FALSE;
1098   }
1099   else
1100   {
1101     const commentcnvYY_CondCtx &ctx = yyextra->condStack.top();
1102     yyextra->skip=ctx.skip;
1103     yyextra->condStack.pop();
1104   }
1105   //printf("endCondSection: skip=%d stack=%d\n",g_skip,g_condStack.count());
1106 }
1107
1108 static void handleCondSectionId(yyscan_t yyscanner,const char *expression)
1109 {
1110   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1111   bool oldSkip=yyextra->skip;
1112   startCondSection(yyscanner,QCString(expression));
1113   if ((yyextra->condCtx==CComment || yyextra->readLineCtx==SComment) && 
1114       !oldSkip && yyextra->skip) 
1115   {
1116     if (yyextra->lang!=SrcLangExt_Python &&
1117         yyextra->lang!=SrcLangExt_VHDL &&
1118         yyextra->lang!=SrcLangExt_Markdown &&
1119         yyextra->lang!=SrcLangExt_Fortran)
1120     {
1121       ADDCHAR('*');
1122       ADDCHAR('/');
1123     }
1124   }
1125   if (yyextra->readLineCtx==SComment)
1126   {
1127     BEGIN(SComment);
1128   }
1129   else
1130   {
1131     BEGIN(yyextra->condCtx);
1132   }
1133 }
1134
1135 /** copies string \a s with length \a len to the output, while 
1136  *  replacing any alias commands found in the string.
1137  */
1138 static void replaceAliases(yyscan_t yyscanner,const QCString &s)
1139 {
1140   QCString result = resolveAliasCmd(s);
1141   //printf("replaceAliases(%s)->'%s'\n",s,result.data());
1142   copyToOutput(yyscanner,result.data(),result.length());
1143 }
1144
1145
1146 static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size)
1147 {
1148   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1149   yy_size_t bytesInBuf = yyextra->inBuf->curPos()-yyextra->inBufPos;
1150   yy_size_t bytesToCopy = std::min(max_size,bytesInBuf);
1151   memcpy(buf,yyextra->inBuf->data()+yyextra->inBufPos,bytesToCopy);
1152   yyextra->inBufPos+=bytesToCopy;
1153   return bytesToCopy;
1154 }
1155
1156 static void replaceComment(yyscan_t yyscanner,int offset)
1157 {
1158   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1159   if (yyextra->mlBrief || yyextra->skip)
1160   {
1161     copyToOutput(yyscanner,yytext,(int)yyleng);
1162   }
1163   else
1164   {
1165     //printf("replaceComment(%s)\n",yytext);
1166     int i=computeIndent(&yytext[offset]);
1167     if (i==yyextra->blockHeadCol)
1168     {
1169       replaceCommentMarker(yyscanner,yytext,(int)yyleng);
1170     }
1171     else
1172     {
1173       copyToOutput(yyscanner," */",3);
1174       for (i=(int)yyleng-1;i>=0;i--) unput(yytext[i]);
1175       yyextra->inSpecialComment=FALSE;
1176       BEGIN(Scan);
1177     }
1178   }
1179 }
1180
1181 /*! This function does three things:
1182  *  -# It converts multi-line C++ style comment blocks (that are aligned)
1183  *     to C style comment blocks (if MULTILINE_CPP_IS_BRIEF is set to NO).
1184  *  -# It replaces aliases with their definition (see ALIASES)
1185  *  -# It handles conditional sections (cond...endcond blocks)
1186  */
1187 void convertCppComments(BufStr *inBuf,BufStr *outBuf,const QCString &fileName)
1188 {
1189   yyscan_t yyscanner;
1190   commentcnvYY_state extra;
1191   commentcnvYYlex_init_extra(&extra,&yyscanner);
1192 #ifdef FLEX_DEBUG
1193   commentcnvYYset_debug(1,yyscanner);
1194 #endif
1195   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1196   //printf("convertCppComments(%s)\n",fileName);
1197   yyextra->inBuf    = inBuf;
1198   yyextra->outBuf   = outBuf;
1199   yyextra->inBufPos = 0;
1200   yyextra->col      = 0;
1201   yyextra->mlBrief = Config_getBool(MULTILINE_CPP_IS_BRIEF);
1202   yyextra->skip     = FALSE;
1203   yyextra->fileName = fileName;
1204   yyextra->lang = getLanguageFromFileName(fileName);
1205   yyextra->pythonDocString = FALSE;
1206   yyextra->lineNr   = 1;
1207   while (!yyextra->condStack.empty()) yyextra->condStack.pop();
1208   clearCommentStack(yyscanner);
1209   yyextra->vhdl = FALSE;
1210
1211   printlex(yy_flex_debug, TRUE, __FILE__, qPrint(fileName));
1212   yyextra->isFixedForm = FALSE;
1213   if (yyextra->lang==SrcLangExt_Fortran)
1214   {
1215     FortranFormat fmt = convertFileNameFortranParserCode(fileName);
1216     yyextra->isFixedForm = recognizeFixedForm(QCString(inBuf->data()),fmt);
1217   }
1218
1219   if (yyextra->lang==SrcLangExt_Markdown)
1220   {
1221     yyextra->nestingCount=0;
1222     BEGIN(CComment);
1223     yyextra->commentStack.push(yyextra->lineNr);
1224   }
1225   else
1226   {
1227     BEGIN(Scan);
1228   }
1229   yylex(yyscanner);
1230   while (!yyextra->condStack.empty())
1231   {
1232     const commentcnvYY_CondCtx &ctx = yyextra->condStack.top();
1233     QCString sectionInfo(" ");
1234     if (ctx.sectionId!=" ") sectionInfo.sprintf(" with label '%s' ",ctx.sectionId.stripWhiteSpace().data());
1235     warn(yyextra->fileName,ctx.lineNr,"Conditional section%sdoes not have "
1236         "a corresponding \\endcond command within this file.",sectionInfo.data());
1237     yyextra->condStack.pop();
1238   }
1239   if (yyextra->nestingCount>0 && yyextra->lang!=SrcLangExt_Markdown && yyextra->lang!=SrcLangExt_Fortran)
1240   {
1241     QCString tmp("(probable line reference: ");
1242     bool first = TRUE;
1243     while (!yyextra->commentStack.empty())
1244     {
1245       int lineNr = yyextra->commentStack.top();
1246       if (!first) tmp += ", ";
1247       tmp += QCString().setNum(lineNr);
1248       first = FALSE;
1249       yyextra->commentStack.pop();
1250     }
1251     tmp += ")";
1252     warn(yyextra->fileName,yyextra->lineNr,"Reached end of file while still inside a (nested) comment. "
1253         "Nesting level %d %s",yyextra->nestingCount,tmp.data());
1254   }
1255   yyextra->nestingCount = 0;
1256   if (Debug::isFlagSet(Debug::CommentCnv))
1257   {
1258     yyextra->outBuf->at(yyextra->outBuf->curPos())='\0';
1259     Debug::print(Debug::CommentCnv,0,"-----------\nCommentCnv: %s\n"
1260                  "output=[\n%s]\n-----------\n",qPrint(fileName),yyextra->outBuf->data()
1261                 );
1262   }
1263   printlex(yy_flex_debug, FALSE, __FILE__, qPrint(fileName));
1264   commentcnvYYlex_destroy(yyscanner);
1265 }
1266
1267
1268 //----------------------------------------------------------------------------
1269
1270 #if USE_STATE2STRING
1271 #include "commentcnv.l.h"
1272 #endif