src/corelib/kernel/qmetaobject_p.h
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QMETAOBJECT_P_H
       
    43 #define QMETAOBJECT_P_H
       
    44 
       
    45 //
       
    46 //  W A R N I N G
       
    47 //  -------------
       
    48 //
       
    49 // This file is not part of the Qt API.  It exists for the convenience
       
    50 // of moc.  This header file may change from version to version without notice,
       
    51 // or even be removed.
       
    52 //
       
    53 // We mean it.
       
    54 //
       
    55 
       
    56 #include <QtCore/qglobal.h>
       
    57 #include <QtCore/qobjectdefs.h>
       
    58 
       
    59 QT_BEGIN_NAMESPACE
       
    60 
       
    61 enum PropertyFlags  {
       
    62     Invalid = 0x00000000,
       
    63     Readable = 0x00000001,
       
    64     Writable = 0x00000002,
       
    65     Resettable = 0x00000004,
       
    66     EnumOrFlag = 0x00000008,
       
    67     StdCppSet = 0x00000100,
       
    68 //     Override = 0x00000200,
       
    69     Constant = 0x00000400,
       
    70     Final = 0x00000800,
       
    71     Designable = 0x00001000,
       
    72     ResolveDesignable = 0x00002000,
       
    73     Scriptable = 0x00004000,
       
    74     ResolveScriptable = 0x00008000,
       
    75     Stored = 0x00010000,
       
    76     ResolveStored = 0x00020000,
       
    77     Editable = 0x00040000,
       
    78     ResolveEditable = 0x00080000,
       
    79     User = 0x00100000,
       
    80     ResolveUser = 0x00200000,
       
    81     Notify = 0x00400000
       
    82 };
       
    83 
       
    84 enum MethodFlags  {
       
    85     AccessPrivate = 0x00,
       
    86     AccessProtected = 0x01,
       
    87     AccessPublic = 0x02,
       
    88     AccessMask = 0x03, //mask
       
    89 
       
    90     MethodMethod = 0x00,
       
    91     MethodSignal = 0x04,
       
    92     MethodSlot = 0x08,
       
    93     MethodConstructor = 0x0c,
       
    94     MethodTypeMask = 0x0c,
       
    95 
       
    96     MethodCompatibility = 0x10,
       
    97     MethodCloned = 0x20,
       
    98     MethodScriptable = 0x40
       
    99 };
       
   100 
       
   101 enum MetaObjectFlags {
       
   102     DynamicMetaObject = 0x01
       
   103 };
       
   104 
       
   105 class QMutex;
       
   106 
       
   107 struct QMetaObjectPrivate
       
   108 {
       
   109     int revision;
       
   110     int className;
       
   111     int classInfoCount, classInfoData;
       
   112     int methodCount, methodData;
       
   113     int propertyCount, propertyData;
       
   114     int enumeratorCount, enumeratorData;
       
   115     int constructorCount, constructorData; //since revision 2
       
   116     int flags; //since revision 3
       
   117     int signalCount; //since revision 4
       
   118 
       
   119     static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
       
   120     { return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
       
   121 
       
   122     static int indexOfSignalRelative(const QMetaObject **baseObject, const char* name);
       
   123     static int originalClone(const QMetaObject *obj, int local_method_index);
       
   124 
       
   125 #ifndef QT_NO_QOBJECT
       
   126     //defined in qobject.cpp
       
   127     static bool connect(const QObject *sender, int signal_index,
       
   128                         const QObject *receiver, int method_index,
       
   129                         int type = 0, int *types = 0);
       
   130     static bool disconnect(const QObject *sender, int signal_index,
       
   131                            const QObject *receiver, int method_index);
       
   132     static inline bool disconnectHelper(QObjectPrivate::Connection *c,
       
   133                                         const QObject *receiver, int method_index,
       
   134                                         QMutex *senderMutex);
       
   135 #endif
       
   136 };
       
   137 
       
   138 #ifndef UTILS_H
       
   139 // mirrored in moc's utils.h
       
   140 static inline bool is_ident_char(char s)
       
   141 {
       
   142     return ((s >= 'a' && s <= 'z')
       
   143             || (s >= 'A' && s <= 'Z')
       
   144             || (s >= '0' && s <= '9')
       
   145             || s == '_'
       
   146        );
       
   147 }
       
   148 
       
   149 static inline bool is_space(char s)
       
   150 {
       
   151     return (s == ' ' || s == '\t');
       
   152 }
       
   153 #endif
       
   154 
       
   155 // This code is shared with moc.cpp
       
   156 static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixScope = false, bool adjustConst = true)
       
   157 {
       
   158     int len = e - t;
       
   159     /*
       
   160       Convert 'char const *' into 'const char *'. Start at index 1,
       
   161       not 0, because 'const char *' is already OK.
       
   162     */
       
   163     QByteArray constbuf;
       
   164     for (int i = 1; i < len; i++) {
       
   165         if ( t[i] == 'c'
       
   166              && strncmp(t + i + 1, "onst", 4) == 0
       
   167              && (i + 5 >= len || !is_ident_char(t[i + 5]))
       
   168              && !is_ident_char(t[i-1])
       
   169              ) {
       
   170             constbuf = QByteArray(t, len);
       
   171             if (is_space(t[i-1]))
       
   172                 constbuf.remove(i-1, 6);
       
   173             else
       
   174                 constbuf.remove(i, 5);
       
   175             constbuf.prepend("const ");
       
   176             t = constbuf.data();
       
   177             e = constbuf.data() + constbuf.length();
       
   178             break;
       
   179         }
       
   180         /*
       
   181           We musn't convert 'char * const *' into 'const char **'
       
   182           and we must beware of 'Bar<const Bla>'.
       
   183         */
       
   184         if (t[i] == '&' || t[i] == '*' ||t[i] == '<')
       
   185             break;
       
   186     }
       
   187     if (adjustConst && e > t + 6 && strncmp("const ", t, 6) == 0) {
       
   188         if (*(e-1) == '&') { // treat const reference as value
       
   189             t += 6;
       
   190             --e;
       
   191         } else if (is_ident_char(*(e-1))) { // treat const value as value
       
   192             t += 6;
       
   193         }
       
   194     }
       
   195     QByteArray result;
       
   196     result.reserve(len);
       
   197 
       
   198 #if 1
       
   199     // consume initial 'const '
       
   200     if (strncmp("const ", t, 6) == 0) {
       
   201         t+= 6;
       
   202         result += "const ";
       
   203     }
       
   204 #endif
       
   205 
       
   206     // some type substitutions for 'unsigned x'
       
   207     if (strncmp("unsigned", t, 8) == 0) {
       
   208         // make sure "unsigned" is an isolated word before making substitutions
       
   209         if (!t[8] || !is_ident_char(t[8])) {
       
   210             if (strncmp(" int", t+8, 4) == 0) {
       
   211                 t += 8+4;
       
   212                 result += "uint";
       
   213             } else if (strncmp(" long", t+8, 5) == 0) {
       
   214                 if ((strlen(t + 8 + 5) < 4 || strncmp(t + 8 + 5, " int", 4) != 0) // preserve '[unsigned] long int'
       
   215                     && (strlen(t + 8 + 5) < 5 || strncmp(t + 8 + 5, " long", 5) != 0) // preserve '[unsigned] long long'
       
   216                    ) {
       
   217                     t += 8+5;
       
   218                     result += "ulong";
       
   219                 }
       
   220             } else if (strncmp(" short", t+8, 6) != 0  // preserve unsigned short
       
   221                 && strncmp(" char", t+8, 5) != 0) {    // preserve unsigned char
       
   222                 //  treat rest (unsigned) as uint
       
   223                 t += 8;
       
   224                 result += "uint";
       
   225             }
       
   226         }
       
   227     } else {
       
   228         // discard 'struct', 'class', and 'enum'; they are optional
       
   229         // and we don't want them in the normalized signature
       
   230         struct {
       
   231             const char *keyword;
       
   232             int len;
       
   233         } optional[] = {
       
   234             { "struct ", 7 },
       
   235             { "class ", 6 },
       
   236             { "enum ", 5 },
       
   237             { 0, 0 }
       
   238         };
       
   239         int i = 0;
       
   240         do {
       
   241             if (strncmp(optional[i].keyword, t, optional[i].len) == 0) {
       
   242                 t += optional[i].len;
       
   243                 break;
       
   244             }
       
   245         } while (optional[++i].keyword != 0);
       
   246     }
       
   247 
       
   248     while (t != e) {
       
   249         char c = *t++;
       
   250         if (fixScope && c == ':' && *t == ':' ) {
       
   251             ++t;
       
   252             c = *t++;
       
   253             int i = result.size() - 1;
       
   254             while (i >= 0 && is_ident_char(result.at(i)))
       
   255                 --i;
       
   256             result.resize(i + 1);
       
   257         }
       
   258         result += c;
       
   259         if (c == '<') {
       
   260             //template recursion
       
   261             const char* tt = t;
       
   262             int templdepth = 1;
       
   263             while (t != e) {
       
   264                 c = *t++;
       
   265                 if (c == '<')
       
   266                     ++templdepth;
       
   267                 if (c == '>')
       
   268                     --templdepth;
       
   269                 if (templdepth == 0) {
       
   270                     result += normalizeTypeInternal(tt, t-1, fixScope, false);
       
   271                     result += c;
       
   272                     if (*t == '>')
       
   273                         result += ' '; // avoid >>
       
   274                     break;
       
   275                 }
       
   276             }
       
   277         }
       
   278     }
       
   279 
       
   280     return result;
       
   281 }
       
   282 
       
   283 
       
   284 QT_END_NAMESPACE
       
   285 
       
   286 #endif
       
   287