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