Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / defargs.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
18 /*! \file
19  *  This scanner is used to convert a string into a list of function or 
20  *  template arguments. Each parsed argument results in a Argument struct,
21  *  that is put into an ArgumentList in declaration order.
22  *  Comment blocks for arguments can also be included in the string.
23  *  The argument string does not contain new-lines (except inside any
24  *  comment blocks).
25  *  An Argument consists of the string fields: 
26  *                 type,name,default value, and documentation
27  *  The Argument list as a whole can be pure, constant or volatile.
28  *
29  *  Examples of input strings are:
30  *  \code
31  *    "(int a,int b) const"
32  *    "(const char *s="hello world",int=5) = 0"
33  *    "<class T,class N>"
34  *    "(char c,const char)"
35  *  \endcode
36  *
37  *  Note: It is not always possible to distinguish between the name and 
38  *        type of an argument. In case of doubt the name is added to the
39  *        type, and the matchArgumentList in util.cpp is be used to
40  *        further determine the correct separation.
41  */
42 %option never-interactive
43 %option prefix="defargsYY"
44
45 %{
46
47 /*
48  *      includes
49  */
50 #include <stdio.h>
51 //#include <iostream.h>
52 #include <assert.h>
53 #include <ctype.h>
54 #include <qregexp.h>
55 #include <qcstringlist.h>
56
57 #include "defargs.h"
58 #include "entry.h"
59 #include "util.h"
60 #include "arguments.h"
61 #include "message.h"
62   
63 #define YY_NO_INPUT 1
64 #define YY_NO_UNISTD_H 1
65   
66 /* -----------------------------------------------------------------
67  *      state variables
68  */
69 static const char      *g_inputString;
70 static int              g_inputPosition;
71 static ArgumentList    *g_argList;
72 static QCString        *g_copyArgValue;
73 static QCString         g_curArgTypeName;
74 static QCString         g_curArgDefValue;
75 static QCString         g_curArgName;
76 static QCString         g_curArgDocs;
77 static QCString         g_curArgAttrib;
78 static QCString         g_curArgArray;
79 static QCString         g_curTypeConstraint;
80 static QCString         g_extraTypeChars;
81 static int              g_argRoundCount;
82 static int              g_argSharpCount;
83 static int              g_argCurlyCount;
84 static int              g_readArgContext;
85 static int              g_lastDocContext;
86 static int              g_lastDocChar;
87 static int              g_lastExtendsContext;
88 static QCString         g_delimiter;
89
90 /* -----------------------------------------------------------------
91  */
92 #undef  YY_INPUT
93 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
94
95 static int yyread(char *buf,int max_size)
96 {
97     int c=0;
98     while( c < max_size && g_inputString[g_inputPosition] )
99     {
100         *buf = g_inputString[g_inputPosition++] ;
101         c++; buf++;
102     }
103     return c;
104 }
105
106 /* bug_520975 */
107 static bool nameIsActuallyPartOfType(QCString &name)
108 {
109   static bool first=TRUE;
110   static QDict<void> keywords(17);
111   if (first) // fill keyword dict first time
112   {
113     #define DUMMY_ADDR (void*)0x8
114     keywords.insert("unsigned", DUMMY_ADDR); // foo(... unsigned)
115     keywords.insert("signed",   DUMMY_ADDR); // foo(... signed)
116     keywords.insert("bool",     DUMMY_ADDR); // foo(... bool)
117     keywords.insert("char",     DUMMY_ADDR); // foo(... char)
118     keywords.insert("char8_t",  DUMMY_ADDR); // foo(... char8_t)
119     keywords.insert("char16_t", DUMMY_ADDR); // foo(... char16_t)
120     keywords.insert("char32_t", DUMMY_ADDR); // foo(... char32_t)
121     keywords.insert("int",      DUMMY_ADDR); // foo(... int)
122     keywords.insert("short",    DUMMY_ADDR); // foo(... short)
123     keywords.insert("long",     DUMMY_ADDR); // foo(... long)
124     keywords.insert("float",    DUMMY_ADDR); // foo(... float)
125     keywords.insert("double",   DUMMY_ADDR); // foo(... double)
126     keywords.insert("int8_t",   DUMMY_ADDR); // foo(... int8_t)
127     keywords.insert("uint8_t",  DUMMY_ADDR); // foo(... uint8_t)
128     keywords.insert("int16_t",  DUMMY_ADDR); // foo(... int16_t)
129     keywords.insert("uint16_t", DUMMY_ADDR); // foo(... uint16_t)
130     keywords.insert("int32_t",  DUMMY_ADDR); // foo(... int32_t)
131     keywords.insert("uint32_t", DUMMY_ADDR); // foo(... uint32_t)
132     keywords.insert("const",    DUMMY_ADDR); // foo(... const)
133     keywords.insert("volatile", DUMMY_ADDR); // foo(... volatile)
134     first=FALSE;
135   }
136   return name.length()>0 && keywords.find(name)!=0;
137 }
138 %}
139
140 B       [ \t]
141 ID      [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
142 RAWBEGIN  (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
143 RAWEND    ")"[^ \t\(\)\\]{0,16}\"
144
145 %option noyywrap
146
147 %x      Start
148 %x      CopyArgString
149 %x      CopyRawString
150 %x      CopyArgRound
151 %x      CopyArgRound2
152 %x      CopyArgSharp
153 %x      CopyArgCurly
154 %x      ReadFuncArgType
155 %x      ReadFuncArgDef
156 %x      ReadFuncArgPtr
157 %x      FuncQual
158 %x      ReadDocBlock
159 %x      ReadDocLine
160 %x      ReadTypeConstraint
161 %x      TrailingReturn
162
163
164 %%
165
166 <Start>[<(]                             { BEGIN(ReadFuncArgType); }
167
168 <ReadFuncArgType>{B}*                   {
169                                           g_curArgTypeName+=" ";
170                                         }
171 <ReadFuncArgType>"["[^\]]*"]"           { 
172                                           if (g_curArgTypeName.stripWhiteSpace().isEmpty())
173                                           {
174                                             g_curArgAttrib=yytext; // for M$-IDL
175                                           }
176                                           else // array type
177                                           {
178                                             g_curArgArray+=yytext;
179                                           }
180                                         }
181 <ReadFuncArgDef>"'"\\[0-7]{1,3}"'"      { g_curArgDefValue+=yytext; }
182 <ReadFuncArgDef>"'"\\."'"               { g_curArgDefValue+=yytext; }
183 <ReadFuncArgDef>"'"."'"                 { g_curArgDefValue+=yytext; }
184 <ReadFuncArgDef>{RAWBEGIN}              { g_curArgDefValue+=yytext; 
185                                           QCString text=yytext;
186                                           int i=text.find('"');
187                                           g_delimiter = yytext+i+1;
188                                           g_delimiter=g_delimiter.left(g_delimiter.length()-1);
189                                           BEGIN( CopyRawString );
190                                         }
191 <ReadFuncArgDef>\"                      {
192                                           g_curArgDefValue+=*yytext;
193                                           BEGIN( CopyArgString );
194                                         }
195 <ReadFuncArgType>"("([^:)]+{B}*"::")*{B}*[&*\^]+{B}*/{ID} { 
196                                           // function pointer as argument
197                                           g_curArgTypeName+=yytext;
198                                           //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
199                                           BEGIN( ReadFuncArgPtr );
200                                         }
201 <ReadFuncArgPtr>{ID}                    {
202                                           g_curArgName=yytext;
203                                         }
204 <ReadFuncArgPtr>")"{B}*"("              { // function pointer
205                                           g_curArgTypeName+=yytext;
206                                           //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
207                                           g_readArgContext = ReadFuncArgType;
208                                           g_copyArgValue=&g_curArgTypeName;
209                                           g_argRoundCount=0;
210                                           BEGIN( CopyArgRound2 );
211                                         }
212 <ReadFuncArgPtr>")"/{B}*"["             { // pointer to fixed size array
213                                           g_curArgTypeName+=yytext;
214                                           g_curArgTypeName+=g_curArgName;
215                                           //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
216                                           BEGIN( ReadFuncArgType );
217                                         }
218 <ReadFuncArgPtr>")"                     { // redundant braces detected / remove them
219                                           int i=g_curArgTypeName.findRev('('),l=g_curArgTypeName.length();
220                                           if (i!=-1)
221                                             g_curArgTypeName=g_curArgTypeName.left(i)+
222                                                            g_curArgTypeName.right(l-i-1);
223                                           g_curArgTypeName+=g_curArgName;
224                                           BEGIN( ReadFuncArgType );
225                                         }
226 <ReadFuncArgType>"<="|">="|"->"|">>"|"<<" { // handle operators in defargs
227                                           g_curArgTypeName+=yytext;
228                                         }
229 <ReadFuncArgType,ReadFuncArgDef>[({<]   {        
230                                           if (YY_START==ReadFuncArgType)
231                                           {
232                                             g_curArgTypeName+=*yytext;
233                                             g_copyArgValue=&g_curArgTypeName;
234                                           }
235                                           else // YY_START==ReadFuncArgDef
236                                           {
237                                             g_curArgDefValue+=*yytext;
238                                             g_copyArgValue=&g_curArgDefValue;
239                                           }
240                                           g_readArgContext = YY_START; 
241                                           if (*yytext=='(')
242                                           {
243                                             g_argRoundCount=0; 
244                                             BEGIN( CopyArgRound ); 
245                                           }
246                                           else if (*yytext=='{')
247                                           {
248                                             g_argCurlyCount=0; 
249                                             BEGIN( CopyArgCurly ); 
250                                           }
251                                           else // yytext=='<'
252                                           {
253                                             g_argSharpCount=0; 
254                                             g_argRoundCount=0; 
255                                             BEGIN( CopyArgSharp ); 
256                                           }
257                                         }
258 <CopyArgRound,CopyArgRound2>"("         {
259                                           g_argRoundCount++;
260                                           *g_copyArgValue += *yytext;
261                                         }
262 <CopyArgRound,CopyArgRound2>")"({B}*{ID})* {
263                                           *g_copyArgValue += yytext;
264                                           if (g_argRoundCount>0) 
265                                           {
266                                             g_argRoundCount--;
267                                           }
268                                           else 
269                                           {
270                                             if (YY_START==CopyArgRound2)
271                                             {
272                                               *g_copyArgValue+=" "+g_curArgName;
273                                             }
274                                             BEGIN( g_readArgContext );
275                                           }
276                                         }
277 <CopyArgRound>")"/{B}*                  {
278                                           *g_copyArgValue += *yytext;
279                                           if (g_argRoundCount>0) g_argRoundCount--;
280                                           else BEGIN( g_readArgContext );
281                                         }
282 <CopyArgSharp>"<<"                      {
283                                           if (g_argRoundCount>0)
284                                           {
285                                             *g_copyArgValue += yytext;
286                                           }
287                                           else
288                                           {
289                                             REJECT;
290                                           }
291                                         }
292 <CopyArgSharp>">>)"                     { // combined token (see bug 790320)
293                                           *g_copyArgValue += yytext;
294                                           if (g_argSharpCount>0) g_argSharpCount--;
295                                           else BEGIN( g_readArgContext );
296                                           if (g_argSharpCount>0) g_argSharpCount--;
297                                           else BEGIN( g_readArgContext );
298                                           g_argRoundCount--;
299                                         }
300 <CopyArgSharp>">>"                      {
301                                           if (g_argRoundCount>0)
302                                           {
303                                             *g_copyArgValue += yytext;
304                                           }
305                                           else
306                                           {
307                                             REJECT;
308                                           }
309                                         }
310 <CopyArgSharp>"<"                       {
311                                           g_argSharpCount++;
312                                           *g_copyArgValue += *yytext;
313                                         }
314 <CopyArgSharp>">"                       {
315                                           *g_copyArgValue += *yytext;
316                                           if (g_argSharpCount>0) g_argSharpCount--;
317                                           else BEGIN( g_readArgContext );
318                                         }
319 <CopyArgSharp>"("                       {
320                                           g_argRoundCount++;
321                                           *g_copyArgValue += *yytext;
322                                         }
323 <CopyArgSharp>")"                       {
324                                           g_argRoundCount--;
325                                           *g_copyArgValue += *yytext;
326                                         }
327 <CopyArgCurly>"{"                       {
328                                           g_argCurlyCount++;
329                                           *g_copyArgValue += *yytext;
330                                         }
331 <CopyArgCurly>"}"                       {
332                                           *g_copyArgValue += *yytext;
333                                           if (g_argCurlyCount>0) g_argCurlyCount--;
334                                           else BEGIN( g_readArgContext );
335                                         }
336 <CopyArgString>\\.                      {
337                                           g_curArgDefValue+=yytext;
338                                         }
339 <CopyRawString>{RAWEND}                 {
340                                           g_curArgDefValue+=yytext;
341                                           QCString delimiter = yytext+1;
342                                           delimiter=delimiter.left(delimiter.length()-1);
343                                           if (delimiter==g_delimiter)
344                                           {
345                                             BEGIN( ReadFuncArgDef );
346                                           }
347                                         }
348 <CopyArgString>\"                       {
349                                           g_curArgDefValue+=*yytext;
350                                           BEGIN( ReadFuncArgDef );
351                                         }
352 <ReadFuncArgType>"="                    {
353                                           BEGIN( ReadFuncArgDef );
354                                         }
355 <ReadFuncArgType,ReadFuncArgDef>[,)>]{B}*("/*"[*!]|"//"[/!])"<" {
356                                           g_lastDocContext=YY_START;
357                                           g_lastDocChar=*yytext;  
358                                           QCString text=yytext;
359                                           if (text.find("//")!=-1)
360                                             BEGIN( ReadDocLine );
361                                           else
362                                             BEGIN( ReadDocBlock );
363                                         }
364 <ReadFuncArgType,ReadFuncArgDef>[,)>]   {
365                                           if (*yytext==')' && g_curArgTypeName.stripWhiteSpace().isEmpty())
366                                           {
367                                             g_curArgTypeName+=*yytext;
368                                             BEGIN(FuncQual);
369                                           }
370                                           else
371                                           {
372                                             g_curArgTypeName=removeRedundantWhiteSpace(g_curArgTypeName);
373                                             g_curArgDefValue=g_curArgDefValue.stripWhiteSpace();
374                                             //printf("curArgType=`%s' curArgDefVal=`%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data());
375                                             int l=g_curArgTypeName.length();
376                                             if (l>0)
377                                             {
378                                               int i=l-1;
379                                               while (i>=0 && (isspace((uchar)g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--;
380                                               while (i>=0 && (isId(g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='$')) i--;
381                                               Argument *a = new Argument;
382                                               a->attrib  = g_curArgAttrib.copy();
383                                               a->typeConstraint = g_curTypeConstraint.stripWhiteSpace();
384                                               //printf("a->type=%s a->name=%s i=%d l=%d\n",
385                                               //        a->type.data(),a->name.data(),i,l);
386                                               a->array.resize(0);
387                                               if (i==l-1 && g_curArgTypeName.at(i)==')') // function argument
388                                               {
389                                                 int bi=g_curArgTypeName.find('(');
390                                                 int fi=bi-1;
391                                                 //printf("func arg fi=%d\n",fi);
392                                                 while (fi>=0 && (isId(g_curArgTypeName.at(fi)) || g_curArgTypeName.at(fi)==':')) fi--;
393                                                 if (fi>=0)
394                                                 {
395                                                   a->type  = g_curArgTypeName.left(fi+1);
396                                                   a->name  = g_curArgTypeName.mid(fi+1,bi-fi-1).stripWhiteSpace();
397                                                   a->array = g_curArgTypeName.right(l-bi);
398                                                 }
399                                                 else
400                                                 {
401                                                   a->type = g_curArgTypeName;
402                                                 }
403                                               }
404                                               else if (i>=0 && g_curArgTypeName.at(i)!=':')
405                                               { // type contains a name
406                                                 a->type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1)).stripWhiteSpace();
407                                                 a->name = g_curArgTypeName.right(l-i-1).stripWhiteSpace();
408
409                                                 // if the type becomes a type specifier only then we make a mistake
410                                                 // and need to correct it to avoid seeing a nameless parameter
411                                                 // "struct A" as a parameter with type "struct" and name "A".
412                                                 int sv=0;
413                                                 if      (a->type.left(6)=="const ")    sv=6;
414                                                 else if (a->type.left(9)=="volatile ") sv=9;
415
416                                                 if (a->type.mid(sv)=="struct"    ||
417                                                     a->type.mid(sv)=="union"     ||
418                                                     a->type.mid(sv)=="class"     ||
419                                                     a->type.mid(sv)=="typename"  ||
420                                                     nameIsActuallyPartOfType(a->name)
421                                                    )
422                                                 {
423                                                   a->type = a->type + " " + a->name;
424                                                   a->name.resize(0);
425                                                 }
426                                                 //printf(" --> a->type='%s' a->name='%s'\n",a->type.data(),a->name.data());
427                                               }
428                                               else // assume only the type was specified, try to determine name later 
429                                               {
430                                                 a->type = removeRedundantWhiteSpace(g_curArgTypeName);  
431                                               }
432                                               if (!a->type.isEmpty() && a->type.at(0)=='$') // typeless PHP name?
433                                               {
434                                                 a->name = a->type;
435                                                 a->type = "";
436                                               }
437                                               a->array  += removeRedundantWhiteSpace(g_curArgArray);
438                                               //printf("array=%s\n",a->array.data());
439                                               int alen = a->array.length();
440                                               if (alen>2 && a->array.at(0)=='(' && 
441                                                             a->array.at(alen-1)==')') // fix-up for int *(a[10])
442                                               {
443                                                 int i=a->array.find('[')-1;
444                                                 a->array = a->array.mid(1,alen-2);
445                                                 if (i>0 && a->name.isEmpty())
446                                                 {
447                                                   a->name  = a->array.left(i).stripWhiteSpace();
448                                                   a->array = a->array.mid(i);
449                                                 }
450                                               }
451                                               a->defval = g_curArgDefValue.copy();
452                                               //printf("a->type=%s a->name=%s a->defval=\"%s\"\n",a->type.data(),a->name.data(),a->defval.data());
453                                               a->docs   = g_curArgDocs.stripWhiteSpace();
454                                               //printf("Argument `%s' `%s' adding docs=`%s'\n",a->type.data(),a->name.data(),a->docs.data());
455                                               g_argList->append(a);
456                                             }
457                                             g_curArgAttrib.resize(0);
458                                             g_curArgTypeName.resize(0);
459                                             g_curArgDefValue.resize(0);
460                                             g_curArgArray.resize(0);
461                                             g_curArgDocs.resize(0);
462                                             g_curTypeConstraint.resize(0);
463                                             if (*yytext==')')
464                                             {
465                                               BEGIN(FuncQual);
466                                               //printf(">>> end of argument list\n");
467                                             }
468                                             else
469                                             {
470                                               BEGIN( ReadFuncArgType );
471                                             }
472                                           }
473                                         }
474 <ReadFuncArgType,ReadFuncArgPtr>"extends" {
475                                           g_curTypeConstraint.resize(0);
476                                           g_lastExtendsContext=YY_START;
477                                           BEGIN(ReadTypeConstraint);
478                                         }
479 <ReadFuncArgType,ReadFuncArgPtr>"$"?{ID} { 
480                                           QCString name=yytext; //resolveDefines(yytext);
481                                           if (YY_START==ReadFuncArgType && g_curArgArray=="[]") // Java style array
482                                           {
483                                             g_curArgTypeName+=" []";
484                                             g_curArgArray.resize(0);
485                                           }
486                                           //printf("resolveName `%s'->`%s'\n",yytext,name.data());
487                                           g_curArgTypeName+=name;
488                                         }
489 <ReadFuncArgType,ReadFuncArgPtr>.       { 
490                                           g_curArgTypeName+=*yytext;
491                                         }
492
493 <ReadFuncArgDef,CopyArgString>"<="|"->"|">="|">>"|"<<"  {
494                                           g_curArgDefValue+=yytext;
495                                         }
496 <ReadFuncArgDef,CopyArgString,CopyRawString>.           {
497                                           g_curArgDefValue+=*yytext;
498                                         }
499 <CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>{ID}  {
500                                           QCString name=yytext; //resolveDefines(yytext);
501                                           *g_copyArgValue+=name;
502                                         }
503 <CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>.  {
504                                           *g_copyArgValue += *yytext;
505                                         }
506 <ReadTypeConstraint>[,)>]               {
507                                           unput(*yytext);
508                                           BEGIN(g_lastExtendsContext);
509                                         }
510 <ReadTypeConstraint>.                   {
511                                           g_curTypeConstraint+=yytext;
512                                         }
513 <ReadTypeConstraint>\n                  {
514                                           g_curTypeConstraint+=' ';
515                                         }
516 <FuncQual>"const"                       {
517                                           g_argList->constSpecifier=TRUE;
518                                         }
519 <FuncQual>"volatile"                    {
520                                           g_argList->volatileSpecifier=TRUE;
521                                         }
522 <FuncQual>"&"                           {
523                                           g_argList->refQualifier=RefQualifierLValue;
524                                         }
525 <FuncQual>"&&"                          {
526                                           g_argList->refQualifier=RefQualifierRValue;
527                                         }
528 <FuncQual,TrailingReturn>"="{B}*"0"     {
529                                           g_argList->pureSpecifier=TRUE;
530                                           BEGIN(FuncQual);
531                                         }
532 <FuncQual>"->"                          { // C++11 trailing return type
533                                           g_argList->trailingReturnType=" -> ";
534                                           BEGIN(TrailingReturn);
535                                         }
536 <TrailingReturn>{B}/("final"|"override"){B}*  {
537                                           unput(*yytext);
538                                           BEGIN(FuncQual);
539                                         }
540 <TrailingReturn>.                       {
541                                           g_argList->trailingReturnType+=yytext;
542                                         }
543 <TrailingReturn>\n                      {
544                                           g_argList->trailingReturnType+=yytext;
545                                         }
546 <FuncQual>")"{B}*"["[^]]*"]"            { // for functions returning a pointer to an array, 
547                                           // i.e. ")[]" in "int (*f(int))[4]" with argsString="(int))[4]"
548                                           g_extraTypeChars=yytext;
549                                         }
550 <ReadDocBlock>[^\*\n]+                  {
551                                           g_curArgDocs+=yytext;
552                                         }
553 <ReadDocLine>[^\n]+                     {
554                                           g_curArgDocs+=yytext;
555                                         }
556 <ReadDocBlock>"*/"                      { 
557                                           if (g_lastDocChar!=0)
558                                             unput(g_lastDocChar);
559                                           BEGIN(g_lastDocContext); 
560                                         }
561 <ReadDocLine>\n                         {
562                                           if (g_lastDocChar!=0)
563                                             unput(g_lastDocChar);
564                                           BEGIN(g_lastDocContext);
565                                         }
566 <ReadDocBlock>\n                        {
567                                           g_curArgDocs+=*yytext;
568                                         }
569 <ReadDocBlock>.                         {
570                                           g_curArgDocs+=*yytext;
571                                         }
572 <*>("/*"[*!]|"//"[/!])("<"?)            {
573                                           g_lastDocContext=YY_START;
574                                           g_lastDocChar=0;  
575                                           if (yytext[1]=='/')
576                                             BEGIN( ReadDocLine );
577                                           else
578                                             BEGIN( ReadDocBlock );
579                                         }
580 <*>\n
581 <*>.
582
583 %%
584
585 /* ----------------------------------------------------------------------------
586  */
587
588 /*! Converts an argument string into an ArgumentList.
589  *  \param[in] argsString the list of Arguments.
590  *  \param[out] al a reference to resulting argument list pointer.
591  *  \param[out] extraTypeChars point to string to which trailing characters 
592  *              for complex types are written to
593  */
594  
595 void stringToArgumentList(const char *argsString,ArgumentList* al,QCString *extraTypeChars)
596 {
597   if (al==0) return; 
598   if (argsString==0) return;
599   printlex(yy_flex_debug, TRUE, __FILE__, NULL);
600
601   g_copyArgValue=0;
602   g_curArgDocs.resize(0);
603   g_curArgAttrib.resize(0);
604   g_curArgArray.resize(0);
605   g_curTypeConstraint.resize(0);
606   g_extraTypeChars.resize(0);
607   g_argRoundCount = 0;
608   g_argSharpCount = 0;
609   g_argCurlyCount = 0;
610   g_lastDocChar = 0;
611
612   g_inputString   = argsString;
613   g_inputPosition = 0;
614   g_curArgTypeName.resize(0);
615   g_curArgDefValue.resize(0);
616   g_curArgName.resize(0);
617   g_argList = al;
618   defargsYYrestart( defargsYYin );
619   BEGIN( Start );
620   defargsYYlex();
621   if (extraTypeChars) *extraTypeChars=g_extraTypeChars;
622   //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data());
623   printlex(yy_flex_debug, FALSE, __FILE__, NULL);
624 }
625
626 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
627 extern "C" { // some bogus code to keep the compiler happy
628   void defargsYYdummy() { yy_flex_realloc(0,0); } 
629 }
630 #endif
631