Blame src/defargs.l

Packit 1c1d7e
/******************************************************************************
Packit 1c1d7e
 *
Packit 1c1d7e
 * 
Packit 1c1d7e
 *
Packit 1c1d7e
 * Copyright (C) 1997-2015 by Dimitri van Heesch.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Permission to use, copy, modify, and distribute this software and its
Packit 1c1d7e
 * documentation under the terms of the GNU General Public License is hereby 
Packit 1c1d7e
 * granted. No representations are made about the suitability of this software 
Packit 1c1d7e
 * for any purpose. It is provided "as is" without express or implied warranty.
Packit 1c1d7e
 * See the GNU General Public License for more details.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Documents produced by Doxygen are derivative works derived from the
Packit 1c1d7e
 * input used in their production; they are not affected by this license.
Packit 1c1d7e
 *
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
/*! \file
Packit 1c1d7e
 *  This scanner is used to convert a string into a list of function or 
Packit 1c1d7e
 *  template arguments. Each parsed argument results in a Argument struct,
Packit 1c1d7e
 *  that is put into an ArgumentList in declaration order.
Packit 1c1d7e
 *  Comment blocks for arguments can also be included in the string.
Packit 1c1d7e
 *  The argument string does not contain new-lines (except inside any
Packit 1c1d7e
 *  comment blocks).
Packit 1c1d7e
 *  An Argument consists of the string fields: 
Packit 1c1d7e
 *                 type,name,default value, and documentation
Packit 1c1d7e
 *  The Argument list as a whole can be pure, constant or volatile.
Packit 1c1d7e
 *
Packit 1c1d7e
 *  Examples of input strings are:
Packit 1c1d7e
 *  \code
Packit 1c1d7e
 *    "(int a,int b) const"
Packit 1c1d7e
 *    "(const char *s="hello world",int=5) = 0"
Packit 1c1d7e
 *    "<class T,class N>"
Packit 1c1d7e
 *    "(char c,const char)"
Packit 1c1d7e
 *  \endcode
Packit 1c1d7e
 *
Packit 1c1d7e
 *  Note: It is not always possible to distinguish between the name and 
Packit 1c1d7e
 *        type of an argument. In case of doubt the name is added to the
Packit 1c1d7e
 *        type, and the matchArgumentList in util.cpp is be used to
Packit 1c1d7e
 *        further determine the correct separation.
Packit 1c1d7e
 */
Packit 1c1d7e
%option never-interactive
Packit 1c1d7e
%option prefix="defargsYY"
Packit 1c1d7e
Packit 1c1d7e
%{
Packit 1c1d7e
Packit 1c1d7e
/*
Packit 1c1d7e
 *	includes
Packit 1c1d7e
 */
Packit 1c1d7e
#include <stdio.h>
Packit 1c1d7e
//#include <iostream.h>
Packit 1c1d7e
#include <assert.h>
Packit 1c1d7e
#include <ctype.h>
Packit 1c1d7e
#include <qregexp.h>
Packit 1c1d7e
Packit 1c1d7e
#include "defargs.h"
Packit 1c1d7e
#include "entry.h"
Packit 1c1d7e
#include "util.h"
Packit 1c1d7e
#include "arguments.h"
Packit 1c1d7e
#include "message.h"
Packit 1c1d7e
  
Packit 1c1d7e
#define YY_NO_INPUT 1
Packit 1c1d7e
#define YY_NO_UNISTD_H 1
Packit 1c1d7e
  
Packit 1c1d7e
/* -----------------------------------------------------------------
Packit 1c1d7e
 *	state variables
Packit 1c1d7e
 */
Packit 1c1d7e
static const char      *g_inputString;
Packit 1c1d7e
static int	        g_inputPosition;
Packit 1c1d7e
static ArgumentList    *g_argList;
Packit 1c1d7e
static QCString        *g_copyArgValue;
Packit 1c1d7e
static QCString         g_curArgTypeName;
Packit 1c1d7e
static QCString         g_curArgDefValue;
Packit 1c1d7e
static QCString		g_curArgName;
Packit 1c1d7e
static QCString		g_curArgDocs;
Packit 1c1d7e
static QCString		g_curArgAttrib;
Packit 1c1d7e
static QCString		g_curArgArray;
Packit 1c1d7e
static QCString         g_curTypeConstraint;
Packit 1c1d7e
static QCString		g_extraTypeChars;
Packit 1c1d7e
static int              g_argRoundCount;
Packit 1c1d7e
static int              g_argSharpCount;
Packit 1c1d7e
static int              g_argCurlyCount;
Packit 1c1d7e
static int              g_readArgContext;
Packit 1c1d7e
static int              g_lastDocContext;
Packit 1c1d7e
static int              g_lastDocChar;
Packit 1c1d7e
static int              g_lastExtendsContext;
Packit 1c1d7e
static QCString         g_delimiter;
Packit 1c1d7e
Packit 1c1d7e
/* -----------------------------------------------------------------
Packit 1c1d7e
 */
Packit 1c1d7e
#undef	YY_INPUT
Packit 1c1d7e
#define	YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
Packit 1c1d7e
Packit 1c1d7e
static int yyread(char *buf,int max_size)
Packit 1c1d7e
{
Packit 1c1d7e
    int c=0;
Packit 1c1d7e
    while( c < max_size && g_inputString[g_inputPosition] )
Packit 1c1d7e
    {
Packit 1c1d7e
	*buf = g_inputString[g_inputPosition++] ;
Packit 1c1d7e
	c++; buf++;
Packit 1c1d7e
    }
Packit 1c1d7e
    return c;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
%}
Packit 1c1d7e
Packit 1c1d7e
B       [ \t]
Packit 1c1d7e
ID	[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
Packit 1c1d7e
RAWBEGIN  (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
Packit 1c1d7e
RAWEND    ")"[^ \t\(\)\\]{0,16}\"
Packit 1c1d7e
Packit 1c1d7e
%option noyywrap
Packit 1c1d7e
Packit 1c1d7e
%x      Start
Packit 1c1d7e
%x      CopyArgString
Packit 1c1d7e
%x      CopyRawString
Packit 1c1d7e
%x	CopyArgRound
Packit 1c1d7e
%x	CopyArgRound2
Packit 1c1d7e
%x	CopyArgSharp
Packit 1c1d7e
%x	CopyArgCurly
Packit 1c1d7e
%x	ReadFuncArgType
Packit 1c1d7e
%x	ReadFuncArgDef
Packit 1c1d7e
%x	ReadFuncArgPtr
Packit 1c1d7e
%x	FuncQual
Packit 1c1d7e
%x	ReadDocBlock
Packit 1c1d7e
%x	ReadDocLine
Packit 1c1d7e
%x      ReadTypeConstraint
Packit 1c1d7e
%x      TrailingReturn
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
%%
Packit 1c1d7e
Packit 1c1d7e
<Start>[<(]				{ BEGIN(ReadFuncArgType); }
Packit 1c1d7e
Packit 1c1d7e
<ReadFuncArgType>{B}*			{
Packit 1c1d7e
  					  g_curArgTypeName+=" ";
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgType>"["[^\]]*"]"		{ 
Packit 1c1d7e
					  if (g_curArgTypeName.stripWhiteSpace().isEmpty())
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_curArgAttrib=yytext; // for M$-IDL
Packit 1c1d7e
					  }
Packit 1c1d7e
					  else // array type
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_curArgArray+=yytext;
Packit 1c1d7e
					  }
Packit 1c1d7e
					}
Packit 1c1d7e
<ReadFuncArgDef>"'"\\[0-7]{1,3}"'"	{ g_curArgDefValue+=yytext; }
Packit 1c1d7e
<ReadFuncArgDef>"'"\\."'"		{ g_curArgDefValue+=yytext; }
Packit 1c1d7e
<ReadFuncArgDef>"'"."'"			{ g_curArgDefValue+=yytext; }
Packit 1c1d7e
<ReadFuncArgDef>{RAWBEGIN}              { g_curArgDefValue+=yytext; 
Packit 1c1d7e
                                          QCString text=yytext;
Packit 1c1d7e
                                          int i=text.find('"');
Packit 1c1d7e
                                          g_delimiter = yytext+i+1;
Packit 1c1d7e
                                          g_delimiter=g_delimiter.left(g_delimiter.length()-1);
Packit 1c1d7e
                                          BEGIN( CopyRawString );
Packit 1c1d7e
                                        }
Packit 1c1d7e
<ReadFuncArgDef>\"			{
Packit 1c1d7e
  					  g_curArgDefValue+=*yytext;
Packit 1c1d7e
  					  BEGIN( CopyArgString );
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgType>"("([^:)]+{B}*"::")*{B}*[&*\^]+{B}*/{ID} { 
Packit 1c1d7e
  					  // function pointer as argument
Packit 1c1d7e
					  g_curArgTypeName+=yytext;
Packit 1c1d7e
					  //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
Packit 1c1d7e
					  BEGIN( ReadFuncArgPtr );
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgPtr>{ID}			{
Packit 1c1d7e
					  g_curArgName=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgPtr>")"{B}*"("		{ // function pointer
Packit 1c1d7e
					  g_curArgTypeName+=yytext;
Packit 1c1d7e
					  //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
Packit 1c1d7e
					  g_readArgContext = ReadFuncArgType;
Packit 1c1d7e
					  g_copyArgValue=&g_curArgTypeName;
Packit 1c1d7e
					  g_argRoundCount=0;
Packit 1c1d7e
					  BEGIN( CopyArgRound2 );
Packit 1c1d7e
					}
Packit 1c1d7e
<ReadFuncArgPtr>")"/{B}*"["		{ // pointer to fixed size array
Packit 1c1d7e
					  g_curArgTypeName+=yytext;
Packit 1c1d7e
					  g_curArgTypeName+=g_curArgName;
Packit 1c1d7e
					  //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace();
Packit 1c1d7e
					  BEGIN( ReadFuncArgType );
Packit 1c1d7e
					}
Packit 1c1d7e
<ReadFuncArgPtr>")"			{ // redundant braces detected / remove them
Packit 1c1d7e
					  int i=g_curArgTypeName.findRev('('),l=g_curArgTypeName.length();
Packit 1c1d7e
					  if (i!=-1)
Packit 1c1d7e
					    g_curArgTypeName=g_curArgTypeName.left(i)+
Packit 1c1d7e
					                   g_curArgTypeName.right(l-i-1);
Packit 1c1d7e
					  g_curArgTypeName+=g_curArgName;
Packit 1c1d7e
					  BEGIN( ReadFuncArgType );
Packit 1c1d7e
					}
Packit 1c1d7e
<ReadFuncArgType>"<="|">="|"->"|">>"|"<<" { // handle operators in defargs
Packit 1c1d7e
  					  g_curArgTypeName+=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgType,ReadFuncArgDef>[({<]	{	 
Packit 1c1d7e
					  if (YY_START==ReadFuncArgType)
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_curArgTypeName+=*yytext;
Packit 1c1d7e
					    g_copyArgValue=&g_curArgTypeName;
Packit 1c1d7e
					  }
Packit 1c1d7e
					  else // YY_START==ReadFuncArgDef
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_curArgDefValue+=*yytext;
Packit 1c1d7e
					    g_copyArgValue=&g_curArgDefValue;
Packit 1c1d7e
					  }
Packit 1c1d7e
					  g_readArgContext = YY_START; 
Packit 1c1d7e
					  if (*yytext=='(')
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_argRoundCount=0; 
Packit 1c1d7e
					    BEGIN( CopyArgRound ); 
Packit 1c1d7e
					  }
Packit 1c1d7e
					  else if (*yytext=='{')
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_argCurlyCount=0; 
Packit 1c1d7e
					    BEGIN( CopyArgCurly ); 
Packit 1c1d7e
					  }
Packit 1c1d7e
					  else // yytext=='<'
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_argSharpCount=0; 
Packit 1c1d7e
					    g_argRoundCount=0; 
Packit 1c1d7e
					    BEGIN( CopyArgSharp ); 
Packit 1c1d7e
					  }
Packit 1c1d7e
					}
Packit 1c1d7e
<CopyArgRound,CopyArgRound2>"("		{
Packit 1c1d7e
  					  g_argRoundCount++;
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyArgRound,CopyArgRound2>")"({B}*{ID})* {
Packit 1c1d7e
					  *g_copyArgValue += yytext;
Packit 1c1d7e
					  if (g_argRoundCount>0) 
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_argRoundCount--;
Packit 1c1d7e
					  }
Packit 1c1d7e
					  else 
Packit 1c1d7e
					  {
Packit 1c1d7e
					    if (YY_START==CopyArgRound2)
Packit 1c1d7e
					    {
Packit 1c1d7e
					      *g_copyArgValue+=" "+g_curArgName;
Packit 1c1d7e
					    }
Packit 1c1d7e
					    BEGIN( g_readArgContext );
Packit 1c1d7e
					  }
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyArgRound>")"/{B}*                  {
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
					  if (g_argRoundCount>0) g_argRoundCount--;
Packit 1c1d7e
					  else BEGIN( g_readArgContext );
Packit 1c1d7e
                                        }
Packit 1c1d7e
<CopyArgSharp>"<<"                      {
Packit 1c1d7e
                                          if (g_argRoundCount>0)
Packit 1c1d7e
                                          {
Packit 1c1d7e
					    *g_copyArgValue += yytext;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          else
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            REJECT;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                        }
Packit 1c1d7e
<CopyArgSharp>">>)"                     { // combined token (see bug 790320)
Packit 1c1d7e
					  *g_copyArgValue += yytext;
Packit 1c1d7e
					  if (g_argSharpCount>0) g_argSharpCount--;
Packit 1c1d7e
					  else BEGIN( g_readArgContext );
Packit 1c1d7e
					  if (g_argSharpCount>0) g_argSharpCount--;
Packit 1c1d7e
					  else BEGIN( g_readArgContext );
Packit 1c1d7e
                                          g_argRoundCount--;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<CopyArgSharp>">>"                      {
Packit 1c1d7e
                                          if (g_argRoundCount>0)
Packit 1c1d7e
                                          {
Packit 1c1d7e
					    *g_copyArgValue += yytext;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          else
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            REJECT;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                        }
Packit 1c1d7e
<CopyArgSharp>"<"			{
Packit 1c1d7e
  					  g_argSharpCount++;
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyArgSharp>">"			{
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
					  if (g_argSharpCount>0) g_argSharpCount--;
Packit 1c1d7e
					  else BEGIN( g_readArgContext );
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyArgSharp>"("                       {
Packit 1c1d7e
                                          g_argRoundCount++;
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<CopyArgSharp>")"                       {
Packit 1c1d7e
                                          g_argRoundCount--;
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<CopyArgCurly>"{"			{
Packit 1c1d7e
  					  g_argCurlyCount++;
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyArgCurly>"}"			{
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
					  if (g_argCurlyCount>0) g_argCurlyCount--;
Packit 1c1d7e
					  else BEGIN( g_readArgContext );
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyArgString>\\.			{
Packit 1c1d7e
					  g_curArgDefValue+=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyRawString>{RAWEND}                 {
Packit 1c1d7e
					  g_curArgDefValue+=yytext;
Packit 1c1d7e
                                          QCString delimiter = yytext+1;
Packit 1c1d7e
                                          delimiter=delimiter.left(delimiter.length()-1);
Packit 1c1d7e
                                          if (delimiter==g_delimiter)
Packit 1c1d7e
                                          {
Packit 1c1d7e
					    BEGIN( ReadFuncArgDef );
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                        }
Packit 1c1d7e
<CopyArgString>\"			{
Packit 1c1d7e
					  g_curArgDefValue+=*yytext;
Packit 1c1d7e
					  BEGIN( ReadFuncArgDef );
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgType>"="			{
Packit 1c1d7e
					  BEGIN( ReadFuncArgDef );
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgType,ReadFuncArgDef>[,)>]{B}*("/*"[*!]|"//"[/!])"<" {
Packit 1c1d7e
					  g_lastDocContext=YY_START;
Packit 1c1d7e
					  g_lastDocChar=*yytext;  
Packit 1c1d7e
					  QCString text=yytext;
Packit 1c1d7e
					  if (text.find("//")!=-1)
Packit 1c1d7e
					    BEGIN( ReadDocLine );
Packit 1c1d7e
					  else
Packit 1c1d7e
					    BEGIN( ReadDocBlock );
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgType,ReadFuncArgDef>[,)>]	{
Packit 1c1d7e
  					  if (*yytext==')' && g_curArgTypeName.stripWhiteSpace().isEmpty())
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_curArgTypeName+=*yytext;
Packit 1c1d7e
					    BEGIN(FuncQual);
Packit 1c1d7e
					  }
Packit 1c1d7e
					  else
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_curArgTypeName=removeRedundantWhiteSpace(g_curArgTypeName);
Packit 1c1d7e
					    g_curArgDefValue=g_curArgDefValue.stripWhiteSpace();
Packit 1c1d7e
					    //printf("curArgType=`%s' curArgDefVal=`%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data());
Packit 1c1d7e
					    int l=g_curArgTypeName.length();
Packit 1c1d7e
					    if (l>0)
Packit 1c1d7e
					    {
Packit 1c1d7e
					      int i=l-1;
Packit 1c1d7e
					      while (i>=0 && (isspace((uchar)g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--;
Packit 1c1d7e
					      while (i>=0 && (isId(g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='$')) i--;
Packit 1c1d7e
					      Argument *a = new Argument;
Packit 1c1d7e
					      a->attrib  = g_curArgAttrib.copy();
Packit 1c1d7e
                                              a->typeConstraint = g_curTypeConstraint.stripWhiteSpace();
Packit 1c1d7e
					      //printf("a->type=%s a->name=%s i=%d l=%d\n",
Packit 1c1d7e
					      //        a->type.data(),a->name.data(),i,l);
Packit 1c1d7e
					      a->array.resize(0);
Packit 1c1d7e
					      if (i==l-1 && g_curArgTypeName.at(i)==')') // function argument
Packit 1c1d7e
					      {
Packit 1c1d7e
						int bi=g_curArgTypeName.find('(');
Packit 1c1d7e
						int fi=bi-1;
Packit 1c1d7e
						//printf("func arg fi=%d\n",fi);
Packit 1c1d7e
						while (fi>=0 && (isId(g_curArgTypeName.at(fi)) || g_curArgTypeName.at(fi)==':')) fi--;
Packit 1c1d7e
						if (fi>=0)
Packit 1c1d7e
						{
Packit 1c1d7e
						  a->type  = g_curArgTypeName.left(fi+1);
Packit 1c1d7e
						  a->name  = g_curArgTypeName.mid(fi+1,bi-fi-1).stripWhiteSpace();
Packit 1c1d7e
						  a->array = g_curArgTypeName.right(l-bi);
Packit 1c1d7e
						}
Packit 1c1d7e
						else
Packit 1c1d7e
						{
Packit 1c1d7e
						  a->type = g_curArgTypeName;
Packit 1c1d7e
						}
Packit 1c1d7e
					      }
Packit 1c1d7e
					      else if (i>=0 && g_curArgTypeName.at(i)!=':')
Packit 1c1d7e
					      { // type contains a name
Packit 1c1d7e
						a->type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1)).stripWhiteSpace();
Packit 1c1d7e
						a->name = g_curArgTypeName.right(l-i-1).stripWhiteSpace();
Packit 1c1d7e
Packit 1c1d7e
						// if the type becomes a type specifier only then we make a mistake
Packit 1c1d7e
						// and need to correct it to avoid seeing a nameless parameter
Packit 1c1d7e
						// "struct A" as a parameter with type "struct" and name "A".
Packit 1c1d7e
						int sv=0;
Packit 1c1d7e
						if      (a->type.left(6)=="const ")    sv=6;
Packit 1c1d7e
						else if (a->type.left(9)=="volatile ") sv=9;
Packit 1c1d7e
Packit 1c1d7e
						if (a->type.mid(sv)=="struct"    ||
Packit 1c1d7e
						    a->type.mid(sv)=="union"     ||
Packit 1c1d7e
						    a->type.mid(sv)=="class"     ||
Packit 1c1d7e
						    a->type.mid(sv)=="typename"  ||
Packit 1c1d7e
						    a->type=="const"               ||
Packit 1c1d7e
						    a->type=="volatile"
Packit 1c1d7e
						   )
Packit 1c1d7e
						{ 
Packit 1c1d7e
						  a->type = a->type + " " + a->name;
Packit 1c1d7e
						  a->name.resize(0);
Packit 1c1d7e
						}
Packit 1c1d7e
						//printf(" --> a->type='%s' a->name='%s'\n",a->type.data(),a->name.data());
Packit 1c1d7e
					      }
Packit 1c1d7e
					      else // assume only the type was specified, try to determine name later 
Packit 1c1d7e
					      {
Packit 1c1d7e
						a->type = removeRedundantWhiteSpace(g_curArgTypeName);  
Packit 1c1d7e
					      }
Packit 1c1d7e
                                              if (!a->type.isEmpty() && a->type.at(0)=='$') // typeless PHP name?
Packit 1c1d7e
                                              {
Packit 1c1d7e
                                                a->name = a->type;
Packit 1c1d7e
                                                a->type = "";
Packit 1c1d7e
                                              }
Packit 1c1d7e
					      a->array  += removeRedundantWhiteSpace(g_curArgArray);
Packit 1c1d7e
					      //printf("array=%s\n",a->array.data());
Packit 1c1d7e
					      int alen = a->array.length();
Packit 1c1d7e
					      if (alen>2 && a->array.at(0)=='(' && 
Packit 1c1d7e
						            a->array.at(alen-1)==')') // fix-up for int *(a[10])
Packit 1c1d7e
					      {
Packit 1c1d7e
						int i=a->array.find('[')-1;
Packit 1c1d7e
						a->array = a->array.mid(1,alen-2);
Packit 1c1d7e
						if (i>0 && a->name.isEmpty())
Packit 1c1d7e
						{
Packit 1c1d7e
						  a->name  = a->array.left(i).stripWhiteSpace();
Packit 1c1d7e
						  a->array = a->array.mid(i);
Packit 1c1d7e
						}
Packit 1c1d7e
					      }
Packit 1c1d7e
					      a->defval = g_curArgDefValue.copy();
Packit 1c1d7e
					      //printf("a->type=%s a->name=%s a->defval=\"%s\"\n",a->type.data(),a->name.data(),a->defval.data());
Packit 1c1d7e
					      a->docs   = g_curArgDocs.stripWhiteSpace();
Packit 1c1d7e
					      //printf("Argument `%s' `%s' adding docs=`%s'\n",a->type.data(),a->name.data(),a->docs.data());
Packit 1c1d7e
					      g_argList->append(a);
Packit 1c1d7e
					    }
Packit 1c1d7e
					    g_curArgAttrib.resize(0);
Packit 1c1d7e
					    g_curArgTypeName.resize(0);
Packit 1c1d7e
					    g_curArgDefValue.resize(0);
Packit 1c1d7e
					    g_curArgArray.resize(0);
Packit 1c1d7e
					    g_curArgDocs.resize(0);
Packit 1c1d7e
                                            g_curTypeConstraint.resize(0);
Packit 1c1d7e
					    if (*yytext==')')
Packit 1c1d7e
					    {
Packit 1c1d7e
					      BEGIN(FuncQual);
Packit 1c1d7e
					      //printf(">>> end of argument list\n");
Packit 1c1d7e
					    }
Packit 1c1d7e
					    else
Packit 1c1d7e
					    {
Packit 1c1d7e
					      BEGIN( ReadFuncArgType );
Packit 1c1d7e
					    }
Packit 1c1d7e
					  }
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgType,ReadFuncArgPtr>"extends" {
Packit 1c1d7e
                                          g_curTypeConstraint.resize(0);
Packit 1c1d7e
                                          g_lastExtendsContext=YY_START;
Packit 1c1d7e
                                          BEGIN(ReadTypeConstraint);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<ReadFuncArgType,ReadFuncArgPtr>"$"?{ID} { 
Packit 1c1d7e
  					  QCString name=yytext; //resolveDefines(yytext);
Packit 1c1d7e
					  if (YY_START==ReadFuncArgType && g_curArgArray=="[]") // Java style array
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_curArgTypeName+=" []";
Packit 1c1d7e
					    g_curArgArray.resize(0);
Packit 1c1d7e
					  }
Packit 1c1d7e
					  //printf("resolveName `%s'->`%s'\n",yytext,name.data());
Packit 1c1d7e
  					  g_curArgTypeName+=name;
Packit 1c1d7e
					}
Packit 1c1d7e
<ReadFuncArgType,ReadFuncArgPtr>.	{ 
Packit 1c1d7e
  					  g_curArgTypeName+=*yytext;
Packit 1c1d7e
					}
Packit 1c1d7e
Packit 1c1d7e
<ReadFuncArgDef,CopyArgString>"<="|"->"|">="|">>"|"<<"	{
Packit 1c1d7e
  					  g_curArgDefValue+=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadFuncArgDef,CopyArgString,CopyRawString>.		{
Packit 1c1d7e
					  g_curArgDefValue+=*yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>{ID}  {
Packit 1c1d7e
  					  QCString name=yytext; //resolveDefines(yytext);
Packit 1c1d7e
					  *g_copyArgValue+=name;
Packit 1c1d7e
					}
Packit 1c1d7e
<CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>.  {
Packit 1c1d7e
					  *g_copyArgValue += *yytext;
Packit 1c1d7e
					}
Packit 1c1d7e
<ReadTypeConstraint>[,)>]               {
Packit 1c1d7e
                                          unput(*yytext);
Packit 1c1d7e
                                          BEGIN(g_lastExtendsContext);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<ReadTypeConstraint>.                   {
Packit 1c1d7e
                                          g_curTypeConstraint+=yytext;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<ReadTypeConstraint>\n                  {
Packit 1c1d7e
                                          g_curTypeConstraint+=' ';
Packit 1c1d7e
                                        }
Packit 1c1d7e
<FuncQual>"const"		       	{
Packit 1c1d7e
					  g_argList->constSpecifier=TRUE;
Packit 1c1d7e
					}
Packit 1c1d7e
<FuncQual>"volatile"		    	{
Packit 1c1d7e
					  g_argList->volatileSpecifier=TRUE;
Packit 1c1d7e
					}
Packit 1c1d7e
<FuncQual>"&"		    	        {
Packit 1c1d7e
                                          g_argList->refQualifier=RefQualifierLValue;
Packit 1c1d7e
					}
Packit 1c1d7e
<FuncQual>"&&"		    	        {
Packit 1c1d7e
                                          g_argList->refQualifier=RefQualifierRValue;
Packit 1c1d7e
					}
Packit 1c1d7e
<FuncQual,TrailingReturn>"="{B}*"0"  	{
Packit 1c1d7e
					  g_argList->pureSpecifier=TRUE;
Packit 1c1d7e
                                          BEGIN(FuncQual);
Packit 1c1d7e
					}
Packit 1c1d7e
<FuncQual>"->"                          { // C++11 trailing return type
Packit 1c1d7e
                                          g_argList->trailingReturnType=" -> ";
Packit 1c1d7e
                                          BEGIN(TrailingReturn);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<TrailingReturn>{B}/("final"|"override"){B}*  {
Packit 1c1d7e
                                          unput(*yytext);
Packit 1c1d7e
                                          BEGIN(FuncQual);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<TrailingReturn>.                       {
Packit 1c1d7e
                                          g_argList->trailingReturnType+=yytext;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<TrailingReturn>\n                      {
Packit 1c1d7e
                                          g_argList->trailingReturnType+=yytext;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<FuncQual>")"{B}*"["[^]]*"]"		{ // for functions returning a pointer to an array, 
Packit 1c1d7e
                                          // i.e. ")[]" in "int (*f(int))[4]" with argsString="(int))[4]"
Packit 1c1d7e
  					  g_extraTypeChars=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadDocBlock>[^\*\n]+			{
Packit 1c1d7e
  					  g_curArgDocs+=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadDocLine>[^\n]+			{
Packit 1c1d7e
  					  g_curArgDocs+=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadDocBlock>"*/"			{ 
Packit 1c1d7e
  					  if (g_lastDocChar!=0)
Packit 1c1d7e
					    unput(g_lastDocChar);
Packit 1c1d7e
  					  BEGIN(g_lastDocContext); 
Packit 1c1d7e
					}
Packit 1c1d7e
<ReadDocLine>\n				{
Packit 1c1d7e
  					  if (g_lastDocChar!=0)
Packit 1c1d7e
					    unput(g_lastDocChar);
Packit 1c1d7e
					  BEGIN(g_lastDocContext);
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadDocBlock>\n			{
Packit 1c1d7e
  					  g_curArgDocs+=*yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<ReadDocBlock>.				{
Packit 1c1d7e
  					  g_curArgDocs+=*yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<*>("/*"[*!]|"//"[/!])("<"?)		{
Packit 1c1d7e
  					  g_lastDocContext=YY_START;
Packit 1c1d7e
					  g_lastDocChar=0;  
Packit 1c1d7e
					  if (yytext[1]=='/')
Packit 1c1d7e
					    BEGIN( ReadDocLine );
Packit 1c1d7e
					  else
Packit 1c1d7e
  					    BEGIN( ReadDocBlock );
Packit 1c1d7e
  					}
Packit 1c1d7e
<*>\n
Packit 1c1d7e
<*>.
Packit 1c1d7e
Packit 1c1d7e
%%
Packit 1c1d7e
Packit 1c1d7e
/* ----------------------------------------------------------------------------
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
/*! Converts an argument string into an ArgumentList.
Packit 1c1d7e
 *  \param[in] argsString the list of Arguments.
Packit 1c1d7e
 *  \param[out] al a reference to resulting argument list pointer.
Packit 1c1d7e
 *  \param[out] extraTypeChars point to string to which trailing characters 
Packit 1c1d7e
 *              for complex types are written to
Packit 1c1d7e
 */
Packit 1c1d7e
 
Packit 1c1d7e
void stringToArgumentList(const char *argsString,ArgumentList* al,QCString *extraTypeChars)
Packit 1c1d7e
{
Packit 1c1d7e
  if (al==0) return; 
Packit 1c1d7e
  if (argsString==0) return;
Packit 1c1d7e
  printlex(yy_flex_debug, TRUE, __FILE__, NULL);
Packit 1c1d7e
Packit 1c1d7e
  g_copyArgValue=0;
Packit 1c1d7e
  g_curArgDocs.resize(0);
Packit 1c1d7e
  g_curArgAttrib.resize(0);
Packit 1c1d7e
  g_curArgArray.resize(0);
Packit 1c1d7e
  g_curTypeConstraint.resize(0);
Packit 1c1d7e
  g_extraTypeChars.resize(0);
Packit 1c1d7e
  g_argRoundCount = 0;
Packit 1c1d7e
  g_argSharpCount = 0;
Packit 1c1d7e
  g_argCurlyCount = 0;
Packit 1c1d7e
  g_lastDocChar = 0;
Packit 1c1d7e
Packit 1c1d7e
  g_inputString   = argsString;
Packit 1c1d7e
  g_inputPosition = 0;
Packit 1c1d7e
  g_curArgTypeName.resize(0);
Packit 1c1d7e
  g_curArgDefValue.resize(0);
Packit 1c1d7e
  g_curArgName.resize(0);
Packit 1c1d7e
  g_argList = al;
Packit 1c1d7e
  defargsYYrestart( defargsYYin );
Packit 1c1d7e
  BEGIN( Start );
Packit 1c1d7e
  defargsYYlex();
Packit 1c1d7e
  if (extraTypeChars) *extraTypeChars=g_extraTypeChars;
Packit 1c1d7e
  //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data());
Packit 1c1d7e
  printlex(yy_flex_debug, FALSE, __FILE__, NULL);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
#if !defined(YY_FLEX_SUBMINOR_VERSION) 
Packit 1c1d7e
extern "C" { // some bogus code to keep the compiler happy
Packit 1c1d7e
  void defargsYYdummy() { yy_flex_realloc(0,0); } 
Packit 1c1d7e
}
Packit 1c1d7e
#endif
Packit 1c1d7e