[prev in list] [next in list] [prev in thread] [next in thread]
List: koffice
Subject: Re: USE_QFD, moc & dcopidl
From: Reginald Stadlbauer <reggie () troll ! no>
Date: 2000-01-18 22:48:00
[Download RAW message or body]
On Tue, 18 Jan 2000, David Faure wrote:
>On Tue, Jan 18, 2000 at 10:47:17PM +0100, Reginald Stadlbauer wrote:
>> On Tue, 18 Jan 2000, David Faure wrote:
>> >On Tue, Jan 18, 2000 at 10:26:25PM +0100, Werner Trobin wrote:
>> >> Hi!
>> >>
>> >> It seems that these programs are a little bit broken at the
>> >> moment. moc is unable to handle killustrator/share/GObject.h
>> >> (some enums and structs) and dcopidl barfs on kspread and
>> >> kpresenter...
>> >
>> >coolo is working on dcopidl, and I reported the moc bug to both
>> >qt-bugs and kde-cvs ;)
>> >(and got a reply from Torben about him fixing it...)
>>
>> According to this p4 log he did it sunday afternoon
>>
>> -------------
>> weis 17:57:12
>> Ignore nested classes. Fixed a bug reported
>> by David Faure.
>>
>> edit main src/moc/moc.l #45
>> edit main src/moc/moc.y #154
>> -------------
>
>Great. Reggie, can you apply the fix to qt-copy ?
>That would make killu compileable again.
I don't want to checkout qt-copy. I attached these two files.
--
Reggie
["moc.l" (text/english)]
/****************************************************************************
** $Id: //depot/qt/main/src/moc/moc.l#36 $
**
** Lexical analyzer for meta object compiler
**
** Created : 930417
**
** Copyright (C) 1993-1999 by Troll Tech AS. All rights reserved.
**
** This file is part of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Troll Tech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** Licensees holding valid Qt Professional Edition licenses may use this
** file in accordance with the Qt Professional Edition License Agreement
** provided with the Qt Professional Edition.
**
** See http://www.troll.no/pricing.html or email sales@troll.no for
** information about the Professional Edition licensing, or see
** http://www.troll.no/qpl/ for QPL licensing information.
**
*****************************************************************************/
%{
#include "qstring.h"
#define input yyinput // yyinput in C++
#define X if(lexDebug){fprintf(stderr,"LEX (%i) : %s\n",lineNo,yytext);};
#define Y if(lexDebug){fprintf(stderr,"LEX (%i) : %s\n",lineNo,yytext);};
// #define Y if(lexDebug){fprintf(stderr,"LEX (%i) : %s updates level to %i\n"\
// ,lineNo,yytext,templLevel);};
#define Z if(lexDebug){fprintf(stderr,"LEX (%i) : skipped the string %s\"\n"\
,lineNo,yytext);};
#define BEGIN_INSIDE
#define linput() (c = input()) == '\n' ? (lineNo++,c) : c
#include <string.h>
#include <stdlib.h>
/* char c,c1; */
int classPLevel = 1; /* Depth of nested curly braces in IN_CLASS*/
int namespacePLevel = 1; /* Depth of nested curly braces in IN_NAMESPACE*/
int expLevel = 1; /* Depth of nested parentheses in IN_EXPR */
int fctLevel = 1; /* Depth of nested parentheses in IN_FCT */
int templLevel = 1; /* Depth of levels in IN_TEMPL_ARGS */
int lastState = 0; /* Remembers the state when a
MOC_SKIP_BEGIN is encountered */
int skipLevel = 0; /* Depth of MOC_SKIP_BEGINs */
class QString;
extern void addExpressionChar( char );
extern void addExpressionString( char * );
extern void moc_warn( char *msg );
%}
%start OUTSIDE QT_DEF IN_CLASS IN_NAMESPACE IN_ENUM IN_EXPR IN_FCT IN_TEMPL_ARGS \
GIMME_SEMICOLON SKIP IN_PROPERTY
%%
<OUTSIDE>"class" { X;
BEGIN QT_DEF;
return CLASS; }
<OUTSIDE>"namespace" { X;
BEGIN QT_DEF;
return NAMESPACE; }
<OUTSIDE>"using" { X;
BEGIN QT_DEF;
return USING; }
<OUTSIDE>"template" { X;
BEGIN QT_DEF;
return TEMPLATE; }
<QT_DEF>"signals" { X; return SIGNALS; }
<QT_DEF>"slots" { X; return SLOTS; }
<QT_DEF>"Q_PROPERTY" { X; return Q_PROPERTY; }
<IN_FCT>"{" { fctLevel++;Y; }
<IN_FCT>"}" { fctLevel--;Y;if (fctLevel==0){X;return '}';}}
<IN_CLASS>"{" { classPLevel++;Y; }
<IN_CLASS>"}" { classPLevel--;Y;if (classPLevel == 0)
{X;return '}';} }
<IN_CLASS>"public" { X;if( classPLevel == 1 ) return PUBLIC; }
<IN_CLASS>"protected" { X;if( classPLevel == 1 )return PROTECTED; }
<IN_CLASS>"private" { X;if( classPLevel == 1 )return PRIVATE; }
<IN_CLASS>"signals" { X;if( classPLevel == 1 )return SIGNALS; }
<IN_CLASS>"slots" { X;if( classPLevel == 1 )return SLOTS; }
<IN_CLASS>"enum" { X;if( classPLevel == 1 )return ENUM_IN_CLASS; }
<IN_CLASS>"Q_OBJECT" { X;if( classPLevel == 1 )return Q_OBJECT; }
<IN_CLASS>"Q_PROPERTY" { X;if( classPLevel == 1 )return Q_PROPERTY; }
<IN_CLASS>"Q_CLASSINFO" { X;if( classPLevel == 1 )return Q_CLASSINFO; }
<IN_NAMESPACE>"{" { namespacePLevel++;Y; }
<IN_NAMESPACE>"}" { namespacePLevel--;Y;if (namespacePLevel == 0)
{X;return '}';}}
<IN_NAMESPACE>"class" { X;
BEGIN QT_DEF;
return CLASS; }
<IN_NAMESPACE>"template" { X;
BEGIN QT_DEF;
return TEMPLATE; }
<IN_NAMESPACE>"namespace" { X;
BEGIN QT_DEF;
return NAMESPACE; }
<IN_NAMESPACE>"using" { X;
BEGIN QT_DEF;
return USING; }
<QT_DEF>"Q_OBJECT" { X; return Q_OBJECT; }
<QT_DEF>"Q_CLASSINFO" { X;return Q_CLASSINFO; }
<IN_PROPERTY>"(" { X; return '('; }
<IN_PROPERTY>"," { X; return ','; }
<IN_PROPERTY>")" { X; return ')'; }
<IN_PROPERTY>"0" { X; return '0'; }
<IN_EXPR>"(" { expLevel++;X; }
<IN_EXPR>")" { expLevel--;Y;if (expLevel == 0)
{ X; BEGIN QT_DEF; return ')';} }
<IN_EXPR>"[" { expLevel++;X; }
<IN_EXPR>"]" { expLevel--;X;if (expLevel == 0)
{ X; BEGIN QT_DEF; return ']';} }
<IN_EXPR>"," { if (expLevel == 0)
{ X; BEGIN QT_DEF; return ',' ;} }
<IN_EXPR>";" { if (expLevel == 0)
{ X; BEGIN QT_DEF; return ';' ;} }
<IN_ENUM>"(" { expLevel++;X; }
<IN_ENUM>")" { expLevel--;X;if (expLevel == 0)
{ X; BEGIN QT_DEF; return ')';} }
<IN_ENUM>"[" { expLevel++;X; }
<IN_ENUM>"]" { expLevel--;X;if (expLevel == 0)
{ X; BEGIN QT_DEF; return ']';} }
<IN_ENUM>"," { if (expLevel == 0)
{ X; BEGIN QT_DEF; return ',' ;} }
<IN_ENUM>";" { if (expLevel == 0)
{ X; BEGIN QT_DEF; return ';' ;} }
<IN_ENUM>"}" { if (expLevel == 0)
{ X; BEGIN QT_DEF; return '}' ;} }
<IN_TEMPL_ARGS>"<" { templLevel++;Y; }
<IN_TEMPL_ARGS>">" { templLevel--;Y;if (templLevel == 0)
{ X; BEGIN QT_DEF; return '>';} }
<IN_TEMPL_ARGS>"(" { templLevel++;Y; }
<IN_TEMPL_ARGS>")" { templLevel--;Y;if (templLevel == 0)
{ X; BEGIN QT_DEF; return ')';} }
<IN_TEMPL_ARGS>"[" { templLevel++;Y; }
<IN_TEMPL_ARGS>"]" { templLevel--;Y;if (templLevel == 0)
{ X; BEGIN QT_DEF; return ']';} }
<QT_DEF>"friend" { X;return FRIEND; }
<QT_DEF>"typedef" { X;return TYPEDEF; }
<QT_DEF>"auto" { X;return AUTO; }
<QT_DEF>"register" { X;return REGISTER; }
<QT_DEF>"static" { X;return STATIC; }
<QT_DEF>"extern" { X;return EXTERN; }
<QT_DEF>"inline" { X;return INLINE; }
<QT_DEF>"virtual" { X;return VIRTUAL; }
<QT_DEF>"const" { X;return CONST; }
<QT_DEF>"volatile" { X;return VOLATILE; }
<QT_DEF>"char" { X;return CHAR; }
<QT_DEF>"short" { X;return SHORT; }
<QT_DEF>"int" { X;return INT; }
<QT_DEF>"long" { X;return LONG; }
<QT_DEF>"signed" { X;return SIGNED; }
<QT_DEF>"unsigned" { X;return UNSIGNED; }
<QT_DEF>"float" { X;return FLOAT; }
<QT_DEF>"double" { X;return DOUBLE; }
<QT_DEF>"void" { X;return VOID; }
<QT_DEF>"enum" { X;return ENUM; }
<QT_DEF>"class" { X;return CLASS; }
<QT_DEF>"struct" { X;return STRUCT; }
<QT_DEF>"union" { X;return UNION; }
<QT_DEF>"asm" { X;return ASM; }
<QT_DEF>"private" { X;return PRIVATE; }
<QT_DEF>"protected" { X;return PROTECTED; }
<QT_DEF>"public" { X;return PUBLIC; }
<QT_DEF>"operator" { X;return OPERATOR; }
<QT_DEF>"::" { X;return DBL_COLON; }
<QT_DEF>"..." { X;return TRIPLE_DOT; }
<QT_DEF>"template" { X;return TEMPLATE; }
<QT_DEF>"mutable" { X;return MUTABLE; }
<QT_DEF>"using" { X;return USING; }
<QT_DEF>"namespace" { X;return NAMESPACE; }
<QT_DEF>[_a-zA-Z][_a-zA-Z0-9]* {
X;
yylval.string = qstrdup(yytext);
return IDENTIFIER;
}
<IN_PROPERTY>[_a-zA-Z][_a-zA-Z0-9]* {
X;
yylval.string = qstrdup(yytext);
return IDENTIFIER;
}
<OUTSIDE>[_a-zA-Z][_a-zA-Z0-9]* ;
<IN_CLASS>[_a-zA-Z][_a-zA-Z0-9]* ;
<IN_NAMESPACE>[_a-zA-Z][_a-zA-Z0-9]* ;
<OUTSIDE>\"[^"]* { /* discard strings */
if (yytext[yyleng - 1] == '\\') {
yymore();
}
else {
Z;
input(); /* discard the '"' */
}
}
<IN_CLASS>\"[^"]* { /* discard strings */
if (yytext[yyleng - 1] == '\\') {
yymore();
}
else {
Z;
input(); /* discard the '"' */
}
}
<IN_NAMESPACE>\"[^"]* { /* discard strings */
if (yytext[yyleng - 1] == '\\') {
yymore();
}
else {
Z;
input(); /* discard the '"' */
}
}
<IN_FCT>\"[^"]* { /* discard strings */
if (yytext[yyleng - 1] == '\\') {
yymore();
}
else {
Z;
addExpressionString(yytext);
input(); /* discard the '"' */
}
}
<IN_TEMPL_ARGS>\"[^"]* { if (yytext[yyleng - 1] == '\\') {
yymore();
}
else {
X;
addExpressionString(yytext);
input(); /* discard the '"' */
return STRING;
}
}
<QT_DEF>\"[^"]* { if (yytext[yyleng - 1] == '\\') {
yymore();
}
else {
X;
yylval.string = qstrdup(yytext+1);
input(); /* discard the '"' */
return STRING;
}
}
<IN_PROPERTY>\"[^"]* { if (yytext[yyleng - 1] == '\\') {
yymore();
}
else {
X;
yylval.string = qstrdup(yytext+1);
input(); /* discard the '"' */
return STRING;
}
}
<QT_DEF>'.' { X;
yylval.char_val = yytext[1];
return CHAR_VAL;
}
<QT_DEF>'\\a' { X;
yylval.char_val = '\a';
return CHAR_VAL;
}
<QT_DEF>'\\b' { X;
yylval.char_val = '\b';
return CHAR_VAL;
}
<QT_DEF>'\\f' { X;
yylval.char_val = '\f';
return CHAR_VAL;
}
<QT_DEF>'\\n' { X;
yylval.char_val = '\n';
return CHAR_VAL;
}
<QT_DEF>'\\r' { X;
yylval.char_val = '\r';
return CHAR_VAL;
}
<QT_DEF>'\\t' { X;
yylval.char_val = '\t';
return CHAR_VAL;
}
<QT_DEF>'\\v' { X;
yylval.char_val = '\v';
return CHAR_VAL;
}
<QT_DEF>'\\\\' { X;
yylval.char_val = '\\';
return CHAR_VAL;
}
<QT_DEF>'\\?' { X;
yylval.char_val = '\?';
return CHAR_VAL;
}
<QT_DEF>'\\'' { X;
yylval.char_val = '\'';
return CHAR_VAL;
}
<QT_DEF>'\\\"' { X;
yylval.char_val = '\"'; /* " */
return CHAR_VAL;
}
<QT_DEF>'\\0' { X;
yylval.char_val = '\0';
return CHAR_VAL;
}
<QT_DEF>'\\[0-7]+' { X;
yylval.char_val =
(char)strtol( &yytext[1], 0, 8 );
return CHAR_VAL;
}
<QT_DEF>'\\x[0-9a-fA-F]+' { X;
yylval.char_val =
(char)strtol( &yytext[2], 0, 16 );
return CHAR_VAL;
}
<QT_DEF>'\\.' { X;
yylval.char_val = ' ';
return CHAR_VAL;
}
<QT_DEF>[0-9]+ { X;
yylval.int_val = atoi(yytext);
return INT_VAL;
}
<QT_DEF>[0-9]+\.[0-9]* { X;
yylval.double_val = atof(yytext);
return DOUBLE_VAL;
}
<QT_DEF>\.[0-9]+ { X;
yylval.double_val = atof(yytext);
return DOUBLE_VAL;
}
^#define.*\\$ { /* skip multi-line macro-definitions */
char c, c1;
input(); /* Discard the '\n'. */
do {
c1=' ';
while((c = linput()) != '\n' && c != 0) c1=c;
if (c == 0) break;
} while(c1=='\\');
unput(c); /* put back the '\n' or the EOF */
}
^[ \t]*#.* { /* preprocessor commands are skipped */}
"//"[^\n]* { /* C++ comment */
QCString s = yytext;
if ( s.contains( "MOC_SKIP_BEGIN" ) ) {
skipLevel++;
if ( skipLevel == 1 ) {
lastState = YYSTATE;
BEGIN SKIP;
}
} else
if ( s.contains( "MOC_SKIP_END" ) ) {
if ( skipLevel == 0 ) {
moc_warn(" MOC_SKIP_END without MOC_SKIP_BEGIN");
} else {
skipLevel--;
if ( skipLevel == 0 ) {
BEGIN lastState;
}
}
}
}
"/*" { /* C comment */
char c = ' ';
do {
if ( c!= '*' ) {
while((c = linput()) != '*' && c != 0)
;
}
if (c == 0) break;
} while(((c = linput())) != '/' && c != 0);
if (c == 0)
unput(c);
}
[ \t\r\b\f]+ ;
<IN_CLASS>. ;
<IN_NAMESPACE>. ;
<IN_FCT>. ;
<IN_EXPR>. { addExpressionChar( yytext[0] ); }
<IN_ENUM>. { addExpressionChar( yytext[0] ); }
<IN_TEMPL_ARGS>. { addExpressionChar( yytext[0] ); }
<IN_PROPERTY>. { return CHAR_VAL; }
<OUTSIDE>. ;
<SKIP>. ;
<QT_DEF>. {
X;
return yytext[0];
}
<GIMME_SEMICOLON>. {
X;
return ';';
}
\n {
lineNo++;
}
%%
["moc.y" (text/english)]
/****************************************************************************
** $Id: //depot/qt/main/src/moc/moc.y#125 $
**
** Parser and code generator for meta object compiler
**
** Created : 930417
**
** Copyright (C) 1993-1999 by Troll Tech AS. All rights reserved.
**
** This file is part of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Troll Tech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** Licensees holding valid Qt Professional Edition licenses may use this
** file in accordance with the Qt Professional Edition License Agreement
** provided with the Qt Professional Edition.
**
** See http://www.troll.no/pricing.html or email sales@troll.no for
** information about the Professional Edition licensing, or see
** http://www.troll.no/qpl/ for QPL licensing information.
**
** --------------------------------------------------------------------------
**
** This compiler reads a C++ header file with class definitions and ouputs
** C++ code to build a meta class. The meta data includes public methods
** (not constructors, destructors or operator functions), signals and slot
** definitions. The output file should be compiled and linked into the
** target application.
**
** C++ header files are assumed to have correct syntax, and we are therefore
** doing less strict checking than C++ compilers.
**
** The C++ grammar has been adopted from the "The Annotated C++ Reference
** Manual" (ARM), by Ellis and Stroustrup (Addison Wesley, 1992).
**
** Notice that this code is not possible to compile with GNU bison, instead
** use standard AT&T yacc or Berkeley yacc.
*****************************************************************************/
%{
void yyerror( char *msg );
#include "qlist.h"
#include "qasciidict.h"
#include "qdict.h"
#include "qstrlist.h"
#include "qdatetime.h"
#include "qfile.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
static QCString rmWS( const char * );
enum AccessPerm { _PRIVATE, _PROTECTED, _PUBLIC };
struct Argument // single arg meta data
{
Argument( char *left, char *right )
{ leftType = rmWS( left );
rightType = rmWS( right );
if ( leftType == "void" && rightType.isEmpty() )
leftType = "";
}
QCString leftType;
QCString rightType;
};
class ArgList : public QList<Argument> { // member function arg list
public:
ArgList() { setAutoDelete( TRUE ); }
~ArgList() { clear(); }
};
struct Function // member function meta data
{ // used for signals and slots
AccessPerm accessPerm;
QCString qualifier; // const or volatile
QCString name;
QCString type;
int lineNo;
ArgList *args;
Function() { args=0; }
~Function() { delete args; }
};
class FuncList : public QList<Function> { // list of member functions
public:
FuncList( bool autoDelete = FALSE ) { setAutoDelete( autoDelete ); }
FuncList find( const char* name )
{
FuncList result;
for ( QListIterator<Function> it( *this); it.current(); ++it ) {
if ( it.current()->name == name )
result.append( it.current() );
}
return result;
}
};
class Enum : public QStrList
{
public:
QCString name;
};
class EnumList : public QList<Enum> { // list of property enums
public:
EnumList() { setAutoDelete(TRUE); }
};
struct Property
{
Property( int l, const char* t, const char* n, const char* s, const char* g)
: lineNo(l), type(t), name(n), set(s), get(g), setfunc(0), getfunc(0),
sspec(Unspecified), gspec(Unspecified)
{}
int lineNo;
QCString type;
QCString name;
QCString set;
QCString get;
Function* setfunc;
Function* getfunc;
enum Specification { Unspecified, Class, Reference, Pointer, ConstCharStar };
Specification sspec;
Specification gspec;
static const char* specToString( Specification s )
{
switch ( s ) {
case Class:
return "Class";
case Reference:
return "Reference";
case Pointer:
return "Pointer";
case ConstCharStar:
return "ConstCharStar";
default:
return "Unspecified";
}
}
};
class PropList : public QList<Property> { // list of properties
public:
PropList() { setAutoDelete( TRUE ); }
};
struct ClassInfo
{
ClassInfo( const char* n, const char* v )
: name(n), value(v)
{}
QCString name;
QCString value;
};
class ClassInfoList : public QList<ClassInfo> { // list of class infos
public:
ClassInfoList() { setAutoDelete( TRUE ); }
};
/*
Attention!
This table is copied from qvariant.cpp. If you change
one, change both.
*/
static const int ntypes = 20;
static const char* type_map[ntypes] =
{
0,
"QMap<QString,QVariant>",
"QValueList<QVariant>",
"QString",
"QStringList",
"QFont",
"QPixmap",
"QBrush",
"QRect",
"QSize",
"QColor",
"QPalette",
"QColorGroup",
"QIconSet",
"QPoint",
"QImage",
"int",
"bool",
"double",
"QCString"
};
int qvariant_nameToType( const char* name )
{
for ( int i = 0; i < ntypes; i++ ) {
if ( !qstrcmp( type_map[i], name ) )
return i;
}
return 0;
}
ArgList *addArg( Argument * ); // add arg to tmpArgList
enum Member { SignalMember,
SlotMember,
PropertyCandidateMember,
};
void addMember( Member ); // add tmpFunc to current class
void addEnum(); // add tmpEnum to current class
char *strnew( const char * ); // returns a new string (copy)
char *stradd( const char *, const char * ); // add two strings
char *stradd( const char *, const char *, // add three strings
const char * );
char *straddSpc( const char *, const char * );
char *straddSpc( const char *, const char *,
const char * );
char *straddSpc( const char *, const char *,
const char *, const char * );
extern int yydebug;
bool lexDebug = FALSE;
int lineNo; // current line number
bool errorControl = FALSE; // controlled errors
bool displayWarnings = TRUE;
bool doEnums = TRUE;
bool skipClass; // don't generate for class
bool skipFunc; // don't generate for func
bool templateClass; // class is a template
bool templateClassOld; // previous class is a template
ArgList *tmpArgList; // current argument list
Function *tmpFunc; // current member function
Enum *tmpEnum; // current enum
AccessPerm tmpAccessPerm; // current access permission
AccessPerm subClassPerm; // current access permission
bool Q_OBJECTdetected; // TRUE if current class
// contains the Q_OBJECT macro
bool Q_PROPERTYdetected; // TRUE if current class
// contains at least one Q_PROPERTY macro
// some temporary values
QCString tmpExpression;
int tmpYYStart;
const int formatRevision = 7; // moc output format revision
%}
%union {
char char_val;
int int_val;
double double_val;
char *string;
AccessPerm access;
Function *function;
ArgList *arg_list;
Argument *arg;
}
%start declaration_seq
%token <char_val> CHAR_VAL /* value types */
%token <int_val> INT_VAL
%token <double_val> DOUBLE_VAL
%token <string> STRING
%token <string> IDENTIFIER /* identifier string */
%token FRIEND /* declaration keywords */
%token TYPEDEF
%token AUTO
%token REGISTER
%token STATIC
%token EXTERN
%token INLINE
%token VIRTUAL
%token CONST
%token VOLATILE
%token CHAR
%token SHORT
%token INT
%token LONG
%token SIGNED
%token UNSIGNED
%token FLOAT
%token DOUBLE
%token VOID
%token ENUM
%token ENUM_IN_CLASS
%token CLASS
%token STRUCT
%token UNION
%token ASM
%token PRIVATE
%token PROTECTED
%token PUBLIC
%token OPERATOR
%token DBL_COLON
%token TRIPLE_DOT
%token TEMPLATE
%token NAMESPACE
%token USING
%token MUTABLE
%token SIGNALS
%token SLOTS
%token Q_OBJECT
%token Q_PROPERTY
%token Q_CLASSINFO
%type <string> class_name
%type <string> template_class_name
%type <string> template_spec
%type <string> opt_base_spec
%type <string> base_spec
%type <string> base_list
%type <string> qt_macro_name
%type <string> base_specifier
%type <access> access_specifier
%type <string> fct_name
%type <string> type_name
%type <string> simple_type_names
%type <string> simple_type_name
%type <string> class_key
%type <string> complete_class_name
%type <string> qualified_class_name
%type <string> elaborated_type_specifier
%type <arg_list> argument_declaration_list
%type <arg_list> arg_declaration_list
%type <arg_list> arg_declaration_list_opt
%type <string> abstract_decl_opt
%type <string> abstract_decl
%type <arg> argument_declaration
%type <string> cv_qualifier_list_opt
%type <string> cv_qualifier_list
%type <string> cv_qualifier
%type <string> decl_specifiers
%type <string> decl_specifier
%type <string> decl_specs_opt
%type <string> decl_specs
%type <string> type_specifier
%type <string> declarator
%type <string> ptr_operator
%type <string> ptr_operators
%type <string> ptr_operators_opt
%type <string> prop_access_function
%%
declaration_seq: /* empty */
| declaration_seq declaration
;
declaration: class_def
/* | template_declaration */
| namespace_def
| namespace_alias_def
| using_declaration
| using_directive
;
namespace_def: named_namespace_def
| unnamed_namespace_def
;
named_namespace_def: NAMESPACE
IDENTIFIER { enterNameSpace($2); }
'{' { BEGIN IN_NAMESPACE; }
namespace_body
'}' { leaveNameSpace();
selectOutsideClassState();
}
;
unnamed_namespace_def: NAMESPACE { enterNameSpace(); }
'{' { BEGIN IN_NAMESPACE; }
namespace_body
'}' { leaveNameSpace();
selectOutsideClassState();
}
;
namespace_body: declaration_seq
;
namespace_alias_def: NAMESPACE IDENTIFIER '=' complete_class_name ';'
{ selectOutsideClassState(); }
;
using_directive: USING NAMESPACE { selectOutsideClassState(); } /* Skip namespace */
;
using_declaration: USING IDENTIFIER { selectOutsideClassState(); }
| USING DBL_COLON { selectOutsideClassState(); }
;
class_def: { initClass(); }
class_specifier ';' { generateClass();
registerClassInNamespace();
selectOutsideClassState(); }
;
/***** r.17.1 (ARM p.387 ): Keywords *****/
class_name: IDENTIFIER { $$ = $1; }
| template_class_name { $$ = $1; }
;
template_class_name: IDENTIFIER '<' template_args '>'
{ $$ = stradd( $1, "<",
tmpExpression =
tmpExpression.stripWhiteSpace(), ">" ); }
;
/*
template_args skips all characters until it encounters a ">" (it
handles and discards sublevels of parentheses). Since the rule is
empty it must be used with care!
*/
template_args: /* empty */ { initExpression();
templLevel = 1;
BEGIN IN_TEMPL_ARGS; }
;
/***** r.17.2 (ARM p.388): Expressions *****/
/* const_expression skips all characters until it encounters either one
of "]", ")" or "," (it handles and discards sublevels of parentheses).
Since the rule is empty it must be used with care!
*/
const_expression: /* empty */ { initExpression();
BEGIN IN_EXPR; }
;
enumerator_expression: /* empty */ { initExpression();
BEGIN IN_ENUM; }
;
/***** r.17.3 (ARM p.391): Declarations *****/
decl_specifier: storage_class_specifier { $$ = ""; }
| type_specifier { $$ = $1; }
| fct_specifier { $$ = ""; }
| FRIEND { skipFunc = TRUE; $$ = ""; }
| TYPEDEF { skipFunc = TRUE; $$ = ""; }
;
decl_specifiers: decl_specs_opt type_name decl_specs_opt
{ $$ = straddSpc($1,$2,$3); }
;
decl_specs_opt: /* empty */ { $$ = ""; }
| decl_specs { $$ = $1; }
;
decl_specs: decl_specifier { $$ = $1; }
| decl_specs decl_specifier { $$ = straddSpc($1,$2); }
;
storage_class_specifier: AUTO
| REGISTER
| STATIC { skipFunc = TRUE; }
| EXTERN
;
fct_specifier: INLINE
| VIRTUAL
;
type_specifier: CONST { $$ = "const"; }
| VOLATILE { $$ = "volatile"; }
;
type_name: elaborated_type_specifier { $$ = $1; }
| complete_class_name { $$ = $1; }
| simple_type_names { $$ = $1; }
;
simple_type_names: simple_type_names simple_type_name
{ $$ = straddSpc($1,$2); }
| simple_type_name { $$ = $1; }
simple_type_name: CHAR { $$ = "char"; }
| SHORT { $$ = "short"; }
| INT { $$ = "int"; }
| LONG { $$ = "long"; }
| SIGNED { $$ = "signed"; }
| UNSIGNED { $$ = "unsigned"; }
| FLOAT { $$ = "float"; }
| DOUBLE { $$ = "double"; }
| VOID { $$ = "void"; }
;
template_spec: TEMPLATE '<' template_args '>'
{ $$ = stradd( "template<",
tmpExpression =
tmpExpression.stripWhiteSpace(), ">" ); }
;
opt_template_spec: /* empty */
| template_spec { templateClassOld = templateClass;
templateClass = TRUE;
}
;
class_key: opt_template_spec CLASS { $$ = "class"; }
| opt_template_spec STRUCT { $$ = "struct"; }
;
complete_class_name: qualified_class_name { $$ = $1; }
| DBL_COLON qualified_class_name
{ $$ = stradd( "::", $2 ); }
;
qualified_class_name: qualified_class_name DBL_COLON class_name
{ $$ = stradd( $1, "::", $3 );}
| class_name { $$ = $1; }
;
elaborated_type_specifier:
class_key IDENTIFIER { $$ = straddSpc($1,$2); }
| ENUM IDENTIFIER { $$ = stradd("enum ",$2); }
| UNION IDENTIFIER { $$ = stradd("union ",$2); }
;
/***** r.17.4 (ARM p.393): Declarators *****/
argument_declaration_list: arg_declaration_list_opt triple_dot_opt { $$ = $1;}
| arg_declaration_list ',' TRIPLE_DOT { $$ = $1;
func_warn("Ellipsis not supported"
" in signals and slots.\n"
"Ellipsis argument ignored."); }
;
arg_declaration_list_opt: /* empty */ { $$ = tmpArgList; }
| arg_declaration_list { $$ = $1; }
;
triple_dot_opt: /* empty */
| TRIPLE_DOT { func_warn("Ellipsis not supported"
" in signals and slots.\n"
"Ellipsis argument ignored."); }
;
arg_declaration_list: arg_declaration_list
','
argument_declaration { $$ = addArg($3); }
| argument_declaration { $$ = addArg($1); }
argument_declaration: decl_specifiers abstract_decl_opt
{ $$ = new Argument(straddSpc($1,$2),""); }
| decl_specifiers abstract_decl_opt
'=' { expLevel = 1; }
const_expression
{ $$ = new Argument(straddSpc($1,$2),""); }
| decl_specifiers abstract_decl_opt dname
abstract_decl_opt
{ $$ = new Argument(straddSpc($1,$2),$4); }
| decl_specifiers abstract_decl_opt dname
abstract_decl_opt
'=' { expLevel = 1; }
const_expression
{ $$ = new Argument(straddSpc($1,$2),$4); }
;
abstract_decl_opt: /* empty */ { $$ = ""; }
| abstract_decl { $$ = $1; }
;
abstract_decl: abstract_decl ptr_operator
{ $$ = straddSpc($1,$2); }
| '[' { expLevel = 1; }
const_expression ']'
{ $$ = stradd( "[",
tmpExpression =
tmpExpression.stripWhiteSpace(), "]" ); }
| abstract_decl '[' { expLevel = 1; }
const_expression ']'
{ $$ = stradd( $1,"[",
tmpExpression =
tmpExpression.stripWhiteSpace(),"]" ); }
| ptr_operator { $$ = $1; }
| '(' abstract_decl ')' { $$ = $2; }
;
declarator: dname { $$ = ""; }
| declarator ptr_operator
{ $$ = straddSpc($1,$2);}
| declarator '[' { expLevel = 1; }
const_expression ']'
{ $$ = stradd( $1,"[",
tmpExpression =
tmpExpression.stripWhiteSpace(),"]" ); }
| '(' declarator ')' { $$ = $2; }
;
dname: IDENTIFIER
;
fct_decl: '('
argument_declaration_list
')'
cv_qualifier_list_opt
ctor_initializer_opt
fct_body_or_semicolon
{ tmpFunc->args = $2;
tmpFunc->qualifier = $4; }
;
fct_name: IDENTIFIER /* NOTE: simplified! */
| IDENTIFIER array_decls
{ func_warn("Variable as signal or slot."); }
| IDENTIFIER '=' { expLevel=0; }
const_expression /* probably const member */
{ skipFunc = TRUE; }
| IDENTIFIER array_decls '=' { expLevel=0; }
const_expression /* probably const member */
{ skipFunc = TRUE; }
;
array_decls: '[' { expLevel = 1; }
const_expression ']'
| array_decls '[' { expLevel = 1; }
const_expression ']'
;
ptr_operators_opt: /* empty */ { $$ = ""; }
| ptr_operators { $$ = $1; }
;
ptr_operators: ptr_operator { $$ = $1; }
| ptr_operators ptr_operator { $$ = straddSpc($1,$2);}
;
ptr_operator: '*' cv_qualifier_list_opt { $$ = straddSpc("*",$2);}
| '&' cv_qualifier_list_opt { $$ = stradd("&",$2);}
/*! | complete_class_name
DBL_COLON
'*'
cv_qualifier_list_opt { $$ = stradd($1,"::*",$4); }*/
;
cv_qualifier_list_opt: /* empty */ { $$ = ""; }
| cv_qualifier_list { $$ = $1; }
;
cv_qualifier_list: cv_qualifier { $$ = $1; }
| cv_qualifier_list cv_qualifier
{ $$ = straddSpc($1,$2); }
;
cv_qualifier: CONST { $$ = "const"; }
| VOLATILE { $$ = "volatile"; }
;
fct_body_or_semicolon: ';'
| fct_body
| '=' INT_VAL ';' /* abstract func, INT_VAL = 0 */
;
fct_body: '{' { BEGIN IN_FCT; fctLevel = 1;}
'}' { BEGIN QT_DEF; }
;
/***** r.17.5 (ARM p.395): Class Declarations *****/
class_specifier: full_class_head
'{' { BEGIN IN_CLASS;
classPLevel = 1;
}
opt_obj_member_list
'}' { BEGIN QT_DEF; } /*catch ';'*/
| class_head { BEGIN QT_DEF; /* -- " -- */
skipClass = TRUE; }
| class_head
'(' IDENTIFIER ')' /* Qt macro name */
{ BEGIN QT_DEF; /* catch ';' */
skipClass = TRUE; }
| template_spec whatever { skipClass = TRUE;
BEGIN GIMME_SEMICOLON; }
;
whatever: IDENTIFIER
| simple_type_name
| type_specifier
| storage_class_specifier
| fct_specifier
;
class_head: class_key
qualified_class_name { className = $2; }
| class_key
IDENTIFIER /* possible DLL EXPORT macro */
class_name { className = $3; }
;
full_class_head: class_head
opt_base_spec { superclassName = $2; }
;
nested_class_head: class_key
qualified_class_name
opt_base_spec { templateClass = templateClassOld; }
ctor_initializer_opt: /* empty */
| ctor_initializer
;
ctor_initializer: ':' mem_initializer_list
;
mem_initializer_list: mem_initializer
| mem_initializer ',' mem_initializer_list
;
/* complete_class_name also represents IDENTIFIER */
mem_initializer: complete_class_name '(' { expLevel = 1; }
const_expression ')'
;
opt_base_spec: /* empty */ { $$ = 0; }
| base_spec { $$ = $1; }
;
opt_obj_member_list: /* empty */
| obj_member_list
;
obj_member_list: obj_member_list obj_member_area
| obj_member_area
;
qt_access_specifier: access_specifier { tmpAccessPerm = $1; }
| SLOTS { moc_err( "Missing access specifier"
" before \"slots:\"." ); }
;
obj_member_area: qt_access_specifier { BEGIN QT_DEF; }
slot_area
| SIGNALS { BEGIN QT_DEF; }
':' opt_signal_declarations
| Q_OBJECT {
if ( tmpAccessPerm )
moc_warn("Q_OBJECT is not in the private"
" section of the class.\n"
"Q_OBJECT is a macro that resets"
" access permission to \"private\".");
Q_OBJECTdetected = TRUE;
}
| Q_PROPERTY { tmpYYStart = YY_START; BEGIN IN_PROPERTY; }
'(' IDENTIFIER ',' STRING ',' prop_access_function ',' prop_access_function ')'
{
checkIdentifier( $6 );
Q_PROPERTYdetected = TRUE;
props.append( new Property( lineNo, $4,$6,$10,$8) );
BEGIN tmpYYStart;
}
opt_property_candidates
| Q_CLASSINFO { tmpYYStart = YY_START; BEGIN IN_PROPERTY; }
'(' STRING ',' STRING ')'
{
infos.append( new ClassInfo( $4, $6 ) );
BEGIN tmpYYStart;
}
opt_property_candidates
| ENUM_IN_CLASS { BEGIN QT_DEF; }
enum_in_class_tail { BEGIN IN_CLASS;}
opt_semicolons
;
slot_area: SIGNALS ':' { moc_err( "Signals cannot "
"have access specifiers" ); }
| SLOTS ':' opt_slot_declarations
| ':' { if ( tmpAccessPerm == _PUBLIC && Q_PROPERTYdetected )
BEGIN QT_DEF;
else
BEGIN IN_CLASS;
suppress_func_warn = TRUE;
}
opt_property_candidates
{
suppress_func_warn = FALSE;
}
| IDENTIFIER { BEGIN IN_CLASS;
if ( classPLevel != 1 )
moc_warn( "unexpected access"
"specifier" );
}
;
opt_property_candidates: /*empty*/
| property_candidate_declarations
;
property_candidate_declarations: property_candidate_declarations property_candidate_declaration
| property_candidate_declaration
;
property_candidate_declaration: signal_or_slot { addMember( PropertyCandidateMember ); }
;
opt_signal_declarations: /* empty */
| signal_declarations
;
signal_declarations: signal_declarations signal_declaration
| signal_declaration
;
signal_declaration: signal_or_slot { addMember( SignalMember ); }
;
opt_slot_declarations: /* empty */
| slot_declarations
;
slot_declarations: slot_declarations slot_declaration
| slot_declaration
;
slot_declaration: signal_or_slot { addMember( SlotMember ); }
;
opt_semicolons: /* empty */
| opt_semicolons ';'
;
base_spec: ':' base_list { $$=$2; }
;
base_list : base_list ',' base_specifier
| base_specifier
;
qt_macro_name: IDENTIFIER '(' IDENTIFIER ')'
{ $$ = stradd( $1, "(", $3, ")" ); }
| IDENTIFIER '(' simple_type_name ')'
{ $$ = stradd( $1, "(", $3, ")" ); }
;
base_specifier: complete_class_name {$$=$1;}
| VIRTUAL access_specifier complete_class_name {$$=$3;}
| VIRTUAL complete_class_name {$$=$2;}
| access_specifier VIRTUAL complete_class_name {$$=$3;}
| access_specifier complete_class_name {$$=$2;}
| qt_macro_name {$$=$1;}
| VIRTUAL access_specifier qt_macro_name {$$=$3;}
| VIRTUAL qt_macro_name {$$=$2;}
| access_specifier VIRTUAL qt_macro_name {$$=$3;}
| access_specifier qt_macro_name {$$=$2;}
;
access_specifier: PRIVATE { $$=_PRIVATE; }
| PROTECTED { $$=_PROTECTED; }
| PUBLIC { $$=_PUBLIC; }
;
operator_name: decl_specs_opt IDENTIFIER ptr_operators_opt
| decl_specs_opt simple_type_name ptr_operators_opt
| '+'
| '-'
| '*'
| '/'
| '%'
| '^'
| '&'
| '|'
| '~'
| '!'
| '='
| '<'
| '>'
| '+' '='
| '-' '='
| '*' '='
| '/' '='
| '%' '='
| '^' '='
| '&' '='
| '|' '='
| '~' '='
| '!' '='
| '=' '='
| '<' '='
| '>' '='
| '<' '<'
| '>' '>'
| '<' '<' '='
| '>' '>' '='
| '&' '&'
| '|' '|'
| '+' '+'
| '-' '-'
| ','
| '-' '>' '*'
| '-' '>'
| '(' ')'
| '[' ']'
;
opt_virtual: /* empty */
| VIRTUAL
;
type_and_name: type_name fct_name
{ tmpFunc->type = $1;
tmpFunc->name = $2; }
| fct_name
{ tmpFunc->type = "int";
tmpFunc->name = $1;
if ( tmpFunc->name == className )
func_warn( "Constructors cannot be"
" signals or slots.");
}
| opt_virtual '~' fct_name
{ tmpFunc->type = "void";
tmpFunc->name = "~";
tmpFunc->name += $3;
func_warn( "Destructors cannot be"
" signals or slots.");
}
| decl_specs type_name decl_specs_opt
ptr_operators_opt fct_name
{
char *tmp =
straddSpc($1,$2,$3,$4);
tmpFunc->type = rmWS(tmp);
delete tmp;
tmpFunc->name = $5; }
| decl_specs type_name /* probably friend decl */
{ skipFunc = TRUE; }
| type_name ptr_operators fct_name
{ tmpFunc->type =
straddSpc($1,$2);
tmpFunc->name = $3; }
| type_name decl_specs ptr_operators_opt
fct_name
{ tmpFunc->type =
straddSpc($1,$2,$3);
tmpFunc->name = $4; }
| type_name OPERATOR operator_name
{ operatorError(); }
| OPERATOR operator_name
{ operatorError(); }
| decl_specs type_name decl_specs_opt
ptr_operators_opt OPERATOR operator_name
{ operatorError(); }
| type_name ptr_operators OPERATOR operator_name
{ operatorError(); }
| type_name decl_specs ptr_operators_opt
OPERATOR operator_name
{ operatorError(); }
;
signal_or_slot: type_and_name fct_decl opt_semicolons
| type_and_name opt_bitfield ';' opt_semicolons
{ func_warn("Variable as signal or slot."); }
| type_and_name opt_bitfield ','member_declarator_list
';' opt_semicolons
{ func_warn("Variable as signal or slot."); }
| enum_specifier opt_identifier ';' opt_semicolons
{ func_warn("Enum declaration as signal or"
" slot."); }
| USING complete_class_name ';' opt_semicolons
{ func_warn("Using declaration as signal or"
" slot."); }
| USING NAMESPACE complete_class_name ';' opt_semicolons
{ func_warn("Using declaration as signal or"
" slot."); }
| NAMESPACE IDENTIFIER '{'
{ classPLevel++;
moc_err("Namespace declaration as signal or"
" slot."); }
| nested_class_head ';' opt_semicolons
{ func_warn("Class declaration as signal or slot.");}
| nested_class_head
'{' { func_warn("Class declaration as signal or slot.");
BEGIN IN_FCT; fctLevel=1;
}
'}' { BEGIN QT_DEF; }
';' opt_semicolons
;
member_declarator_list: member_declarator
| member_declarator_list ',' member_declarator
;
member_declarator: declarator
| IDENTIFIER ':' { expLevel = 0; }
const_expression
| ':' { expLevel = 0; }
const_expression
;
opt_bitfield: /* empty */
| ':' { expLevel = 0; }
const_expression
;
enum_specifier: ENUM enum_tail
;
/* optional final comma at the end of an enum list. Not really C++ but
some people still use it */
opt_komma: /*empty*/
| ','
;
enum_tail: IDENTIFIER '{' enum_list opt_komma
'}' { BEGIN QT_DEF;
if ( tmpAccessPerm == _PUBLIC) {
tmpEnum->name = $1;
addEnum();
}
}
| '{' enum_list opt_komma
'}' { tmpEnum->clear();}
;
opt_identifier: /* empty */
| IDENTIFIER
;
enum_in_class_tail: IDENTIFIER IDENTIFIER
| enum_tail opt_identifier
;
enum_list: /* empty */
| enumerator
| enum_list ',' enumerator
;
enumerator: IDENTIFIER { if ( tmpAccessPerm == _PUBLIC) tmpEnum->append( $1 ); }
| IDENTIFIER '=' { expLevel=0; }
enumerator_expression { if ( tmpAccessPerm == _PUBLIC) tmpEnum->append( $1 ); }
prop_access_function: IDENTIFIER { $$ = $1; }
| '0' { $$ = ""; }
;
%%
#if defined(_OS_WIN32_)
#include <io.h>
#undef isatty
extern "C" int hack_isatty( int )
{
return 0;
}
#define isatty hack_isatty
#else
#include <unistd.h>
#endif
#include "lex.yy.c"
void init(); // initialize
void initClass(); // prepare for new class
void generateClass(); // generate C++ code for class
void initExpression(); // prepare for new expression
QCString combinePath( const char *, const char * );
QCString fileName; // file name
QCString outputFile; // output file name
QCString includeFile; // name of #include file
QCString includePath; // #include file path
QCString qtPath; // #include qt file path
bool noInclude = FALSE; // no #include <filename>
bool generatedCode = FALSE; // no code generated
bool mocError = FALSE; // moc parsing error occurred
QCString className; // name of parsed class
QCString superclassName; // name of super class
FuncList signals; // signal interface
FuncList slots; // slots interface
FuncList propfuncs; // all possible property access functions
FuncList funcs( TRUE ); // all parsed functions, including signals
EnumList enums; // enums used in properties
PropList props; // list of all properties
ClassInfoList infos; // list of all class infos
FILE *out; // output file
int yyparse();
void replace( char *s, char c1, char c2 );
int main( int argc, char **argv )
{
bool autoInclude = TRUE;
char *error = 0;
qtPath = "";
for ( int n=1; n<argc && error==0; n++ ) {
QCString arg = argv[n];
if ( arg[0] == '-' ) { // option
QCString opt = &arg[1];
if ( opt[0] == 'o' ) { // output redirection
if ( opt[1] == '\0' ) {
if ( !(n < argc-1) ) {
error = "Missing output-file name";
break;
}
outputFile = argv[++n];
} else
outputFile = &opt[1];
} else if ( opt == "i" ) { // no #include statement
noInclude = TRUE;
autoInclude = FALSE;
} else if ( opt[0] == 'f' ) { // produce #include statement
noInclude = FALSE;
autoInclude = FALSE;
if ( opt[1] ) { // -fsomething.h
includeFile = &opt[1];
}
} else if ( opt[0] == 'p' ) { // include file path
if ( opt[1] == '\0' ) {
if ( !(n < argc-1) ) {
error = "Missing path name for the -p option.";
break;
}
includePath = argv[++n];
} else {
includePath = &opt[1];
}
} else if ( opt[0] == 'q' ) { // qt include file path
if ( opt[1] == '\0' ) {
if ( !(n < argc-1) ) {
error = "Missing path name for the -q option.";
break;
}
qtPath = argv[++n];
} else {
qtPath = &opt[1];
}
replace(qtPath.data(),'\\','/');
if ( qtPath.right(1) != "/" )
qtPath += '/';
} else if ( opt == "k" ) { // don't stop on errors
errorControl = TRUE;
} else if ( opt == "nw" ) { // don't display warnings
displayWarnings = FALSE;
} else if ( opt == "ne" ) { // don't do enums
doEnums = FALSE;
} else if ( opt == "ldbg" ) { // lex debug output
lexDebug = TRUE;
} else if ( opt == "ydbg" ) { // yacc debug output
yydebug = TRUE;
} else {
error = "Invalid argument";
}
} else {
if ( !fileName.isNull() ) // can handle only one file
error = "Too many input files specified";
else
fileName = arg.copy();
}
}
if ( autoInclude ) {
int ppos = fileName.findRev('.');
if ( ppos != -1 && tolower( fileName[ppos + 1] ) == 'h' )
noInclude = FALSE;
else
noInclude = TRUE;
}
if ( !fileName.isEmpty() && !outputFile.isEmpty() &&
includeFile.isEmpty() && includePath.isEmpty() ) {
includeFile = combinePath(fileName,outputFile);
}
if ( includeFile.isEmpty() )
includeFile = fileName.copy();
if ( !includePath.isEmpty() ) {
if ( includePath.right(1) != "/" )
includePath += '/';
includeFile = includePath + includeFile;
}
if ( fileName.isNull() && !error ) {
fileName = "standard input";
yyin = stdin;
} else if ( argc < 2 || error ) { // incomplete/wrong args
fprintf( stderr, "Qt meta object compiler\n" );
if ( error )
fprintf( stderr, "moc: %s\n", error );
fprintf( stderr, "Usage: moc [options] <header-file>\n"
"\t-o file Write output to file rather than stdout\n"
"\t-i Do not generate an #include statement\n"
"\t-f[file] Force #include, optional file name\n"
"\t-p path Path prefix for included file\n"
"\t-k Do not stop on errors\n"
"\t-nw Do not display warnings\n"
"\t-ne Do not scan for enumeration declarations\n"
);
return 1;
} else {
yyin = fopen( (const char *)fileName, "r" );
if ( !yyin ) {
fprintf( stderr, "moc: %s: No such file\n", (const char*)fileName);
return 1;
}
}
if ( !outputFile.isEmpty() ) { // output file specified
out = fopen( (const char *)outputFile, "w" ); // create output file
if ( !out ) {
fprintf( stderr, "moc: Cannot create %s\n",
(const char*)outputFile );
return 1;
}
} else { // use stdout
out = stdout;
}
init();
yyparse();
fclose( yyin );
if ( !outputFile.isNull() )
fclose( out );
if ( !generatedCode && displayWarnings && !mocError ) {
fprintf( stderr, "%s:%d: Warning: %s\n", fileName.data(), 0,
"No relevant classes found. No output generated." );
}
slots.clear();
signals.clear();
propfuncs.clear();
funcs.clear();
infos.clear();
props.clear();
infos.clear();
return mocError ? 1 : 0;
}
void replace( char *s, char c1, char c2 )
{
if ( !s )
return;
while ( *s ) {
if ( *s == c1 )
*s = c2;
s++;
}
}
/*
This function looks at two file names and returns the name of the
infile, with a path relative to outfile. Examples:
/tmp/abc /tmp/bcd -> abc
xyz/a/bc xyz/b/ac -> ../a/bc
/tmp/abc xyz/klm -) /tmp/abc
*/
QCString combinePath( const char *infile, const char *outfile )
{
QCString a = infile; replace(a.data(),'\\','/');
QCString b = outfile; replace(b.data(),'\\','/');
a = a.stripWhiteSpace();
b = b.stripWhiteSpace();
QCString r;
int i = 0;
int ncommondirs = 0;
while ( a[i] && a[i] == b[i] ) {
if ( a[i] == '/' && i > 0 )
ncommondirs++;
i++;
}
if ( ncommondirs > 0 ) { // common base directory
while ( i>=0 ) {
if ( a[i] == '/' && b[i] == '/' )
break;
--i;
}
++i;
a = &a[i];
b = &b[i];
} else {
if ( (a[0] == '/') || (isalpha(a[0]) && a[1] == ':') )
return a;
b = &b[i];
}
i = b.contains('/');
while ( i-- > 0 )
r += "../";
r += a;
return r;
}
#define getenv hack_getenv // workaround for byac
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic