Orb/Doxygen/src/defargs.l
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 /*! \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 
       
    43 %{
       
    44 
       
    45 /*
       
    46  *	includes
       
    47  */
       
    48 #include "qtbc.h"
       
    49 #include <stdio.h>
       
    50 //#include <iostream.h>
       
    51 #include <assert.h>
       
    52 #include <ctype.h>
       
    53 #include <qregexp.h>
       
    54 
       
    55 #include "defargs.h"
       
    56 #include "entry.h"
       
    57 #include "util.h"
       
    58   
       
    59 #define YY_NEVER_INTERACTIVE 1
       
    60   
       
    61 /* -----------------------------------------------------------------
       
    62  *	state variables
       
    63  */
       
    64 static const char      *g_inputString;
       
    65 static int	        g_inputPosition;
       
    66 static ArgumentList    *g_argList;
       
    67 static QCString        *g_copyArgValue;
       
    68 static QCString         g_curArgTypeName;
       
    69 static QCString         g_curArgDefValue;
       
    70 static QCString		g_curArgName;
       
    71 static QCString		g_curArgDocs;
       
    72 static QCString		g_curArgAttrib;
       
    73 static QCString		g_curArgArray;
       
    74 static QCString		g_extraTypeChars;
       
    75 static int              g_argRoundCount;
       
    76 static int              g_argSharpCount;
       
    77 static int              g_argCurlyCount;
       
    78 static int              g_readArgContext;
       
    79 static int              g_lastDocContext;
       
    80 static int              g_lastDocChar;
       
    81 
       
    82 /* -----------------------------------------------------------------
       
    83  */
       
    84 #undef	YY_INPUT
       
    85 #define	YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
       
    86 
       
    87 static int yyread(char *buf,int max_size)
       
    88 {
       
    89     int c=0;
       
    90     while( c < max_size && g_inputString[g_inputPosition] )
       
    91     {
       
    92 	*buf = g_inputString[g_inputPosition++] ;
       
    93 	c++; buf++;
       
    94     }
       
    95     return c;
       
    96 }
       
    97 
       
    98 %}
       
    99 
       
   100 B       [ \t]
       
   101 ID	[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
       
   102 
       
   103 %option noyywrap
       
   104 
       
   105 %x      Start
       
   106 %x      CopyArgString
       
   107 %x	CopyArgRound
       
   108 %x	CopyArgRound2
       
   109 %x	CopyArgSharp
       
   110 %x	CopyArgCurly
       
   111 %x	ReadFuncArgType
       
   112 %x	ReadFuncArgDef
       
   113 %x	ReadFuncArgPtr
       
   114 %x	FuncQual
       
   115 %x	ReadDocBlock
       
   116 %x	ReadDocLine
       
   117 
       
   118 
       
   119 %%
       
   120 
       
   121 <Start>[<(]				{ BEGIN(ReadFuncArgType); }
       
   122 
       
   123 <ReadFuncArgType>{B}*			{
       
   124   					  g_curArgTypeName+=" ";
       
   125   					}
       
   126 <ReadFuncArgType>"["[^\]]*"]"		{ 
       
   127 					  if (g_curArgTypeName.stripWhiteSpace().isEmpty())
       
   128 					  {
       
   129 					    g_curArgAttrib=yytext; // for M$-IDL
       
   130 					  }
       
   131 					  else // array type
       
   132 					  {
       
   133 					    g_curArgArray+=yytext;
       
   134 					  }
       
   135 					}
       
   136 <ReadFuncArgDef>"'"\\[0-7]{1,3}"'"	{ g_curArgDefValue+=yytext; }
       
   137 <ReadFuncArgDef>"'"\\."'"		{ g_curArgDefValue+=yytext; }
       
   138 <ReadFuncArgDef>"'"."'"			{ g_curArgDefValue+=yytext; }
       
   139 <ReadFuncArgDef>\"			{
       
   140   					  g_curArgDefValue+=*yytext;
       
   141   					  BEGIN( CopyArgString );
       
   142   					}
       
   143 <ReadFuncArgType>"("([^:)]+{B}*"::")*{B}*[&*]+{B}*/{ID} { 
       
   144   					  // function pointer as argument
       
   145 					  g_curArgTypeName+=yytext;
       
   146 					  //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
       
   147 					  BEGIN( ReadFuncArgPtr );
       
   148   					}
       
   149 <ReadFuncArgPtr>{ID}			{
       
   150 					  g_curArgName=yytext;
       
   151   					}
       
   152 <ReadFuncArgPtr>")"{B}*"("		{ // function pointer
       
   153 					  g_curArgTypeName+=yytext;
       
   154 					  //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
       
   155 					  g_readArgContext = ReadFuncArgType;
       
   156 					  g_copyArgValue=&g_curArgTypeName;
       
   157 					  g_argRoundCount=0;
       
   158 					  BEGIN( CopyArgRound2 );
       
   159 					}
       
   160 <ReadFuncArgPtr>")"/{B}*"["		{ // pointer to fixed size array
       
   161 					  g_curArgTypeName+=yytext;
       
   162 					  g_curArgTypeName+=g_curArgName;
       
   163 					  //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
       
   164 					  BEGIN( ReadFuncArgType );
       
   165 					}
       
   166 <ReadFuncArgPtr>")"			{ // redundant braces detected / remove them
       
   167 					  int i=g_curArgTypeName.findRev('('),l=g_curArgTypeName.length();
       
   168 					  if (i!=-1)
       
   169 					    g_curArgTypeName=g_curArgTypeName.left(i)+
       
   170 					                   g_curArgTypeName.right(l-i-1);
       
   171 					  g_curArgTypeName+=g_curArgName;
       
   172 					  BEGIN( ReadFuncArgType );
       
   173 					}
       
   174 <ReadFuncArgType>"<="|">="|"->"|">>"|"<<" { // handle operators in defargs
       
   175   					  g_curArgTypeName+=yytext;
       
   176   					}
       
   177 <ReadFuncArgType,ReadFuncArgDef>[({<]	{	 
       
   178 					  if (YY_START==ReadFuncArgType)
       
   179 					  {
       
   180 					    g_curArgTypeName+=*yytext;
       
   181 					    g_copyArgValue=&g_curArgTypeName;
       
   182 					  }
       
   183 					  else // YY_START==ReadFuncArgDef
       
   184 					  {
       
   185 					    g_curArgDefValue+=*yytext;
       
   186 					    g_copyArgValue=&g_curArgDefValue;
       
   187 					  }
       
   188 					  g_readArgContext = YY_START; 
       
   189 					  if (*yytext=='(')
       
   190 					  {
       
   191 					    g_argRoundCount=0; 
       
   192 					    BEGIN( CopyArgRound ); 
       
   193 					  }
       
   194 					  else if (*yytext=='{')
       
   195 					  {
       
   196 					    g_argCurlyCount=0; 
       
   197 					    BEGIN( CopyArgCurly ); 
       
   198 					  }
       
   199 					  else // yytext=='<'
       
   200 					  {
       
   201 					    g_argSharpCount=0; 
       
   202 					    BEGIN( CopyArgSharp ); 
       
   203 					  }
       
   204 					}
       
   205 <CopyArgRound,CopyArgRound2>"("		{
       
   206   					  g_argRoundCount++;
       
   207 					  *g_copyArgValue += *yytext;
       
   208   					}
       
   209 <CopyArgRound,CopyArgRound2>")"({B}*{ID})* {
       
   210 					  *g_copyArgValue += yytext;
       
   211 					  if (g_argRoundCount>0) 
       
   212 					  {
       
   213 					    g_argRoundCount--;
       
   214 					  }
       
   215 					  else 
       
   216 					  {
       
   217 					    if (YY_START==CopyArgRound2)
       
   218 					    {
       
   219 					      *g_copyArgValue+=" "+g_curArgName;
       
   220 					    }
       
   221 					    BEGIN( g_readArgContext );
       
   222 					  }
       
   223   					}
       
   224 <CopyArgSharp>"<"			{
       
   225   					  g_argSharpCount++;
       
   226 					  *g_copyArgValue += *yytext;
       
   227   					}
       
   228 <CopyArgSharp>">"			{
       
   229 					  *g_copyArgValue += *yytext;
       
   230 					  if (g_argSharpCount>0) g_argSharpCount--;
       
   231 					  else BEGIN( g_readArgContext );
       
   232   					}
       
   233 <CopyArgCurly>"{"			{
       
   234   					  g_argCurlyCount++;
       
   235 					  *g_copyArgValue += *yytext;
       
   236   					}
       
   237 <CopyArgSharp>"}"			{
       
   238 					  *g_copyArgValue += *yytext;
       
   239 					  if (g_argCurlyCount>0) g_argCurlyCount--;
       
   240 					  else BEGIN( g_readArgContext );
       
   241   					}
       
   242 <CopyArgString>\\.			{
       
   243 					  g_curArgDefValue+=yytext;
       
   244   					}
       
   245 <CopyArgString>\"			{
       
   246 					  g_curArgDefValue+=*yytext;
       
   247 					  BEGIN( ReadFuncArgDef );
       
   248   					}
       
   249 <ReadFuncArgType>"="			{
       
   250 					  BEGIN( ReadFuncArgDef );
       
   251   					}
       
   252 <ReadFuncArgType,ReadFuncArgDef>[,)>]{B}*("/*"[*!]|"//"[/!])"<" {
       
   253 					  g_lastDocContext=YY_START;
       
   254 					  g_lastDocChar=*yytext;  
       
   255 					  QCString text=yytext;
       
   256 					  if (text.find("//")!=-1)
       
   257 					    BEGIN( ReadDocLine );
       
   258 					  else
       
   259 					    BEGIN( ReadDocBlock );
       
   260   					}
       
   261 <ReadFuncArgType,ReadFuncArgDef>[,)>]	{
       
   262   					  if (*yytext==')' && g_curArgTypeName.stripWhiteSpace().isEmpty())
       
   263 					  {
       
   264 					    g_curArgTypeName+=*yytext;
       
   265 					    BEGIN(FuncQual);
       
   266 					  }
       
   267 					  else
       
   268 					  {
       
   269 					    g_curArgTypeName=removeRedundantWhiteSpace(g_curArgTypeName);
       
   270 					    g_curArgDefValue=g_curArgDefValue.stripWhiteSpace();
       
   271 					    //printf("curArgType=`%s' curArgDefVal=`%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data());
       
   272 					    int l=g_curArgTypeName.length();
       
   273 					    if (l>0)
       
   274 					    {
       
   275 					      int i=l-1;
       
   276 					      while (i>=0 && (isspace((uchar)g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--;
       
   277 					      while (i>=0 && isId(g_curArgTypeName.at(i))) i--;
       
   278 					      //printf("g_curArgTypeName=`%s' i=%d\n",g_curArgTypeName.data(),i);
       
   279 					      Argument *a = new Argument; 
       
   280 					      a->attrib = g_curArgAttrib.copy();
       
   281 					      //printf("a->type=%s a->name=%s i=%d l=%d\n",
       
   282 					      //	a->type.data(),a->name.data(),i,l);
       
   283 					      a->array.resize(0);
       
   284 					      if (i==l-1 && g_curArgTypeName.at(i)==')') // function argument
       
   285 					      {
       
   286 						int bi=g_curArgTypeName.find('(');
       
   287 						int fi=bi-1;
       
   288 						//printf("func arg fi=%d\n",fi);
       
   289 						while (fi>=0 && isId(g_curArgTypeName.at(fi))) fi--;
       
   290 						if (fi>=0)
       
   291 						{
       
   292 						  a->type  = g_curArgTypeName.left(fi+1);
       
   293 						  a->name  = g_curArgTypeName.mid(fi+1,bi-fi-1).stripWhiteSpace();
       
   294 						  a->array = g_curArgTypeName.right(l-bi);
       
   295 						}
       
   296 						else
       
   297 						{
       
   298 						  a->type = g_curArgTypeName;
       
   299 						}
       
   300 					      }
       
   301 					      else if (i>=0 && g_curArgTypeName.at(i)!=':')
       
   302 					      { // type contains a name
       
   303 						a->type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1));
       
   304 						a->name = g_curArgTypeName.right(l-i-1).stripWhiteSpace();
       
   305 
       
   306 						// if the type becomes a type specifier only then we make a mistake
       
   307 						// and need to correct it to avoid seeing a nameless parameter
       
   308 						// "struct A" as a parameter with type "struct" and name "A".
       
   309 						int sv=0;
       
   310 						if (a->type.left(6)=="const ") sv=6;
       
   311 						else if (a->type.left(8)=="volatile ") sv=9;
       
   312 						if (a->type.mid(sv)=="struct"    || 
       
   313 						    a->type.mid(sv)=="union"     || 
       
   314 						    a->type.mid(sv)=="class"     || 
       
   315 						    a->type.mid(sv)=="typename"  || 
       
   316 						    a->type=="const" || a->type=="volatile")
       
   317 						{ 
       
   318 						  a->type = a->type + " " + a->name;
       
   319 						  a->name.resize(0);
       
   320 						}
       
   321 					      }
       
   322 					      else // assume only the type was specified, try to determine name later 
       
   323 					      {
       
   324 						a->type = removeRedundantWhiteSpace(g_curArgTypeName);  
       
   325 					      }
       
   326 					      a->array  += removeRedundantWhiteSpace(g_curArgArray);
       
   327 					      //printf("array=%s\n",a->array.data());
       
   328 					      int alen = a->array.length();
       
   329 					      if (alen>2 && a->array.at(0)=='(' && 
       
   330 						            a->array.at(alen-1)==')') // fix-up for int *(a[10])
       
   331 					      {
       
   332 						int i=a->array.find('[')-1;
       
   333 						a->array = a->array.mid(1,alen-2);
       
   334 						if (i>0 && a->name.isEmpty())
       
   335 						{
       
   336 						  a->name  = a->array.left(i).stripWhiteSpace();
       
   337 						  a->array = a->array.mid(i);
       
   338 						}
       
   339 					      }
       
   340 					      a->defval = g_curArgDefValue.copy();
       
   341 					      //printf("a->type=%s a->name=%s a->defval=\"%s\"\n",a->type.data(),a->name.data(),a->defval.data());
       
   342 					      a->docs   = g_curArgDocs.stripWhiteSpace();
       
   343 					      //printf("Argument `%s' `%s' adding docs=`%s'\n",a->type.data(),a->name.data(),a->docs.data());
       
   344 					      g_argList->append(a);
       
   345 					    }
       
   346 					    g_curArgAttrib.resize(0);
       
   347 					    g_curArgTypeName.resize(0);
       
   348 					    g_curArgDefValue.resize(0);
       
   349 					    g_curArgArray.resize(0);
       
   350 					    g_curArgDocs.resize(0);
       
   351 					    if (*yytext==')')
       
   352 					    {
       
   353 					      BEGIN(FuncQual);
       
   354 					      //printf(">>> end of argument list\n");
       
   355 					    }
       
   356 					    else
       
   357 					    {
       
   358 					      BEGIN( ReadFuncArgType );
       
   359 					    }
       
   360 					  }
       
   361   					}
       
   362 <ReadFuncArgType,ReadFuncArgPtr>{ID}	{ 
       
   363   					  QCString name=yytext; //resolveDefines(yytext);
       
   364 					  if (YY_START==ReadFuncArgType && g_curArgArray=="[]") // Java style array
       
   365 					  {
       
   366 					    g_curArgTypeName+=" []";
       
   367 					    g_curArgArray.resize(0);
       
   368 					  }
       
   369 					  //printf("resolveName `%s'->`%s'\n",yytext,name.data());
       
   370   					  g_curArgTypeName+=name;
       
   371 					}
       
   372 <ReadFuncArgType,ReadFuncArgPtr>.	{ 
       
   373   					  g_curArgTypeName+=*yytext;
       
   374 					}
       
   375 
       
   376 <ReadFuncArgDef,CopyArgString>"->"|">="|">>"	{
       
   377   					  g_curArgDefValue+=yytext;
       
   378   					}
       
   379 <ReadFuncArgDef,CopyArgString>.		{
       
   380 					  g_curArgDefValue+=*yytext;
       
   381   					}
       
   382 <CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>{ID}  {
       
   383   					  QCString name=yytext; //resolveDefines(yytext);
       
   384 					  *g_copyArgValue+=name;
       
   385 					}
       
   386 <CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>.  {
       
   387 					  *g_copyArgValue += *yytext;
       
   388 					}
       
   389 <FuncQual>"const"		       	{ 
       
   390 					  g_argList->constSpecifier=TRUE;
       
   391 					}
       
   392 <FuncQual>"volatile"		    	{ 
       
   393 					  g_argList->volatileSpecifier=TRUE;
       
   394 					}
       
   395 <FuncQual>"="{B}*"0"		  	{ 
       
   396 					  g_argList->pureSpecifier=TRUE;
       
   397 					}
       
   398 <FuncQual>")"{B}*"["[^]]*"]"		{ // for functions returning a pointer to an array, 
       
   399                                           // i.e. ")[]" in "int (*f(int))[4]" with argsString="(int))[4]"
       
   400   					  g_extraTypeChars=yytext;
       
   401   					}
       
   402 <ReadDocBlock>[^\*\n]+			{
       
   403   					  g_curArgDocs+=yytext;
       
   404   					}
       
   405 <ReadDocLine>[^\n]+			{
       
   406   					  g_curArgDocs+=yytext;
       
   407   					}
       
   408 <ReadDocBlock>"*/"			{ 
       
   409   					  if (g_lastDocChar!=0)
       
   410 					    unput(g_lastDocChar);
       
   411   					  BEGIN(g_lastDocContext); 
       
   412 					}
       
   413 <ReadDocLine>\n				{
       
   414   					  if (g_lastDocChar!=0)
       
   415 					    unput(g_lastDocChar);
       
   416 					  BEGIN(g_lastDocContext);
       
   417   					}
       
   418 <ReadDocBlock>\n			{
       
   419   					  g_curArgDocs+=*yytext;
       
   420   					}
       
   421 <ReadDocBlock>.				{
       
   422   					  g_curArgDocs+=*yytext;
       
   423   					}
       
   424 <*>("/*"[*!]|"//"[/!])("<"?)		{
       
   425   					  g_lastDocContext=YY_START;
       
   426 					  g_lastDocChar=0;  
       
   427 					  if (yytext[1]=='/')
       
   428 					    BEGIN( ReadDocLine );
       
   429 					  else
       
   430   					    BEGIN( ReadDocBlock );
       
   431   					}
       
   432 <*>\n
       
   433 <*>.
       
   434 
       
   435 %%
       
   436 
       
   437 /* ----------------------------------------------------------------------------
       
   438  */
       
   439 
       
   440 /*! Converts an argument string into an ArgumentList.
       
   441  *  \param argsString the list of Arguments.
       
   442  *  \param al a reference to resulting argument list pointer.
       
   443  */
       
   444  
       
   445 void stringToArgumentList(const char *argsString,ArgumentList* al,QCString *extraTypeChars)
       
   446 {
       
   447   if (al==0) return; 
       
   448   if (argsString==0) return;
       
   449 
       
   450   g_copyArgValue=0;
       
   451   g_curArgDocs.resize(0);
       
   452   g_curArgAttrib.resize(0);
       
   453   g_curArgArray.resize(0);
       
   454   g_extraTypeChars.resize(0);
       
   455   g_argRoundCount = 0;
       
   456   g_argSharpCount = 0;
       
   457   g_argCurlyCount = 0;
       
   458   g_lastDocChar = 0;
       
   459 
       
   460   g_inputString   = argsString;
       
   461   g_inputPosition = 0;
       
   462   g_curArgTypeName.resize(0);
       
   463   g_curArgDefValue.resize(0);
       
   464   g_curArgName.resize(0);
       
   465   g_argList = al;
       
   466   defargsYYrestart( defargsYYin );
       
   467   BEGIN( Start );
       
   468   defargsYYlex();
       
   469   if (extraTypeChars) *extraTypeChars=g_extraTypeChars;
       
   470   //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data());
       
   471 }
       
   472 
       
   473 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
       
   474 extern "C" { // some bogus code to keep the compiler happy
       
   475   void defargsYYdummy() { yy_flex_realloc(0,0); } 
       
   476 }
       
   477 #endif
       
   478