diff -r 932c358ece3e -r d8fccb2cd802 Orb/Doxygen/src/defargs.l --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orb/Doxygen/src/defargs.l Fri Apr 23 20:47:58 2010 +0100 @@ -0,0 +1,478 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2008 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +/*! \file + * This scanner is used to convert a string into a list of function or + * template arguments. Each parsed argument results in a Argument struct, + * that is put into an ArgumentList in declaration order. + * Comment blocks for arguments can also be included in the string. + * The argument string does not contain new-lines (except inside any + * comment blocks). + * An Argument consists of the string fields: + * type,name,default value, and documentation + * The Argument list as a whole can be pure, constant or volatile. + * + * Examples of input strings are: + * \code + * "(int a,int b) const" + * "(const char *s="hello world",int=5) = 0" + * "" + * "(char c,const char)" + * \endcode + * + * Note: It is not always possible to distinguish between the name and + * type of an argument. In case of doubt the name is added to the + * type, and the matchArgumentList in util.cpp is be used to + * further determine the correct separation. + */ + +%{ + +/* + * includes + */ +#include "qtbc.h" +#include +//#include +#include +#include +#include + +#include "defargs.h" +#include "entry.h" +#include "util.h" + +#define YY_NEVER_INTERACTIVE 1 + +/* ----------------------------------------------------------------- + * state variables + */ +static const char *g_inputString; +static int g_inputPosition; +static ArgumentList *g_argList; +static QCString *g_copyArgValue; +static QCString g_curArgTypeName; +static QCString g_curArgDefValue; +static QCString g_curArgName; +static QCString g_curArgDocs; +static QCString g_curArgAttrib; +static QCString g_curArgArray; +static QCString g_extraTypeChars; +static int g_argRoundCount; +static int g_argSharpCount; +static int g_argCurlyCount; +static int g_readArgContext; +static int g_lastDocContext; +static int g_lastDocChar; + +/* ----------------------------------------------------------------- + */ +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); + +static int yyread(char *buf,int max_size) +{ + int c=0; + while( c < max_size && g_inputString[g_inputPosition] ) + { + *buf = g_inputString[g_inputPosition++] ; + c++; buf++; + } + return c; +} + +%} + +B [ \t] +ID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* + +%option noyywrap + +%x Start +%x CopyArgString +%x CopyArgRound +%x CopyArgRound2 +%x CopyArgSharp +%x CopyArgCurly +%x ReadFuncArgType +%x ReadFuncArgDef +%x ReadFuncArgPtr +%x FuncQual +%x ReadDocBlock +%x ReadDocLine + + +%% + +[<(] { BEGIN(ReadFuncArgType); } + +{B}* { + g_curArgTypeName+=" "; + } +"["[^\]]*"]" { + if (g_curArgTypeName.stripWhiteSpace().isEmpty()) + { + g_curArgAttrib=yytext; // for M$-IDL + } + else // array type + { + g_curArgArray+=yytext; + } + } +"'"\\[0-7]{1,3}"'" { g_curArgDefValue+=yytext; } +"'"\\."'" { g_curArgDefValue+=yytext; } +"'"."'" { g_curArgDefValue+=yytext; } +\" { + g_curArgDefValue+=*yytext; + BEGIN( CopyArgString ); + } +"("([^:)]+{B}*"::")*{B}*[&*]+{B}*/{ID} { + // function pointer as argument + g_curArgTypeName+=yytext; + //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace(); + BEGIN( ReadFuncArgPtr ); + } +{ID} { + g_curArgName=yytext; + } +")"{B}*"(" { // function pointer + g_curArgTypeName+=yytext; + //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace(); + g_readArgContext = ReadFuncArgType; + g_copyArgValue=&g_curArgTypeName; + g_argRoundCount=0; + BEGIN( CopyArgRound2 ); + } +")"/{B}*"[" { // pointer to fixed size array + g_curArgTypeName+=yytext; + g_curArgTypeName+=g_curArgName; + //g_curArgTypeName=g_curArgTypeName.simplifyWhiteSpace(); + BEGIN( ReadFuncArgType ); + } +")" { // redundant braces detected / remove them + int i=g_curArgTypeName.findRev('('),l=g_curArgTypeName.length(); + if (i!=-1) + g_curArgTypeName=g_curArgTypeName.left(i)+ + g_curArgTypeName.right(l-i-1); + g_curArgTypeName+=g_curArgName; + BEGIN( ReadFuncArgType ); + } +"<="|">="|"->"|">>"|"<<" { // handle operators in defargs + g_curArgTypeName+=yytext; + } +[({<] { + if (YY_START==ReadFuncArgType) + { + g_curArgTypeName+=*yytext; + g_copyArgValue=&g_curArgTypeName; + } + else // YY_START==ReadFuncArgDef + { + g_curArgDefValue+=*yytext; + g_copyArgValue=&g_curArgDefValue; + } + g_readArgContext = YY_START; + if (*yytext=='(') + { + g_argRoundCount=0; + BEGIN( CopyArgRound ); + } + else if (*yytext=='{') + { + g_argCurlyCount=0; + BEGIN( CopyArgCurly ); + } + else // yytext=='<' + { + g_argSharpCount=0; + BEGIN( CopyArgSharp ); + } + } +"(" { + g_argRoundCount++; + *g_copyArgValue += *yytext; + } +")"({B}*{ID})* { + *g_copyArgValue += yytext; + if (g_argRoundCount>0) + { + g_argRoundCount--; + } + else + { + if (YY_START==CopyArgRound2) + { + *g_copyArgValue+=" "+g_curArgName; + } + BEGIN( g_readArgContext ); + } + } +"<" { + g_argSharpCount++; + *g_copyArgValue += *yytext; + } +">" { + *g_copyArgValue += *yytext; + if (g_argSharpCount>0) g_argSharpCount--; + else BEGIN( g_readArgContext ); + } +"{" { + g_argCurlyCount++; + *g_copyArgValue += *yytext; + } +"}" { + *g_copyArgValue += *yytext; + if (g_argCurlyCount>0) g_argCurlyCount--; + else BEGIN( g_readArgContext ); + } +\\. { + g_curArgDefValue+=yytext; + } +\" { + g_curArgDefValue+=*yytext; + BEGIN( ReadFuncArgDef ); + } +"=" { + BEGIN( ReadFuncArgDef ); + } +[,)>]{B}*("/*"[*!]|"//"[/!])"<" { + g_lastDocContext=YY_START; + g_lastDocChar=*yytext; + QCString text=yytext; + if (text.find("//")!=-1) + BEGIN( ReadDocLine ); + else + BEGIN( ReadDocBlock ); + } +[,)>] { + if (*yytext==')' && g_curArgTypeName.stripWhiteSpace().isEmpty()) + { + g_curArgTypeName+=*yytext; + BEGIN(FuncQual); + } + else + { + g_curArgTypeName=removeRedundantWhiteSpace(g_curArgTypeName); + g_curArgDefValue=g_curArgDefValue.stripWhiteSpace(); + //printf("curArgType=`%s' curArgDefVal=`%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data()); + int l=g_curArgTypeName.length(); + if (l>0) + { + int i=l-1; + while (i>=0 && (isspace((uchar)g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--; + while (i>=0 && isId(g_curArgTypeName.at(i))) i--; + //printf("g_curArgTypeName=`%s' i=%d\n",g_curArgTypeName.data(),i); + Argument *a = new Argument; + a->attrib = g_curArgAttrib.copy(); + //printf("a->type=%s a->name=%s i=%d l=%d\n", + // a->type.data(),a->name.data(),i,l); + a->array.resize(0); + if (i==l-1 && g_curArgTypeName.at(i)==')') // function argument + { + int bi=g_curArgTypeName.find('('); + int fi=bi-1; + //printf("func arg fi=%d\n",fi); + while (fi>=0 && isId(g_curArgTypeName.at(fi))) fi--; + if (fi>=0) + { + a->type = g_curArgTypeName.left(fi+1); + a->name = g_curArgTypeName.mid(fi+1,bi-fi-1).stripWhiteSpace(); + a->array = g_curArgTypeName.right(l-bi); + } + else + { + a->type = g_curArgTypeName; + } + } + else if (i>=0 && g_curArgTypeName.at(i)!=':') + { // type contains a name + a->type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1)); + a->name = g_curArgTypeName.right(l-i-1).stripWhiteSpace(); + + // if the type becomes a type specifier only then we make a mistake + // and need to correct it to avoid seeing a nameless parameter + // "struct A" as a parameter with type "struct" and name "A". + int sv=0; + if (a->type.left(6)=="const ") sv=6; + else if (a->type.left(8)=="volatile ") sv=9; + if (a->type.mid(sv)=="struct" || + a->type.mid(sv)=="union" || + a->type.mid(sv)=="class" || + a->type.mid(sv)=="typename" || + a->type=="const" || a->type=="volatile") + { + a->type = a->type + " " + a->name; + a->name.resize(0); + } + } + else // assume only the type was specified, try to determine name later + { + a->type = removeRedundantWhiteSpace(g_curArgTypeName); + } + a->array += removeRedundantWhiteSpace(g_curArgArray); + //printf("array=%s\n",a->array.data()); + int alen = a->array.length(); + if (alen>2 && a->array.at(0)=='(' && + a->array.at(alen-1)==')') // fix-up for int *(a[10]) + { + int i=a->array.find('[')-1; + a->array = a->array.mid(1,alen-2); + if (i>0 && a->name.isEmpty()) + { + a->name = a->array.left(i).stripWhiteSpace(); + a->array = a->array.mid(i); + } + } + a->defval = g_curArgDefValue.copy(); + //printf("a->type=%s a->name=%s a->defval=\"%s\"\n",a->type.data(),a->name.data(),a->defval.data()); + a->docs = g_curArgDocs.stripWhiteSpace(); + //printf("Argument `%s' `%s' adding docs=`%s'\n",a->type.data(),a->name.data(),a->docs.data()); + g_argList->append(a); + } + g_curArgAttrib.resize(0); + g_curArgTypeName.resize(0); + g_curArgDefValue.resize(0); + g_curArgArray.resize(0); + g_curArgDocs.resize(0); + if (*yytext==')') + { + BEGIN(FuncQual); + //printf(">>> end of argument list\n"); + } + else + { + BEGIN( ReadFuncArgType ); + } + } + } +{ID} { + QCString name=yytext; //resolveDefines(yytext); + if (YY_START==ReadFuncArgType && g_curArgArray=="[]") // Java style array + { + g_curArgTypeName+=" []"; + g_curArgArray.resize(0); + } + //printf("resolveName `%s'->`%s'\n",yytext,name.data()); + g_curArgTypeName+=name; + } +. { + g_curArgTypeName+=*yytext; + } + +"->"|">="|">>" { + g_curArgDefValue+=yytext; + } +. { + g_curArgDefValue+=*yytext; + } +{ID} { + QCString name=yytext; //resolveDefines(yytext); + *g_copyArgValue+=name; + } +. { + *g_copyArgValue += *yytext; + } +"const" { + g_argList->constSpecifier=TRUE; + } +"volatile" { + g_argList->volatileSpecifier=TRUE; + } +"="{B}*"0" { + g_argList->pureSpecifier=TRUE; + } +")"{B}*"["[^]]*"]" { // for functions returning a pointer to an array, + // i.e. ")[]" in "int (*f(int))[4]" with argsString="(int))[4]" + g_extraTypeChars=yytext; + } +[^\*\n]+ { + g_curArgDocs+=yytext; + } +[^\n]+ { + g_curArgDocs+=yytext; + } +"*/" { + if (g_lastDocChar!=0) + unput(g_lastDocChar); + BEGIN(g_lastDocContext); + } +\n { + if (g_lastDocChar!=0) + unput(g_lastDocChar); + BEGIN(g_lastDocContext); + } +\n { + g_curArgDocs+=*yytext; + } +. { + g_curArgDocs+=*yytext; + } +<*>("/*"[*!]|"//"[/!])("<"?) { + g_lastDocContext=YY_START; + g_lastDocChar=0; + if (yytext[1]=='/') + BEGIN( ReadDocLine ); + else + BEGIN( ReadDocBlock ); + } +<*>\n +<*>. + +%% + +/* ---------------------------------------------------------------------------- + */ + +/*! Converts an argument string into an ArgumentList. + * \param argsString the list of Arguments. + * \param al a reference to resulting argument list pointer. + */ + +void stringToArgumentList(const char *argsString,ArgumentList* al,QCString *extraTypeChars) +{ + if (al==0) return; + if (argsString==0) return; + + g_copyArgValue=0; + g_curArgDocs.resize(0); + g_curArgAttrib.resize(0); + g_curArgArray.resize(0); + g_extraTypeChars.resize(0); + g_argRoundCount = 0; + g_argSharpCount = 0; + g_argCurlyCount = 0; + g_lastDocChar = 0; + + g_inputString = argsString; + g_inputPosition = 0; + g_curArgTypeName.resize(0); + g_curArgDefValue.resize(0); + g_curArgName.resize(0); + g_argList = al; + defargsYYrestart( defargsYYin ); + BEGIN( Start ); + defargsYYlex(); + if (extraTypeChars) *extraTypeChars=g_extraTypeChars; + //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data()); +} + +#if !defined(YY_FLEX_SUBMINOR_VERSION) +extern "C" { // some bogus code to keep the compiler happy + void defargsYYdummy() { yy_flex_realloc(0,0); } +} +#endif +