qtbindings 4.6.3.4 → 4.8.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/KNOWN_ISSUES.txt +19 -5
  2. data/README.txt +119 -93
  3. data/Rakefile +28 -27
  4. data/examples/desktop/systray/window.rb +43 -47
  5. data/examples/draganddrop/dropsite/dropsitewidget.rb +10 -9
  6. data/examples/mainwindows/mdi/mainwindow.rb +4 -4
  7. data/examples/network/broadcastsender/sender.rb +3 -1
  8. data/examples/qtscribble/scribble.rb +270 -0
  9. data/examples/ruboids/LICENSE.txt +58 -0
  10. data/examples/run_all.rb +1 -0
  11. data/examples/textedit/textedit.rb +150 -0
  12. data/examples/widgets/scribble/scribblearea.rb +19 -19
  13. data/ext/cmake/modules/BasicFindPackageVersion.cmake.in +30 -0
  14. data/ext/cmake/modules/FindLibraryWithDebug.cmake +113 -0
  15. data/ext/cmake/modules/FindPhonon.cmake +71 -0
  16. data/ext/cmake/modules/FindQImageBlitz.cmake +51 -0
  17. data/ext/cmake/modules/FindRuby.cmake +17 -17
  18. data/ext/cmake/modules/MacroOptionalFindPackage.cmake +6 -26
  19. data/ext/cmake/modules/MacroWriteBasicCMakeVersionFile.cmake +22 -0
  20. data/ext/cmake/modules/SmokeConfig.cmake.in +109 -0
  21. data/ext/generator/cmake/BasicFindPackageVersion.cmake.in +30 -0
  22. data/ext/generator/cmake/CMakeLists.txt +24 -0
  23. data/ext/generator/cmake/FindLibraryWithDebug.cmake +113 -0
  24. data/ext/generator/cmake/FindPhonon.cmake +71 -0
  25. data/ext/generator/cmake/FindQImageBlitz.cmake +51 -0
  26. data/ext/generator/cmake/FindQScintilla.cmake +57 -0
  27. data/ext/generator/cmake/FindQwt5.cmake +104 -0
  28. data/ext/generator/cmake/HandleImportedTargetsInCMakeRequiredLibraries.cmake +85 -0
  29. data/ext/generator/cmake/MacroLogFeature.cmake +146 -0
  30. data/ext/generator/cmake/MacroOptionalAddBindings.cmake +47 -0
  31. data/ext/generator/cmake/MacroOptionalFindPackage.cmake +28 -0
  32. data/ext/generator/cmake/MacroWriteBasicCMakeVersionFile.cmake +22 -0
  33. data/ext/generator/cmake/SmokeConfig.cmake.in +109 -0
  34. data/ext/generator/config.h +25 -0
  35. data/ext/generator/generatorpreprocessor.cpp +60 -41
  36. data/ext/generator/generators/dump/CMakeLists.txt +5 -0
  37. data/ext/generator/generators/smoke/CMakeLists.txt +5 -0
  38. data/ext/generator/generators/smoke/globals.h +3 -1
  39. data/ext/generator/generators/smoke/helpers.cpp +21 -2
  40. data/ext/generator/generators/smoke/writeSmokeDataFile.cpp +26 -1
  41. data/ext/generator/main.cpp +5 -1
  42. data/ext/generator/options.cpp +1 -0
  43. data/ext/generator/options.h +1 -0
  44. data/ext/generator/parser/CMakeLists.txt +10 -1
  45. data/ext/generator/parser/parser.cpp +6 -6
  46. data/ext/generator/parser/parser.h +2 -12
  47. data/ext/generator/parser/parsesession.cpp +1 -0
  48. data/ext/generator/parser/rpp/CMakeLists.txt +6 -0
  49. data/ext/generator/parser/rpp/chartools.cpp +3 -3
  50. data/ext/generator/parser/rpp/chartools.h +3 -1
  51. data/ext/generator/parser/rpp/pp-scanner.cpp +2 -1
  52. data/ext/generator/parser/rpp/tests/CMakeLists.txt +4 -0
  53. data/ext/generator/parser/tests/CMakeLists.txt +16 -0
  54. data/ext/generator/smoke.h +557 -0
  55. data/ext/generator/smokegen_string.h +43 -0
  56. data/ext/generator/type.cpp +15 -6
  57. data/ext/generator/type_compiler.cpp +2 -0
  58. data/ext/ruby/qtruby/src/qtruby.cpp +147 -143
  59. data/ext/ruby/qttest/qttesthandlers.cpp +1 -0
  60. data/ext/smoke/qtcore/QtGuess.txt +23 -25
  61. data/ext/smoke/qtcore/smokeconfig.xml +1 -0
  62. data/ext/smoke/qtdbus/smokeconfig.xml +2 -0
  63. data/ext/smoke/qtgui/smokeconfig.xml +14 -4
  64. data/ext/smoke/qthelp/smokeconfig.xml +1 -0
  65. data/ext/smoke/qtmultimedia/smokeconfig.xml +1 -0
  66. data/ext/smoke/qtnetwork/smokeconfig.xml +2 -0
  67. data/ext/smoke/qtopengl/smokeconfig.xml +1 -0
  68. data/ext/smoke/qtsql/smokeconfig.xml +1 -0
  69. data/ext/smoke/qtsvg/smokeconfig.xml +1 -0
  70. data/ext/smoke/qtwebkit/smokeconfig.xml +3 -0
  71. data/extconf.rb +37 -23
  72. data/lib/Qt/qtruby4.rb +4 -4
  73. data/lib/Qt4.rb +1 -1
  74. data/lib/qtbindings_version.rb +2 -2
  75. metadata +50 -40
@@ -37,6 +37,8 @@
37
37
  #include "generatorpreprocessor.h"
38
38
  #include "generatorvisitor.h"
39
39
  #include "options.h"
40
+ #include "config.h"
41
+
40
42
 
41
43
  typedef int (*GenerateFn)();
42
44
 
@@ -72,6 +74,8 @@ int main(int argc, char **argv)
72
74
  bool hasCommandLineGenerator = false;
73
75
  QStringList classes;
74
76
 
77
+ ParserOptions::notToBeResolved << "FILE";
78
+
75
79
  for (int i = 1; i < args.count(); i++) {
76
80
  if ((args[i] == "-I" || args[i] == "-d" || args[i] == "-dm" ||
77
81
  args[i] == "-g" || args[i] == "-config") && i + 1 >= args.count())
@@ -165,7 +169,7 @@ int main(int argc, char **argv)
165
169
  lib.load();
166
170
  if (!lib.isLoaded()) {
167
171
  lib.unload();
168
- lib.setFileName(app.applicationDirPath() + "/../lib/smokegen/generator_" + generator);
172
+ lib.setFileName(app.applicationDirPath() + "/../lib" + LIB_SUFFIX + "/smokegen/generator_" + generator);
169
173
  lib.load();
170
174
  }
171
175
  if (!lib.isLoaded()) {
@@ -28,5 +28,6 @@ QFileInfo ParserOptions::definesList;
28
28
  QList<QFileInfo>ParserOptions:: headerList;
29
29
  QList<QDir> ParserOptions::includeDirs;
30
30
  bool ParserOptions::resolveTypedefs = false;
31
+ QList<QString> ParserOptions::notToBeResolved;
31
32
  bool ParserOptions::qtMode = false;
32
33
  QStringList ParserOptions::dropMacros;
@@ -38,6 +38,7 @@ struct GENERATOR_EXPORT ParserOptions
38
38
  static QList<QFileInfo> headerList;
39
39
  static QList<QDir> includeDirs;
40
40
  static bool resolveTypedefs;
41
+ static QList<QString> notToBeResolved;
41
42
  static bool qtMode;
42
43
  static QStringList dropMacros;
43
44
  };
@@ -38,4 +38,13 @@ add_definitions(-D__CPPPARSER_BUILDING)
38
38
  add_library(cppparser SHARED ${cppparser_LIB_SRCS})
39
39
  target_link_libraries(cppparser ${QT_QTCORE_LIBRARY})
40
40
 
41
- install(TARGETS cppparser DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX} )
41
+ install(TARGETS cppparser LIBRARY DESTINATION ${LIB_INSTALL_DIR}
42
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
43
+ RUNTIME DESTINATION bin)
44
+ if (WIN32)
45
+ # Realign the stack, for compatibility with an older ABI.
46
+ set_target_properties (cppparser PROPERTIES COMPILE_FLAGS -mstackrealign)
47
+
48
+ # Get rid of the "lib" prefix on archives/DLLs in Windows.
49
+ set_target_properties(cppparser PROPERTIES PREFIX "" IMPORT_PREFIX "")
50
+ endif (WIN32)
@@ -241,18 +241,18 @@ void Parser::clear()
241
241
 
242
242
  void Parser::addTokenMarkers(size_t tokenNumber, Parser::TokenMarkers markers)
243
243
  {
244
- hash_map<size_t, TokenMarkers>::iterator it = m_tokenMarkers.find(tokenNumber);
244
+ QHash<size_t, TokenMarkers>::iterator it = m_tokenMarkers.find(tokenNumber);
245
245
  if(it != m_tokenMarkers.end())
246
- (*it).second = (TokenMarkers)((*it).second | markers);
246
+ *it = (TokenMarkers)(*it | markers);
247
247
  else
248
- m_tokenMarkers.insert(std::make_pair(tokenNumber, markers));
248
+ m_tokenMarkers.insert(tokenNumber, markers);
249
249
  }
250
250
 
251
251
  Parser::TokenMarkers Parser::tokenMarkers(size_t tokenNumber) const
252
252
  {
253
- hash_map<size_t, TokenMarkers>::const_iterator it = m_tokenMarkers.find(tokenNumber);
253
+ QHash<size_t, TokenMarkers>::const_iterator it = m_tokenMarkers.find(tokenNumber);
254
254
  if(it != m_tokenMarkers.end())
255
- return (*it).second;
255
+ return *it;
256
256
  else
257
257
  return None;
258
258
  }
@@ -369,7 +369,7 @@ void Parser::reportError(const QString& msg)
369
369
  Problem *p = new Problem;
370
370
  p->file = session->url().str();
371
371
  p->position = position;
372
- p->description = msg + " : " + QString::fromUtf8(lineFromContents(session->contents(), p->position.line));
372
+ p->description = msg + " : " + QString::fromUtf8(lineFromContents(session->size(), session->contents(), p->position.line));
373
373
  p->source = Problem::Source_Parser;
374
374
  control->reportProblem(p);
375
375
  }
@@ -29,17 +29,7 @@
29
29
  #include <QtCore/QQueue>
30
30
  #include <QtCore/QSet>
31
31
  #include <QtCore/QString>
32
- #ifdef Q_CC_MSVC
33
- #include <hash_map>
34
- using namespace stdext;
35
- #elif defined(Q_CC_GNU)
36
- #include <ext/hash_map>
37
- using namespace __gnu_cxx;
38
- #else
39
- #include <map>
40
- // template typedefs aren't supported by C++ - resort to a #define for now.
41
- #define hash_map std::map
42
- #endif
32
+ #include <QtCore/QHash>
43
33
 
44
34
  class TokenStream;
45
35
  class Control;
@@ -265,7 +255,7 @@ private:
265
255
  Comment m_currentComment;
266
256
  CommentStore m_commentStore;
267
257
 
268
- hash_map<size_t, TokenMarkers> m_tokenMarkers;
258
+ QHash<size_t, TokenMarkers> m_tokenMarkers;
269
259
  int _M_problem_count;
270
260
  int _M_max_problem_count;
271
261
  ParseSession* session;
@@ -19,6 +19,7 @@
19
19
  #include "parsesession.h"
20
20
 
21
21
  #include "rpp/pp-location.h"
22
+ #include "rpp/pp-environment.h"
22
23
  #include "lexer.h"
23
24
  #include "memorypool.h"
24
25
  #include "problem.h"
@@ -22,6 +22,12 @@ set(kdevcpprpp_LIB_SRCS
22
22
  # to the plugin target
23
23
  kde4_add_library(kdev4cpprpp SHARED ${kdevcpprpp_LIB_SRCS})
24
24
  target_link_libraries(kdev4cpprpp ${KDE4_KDECORE_LIBS} ${KDEVPLATFORM_LANGUAGE_LIBRARY} ${KDE4_KTEXTEDITOR_LIBS} )
25
+
26
+ if (WIN32)
27
+ # Realign the stack, for compatibility with an older ABI.
28
+ set_target_properties (kdev4cpprpp PROPERTIES COMPILE_FLAGS -mstackrealign)
29
+ endif (WIN32)
30
+
25
31
  install(TARGETS kdev4cpprpp ${INSTALL_TARGETS_DEFAULT_ARGS} )
26
32
 
27
33
  ########### install files ###############
@@ -38,10 +38,10 @@ QByteArray stringFromContents(const PreprocessedContents& contents, int offset,
38
38
 
39
39
  #include <stdio.h>
40
40
 
41
- QByteArray lineFromContents(const uint* contents, int lineNumber) {
41
+ QByteArray lineFromContents(std::size_t size, const uint* contents, int lineNumber) {
42
42
  int a1 = 0;
43
43
  int lineCount = 0;
44
- while (lineCount < lineNumber) {
44
+ while (a1 < size && lineCount < lineNumber) {
45
45
  if (isNewline(contents[a1])) {
46
46
  lineCount++;
47
47
  }
@@ -49,7 +49,7 @@ QByteArray lineFromContents(const uint* contents, int lineNumber) {
49
49
  }
50
50
 
51
51
  int a2 = a1;
52
- while (!isNewline(contents[a2])) {
52
+ while (a2 < size && !isNewline(contents[a2])) {
53
53
  a2++;
54
54
  }
55
55
 
@@ -22,6 +22,8 @@
22
22
  #define CHARTOOLS
23
23
  #include <QChar>
24
24
 
25
+ #include <cstdlib>
26
+
25
27
  #include "../cppparser_export.h"
26
28
 
27
29
  template<class T>
@@ -83,7 +85,7 @@ CPPPARSER_EXPORT QByteArray stringFromContents(const PreprocessedContents& conte
83
85
  CPPPARSER_EXPORT QByteArray stringFromContents(const uint* contents, int count);
84
86
 
85
87
  ///Return the line at the given line number from the contents
86
- CPPPARSER_EXPORT QByteArray lineFromContents(const uint* contents, int lineNumber);
88
+ CPPPARSER_EXPORT QByteArray lineFromContents(std::size_t size, const uint* contents, int lineNumber);
87
89
 
88
90
  ///Returns a string that has a gap inserted between the tokens(for debugging)
89
91
  CPPPARSER_EXPORT QByteArray stringFromContentsWithGaps(const PreprocessedContents& contents, int offset = 0, int count = 0);
@@ -247,8 +247,9 @@ void pp_skip_char_literal::operator()(Stream& input, Stream& output)
247
247
  state = END;
248
248
  else if (input == '\\')
249
249
  state = QUOTE;
250
- break;
250
+
251
251
  ++inner_count;
252
+ break;
252
253
  case QUOTE:
253
254
  state = IN_STRING;
254
255
  break;
@@ -11,3 +11,7 @@ set(pp_SRCS
11
11
  kde4_add_executable(pp TEST ${pp_SRCS})
12
12
  target_link_libraries(pp ${KDE4_KDECORE_LIBS} kdev4cpprpp)
13
13
 
14
+ if (WIN32)
15
+ # Realign the stack, for compatibility with an older ABI.
16
+ set_target_properties (pp PROPERTIES COMPILE_FLAGS -mstackrealign)
17
+ endif (WIN32)
@@ -11,6 +11,12 @@ set(parsertest_SRCS test_parser.cpp)
11
11
 
12
12
  QT4_GENERATE_MOC(${parsertest_SRCS} test_parser.moc)
13
13
  add_executable(parsertest ${parsertest_SRCS} test_parser.moc)
14
+
15
+ if (WIN32)
16
+ # Realign the stack, for compatibility with an older ABI.
17
+ set_target_properties (parsertest PROPERTIES COMPILE_FLAGS -mstackrealign)
18
+ endif (WIN32)
19
+
14
20
  target_link_libraries(parsertest ${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY} cppparser)
15
21
 
16
22
  ########### next target ###############
@@ -19,6 +25,11 @@ set(generatortest_SRCS test_generator.cpp)
19
25
 
20
26
  QT4_GENERATE_MOC(${generatortest_SRCS} test_generator.moc)
21
27
  add_executable(generatortest ${generatortest_SRCS} test_generator.moc)
28
+ if (WIN32)
29
+ # Realign the stack, for compatibility with an older ABI.
30
+ set_target_properties (generatortest PROPERTIES COMPILE_FLAGS -mstackrealign)
31
+ endif (WIN32)
32
+
22
33
  target_link_libraries(generatortest ${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY} cppparser)
23
34
 
24
35
  ########### next target ###############
@@ -27,4 +38,9 @@ set(pooltest_SRCS test_pool.cpp)
27
38
 
28
39
  QT4_GENERATE_MOC(test_pool.h test_pool.moc)
29
40
  add_executable(pooltest ${pooltest_SRCS} test_pool.moc)
41
+ if (WIN32)
42
+ # Realign the stack, for compatibility with an older ABI.
43
+ set_target_properties (pooltest PROPERTIES COMPILE_FLAGS -mstackrealign)
44
+ endif (WIN32)
45
+
30
46
  target_link_libraries(pooltest ${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY} cppparser)
@@ -0,0 +1,557 @@
1
+ #ifndef SMOKE_H
2
+ #define SMOKE_H
3
+
4
+ #include <cstddef>
5
+ #include <cstring>
6
+ #include <string>
7
+ #include <map>
8
+
9
+ /*
10
+ Copyright (C) 2002, Ashley Winters <qaqortog@nwlink.com>
11
+ Copyright (C) 2007, Arno Rehn <arno@arnorehn.de>
12
+
13
+ BSD License
14
+
15
+ Redistribution and use in source and binary forms, with or
16
+ without modification, are permitted provided that the following
17
+ conditions are met:
18
+
19
+ Redistributions of source code must retain the above
20
+ copyright notice, this list of conditions and the following disclaimer.
21
+
22
+ Redistributions in binary form must reproduce the above
23
+ copyright notice, this list of conditions and the following
24
+ disclaimer in the documentation and/or other materials
25
+ provided with the distribution.>
26
+
27
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
28
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
30
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
31
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
33
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
38
+ THE POSSIBILITY OF SUCH DAMAGE.
39
+ */
40
+
41
+ #ifdef WIN32
42
+ // Define this when building a smoke lib that doesn't have any parents - else Smoke::classMap is not exported.
43
+ #ifdef BASE_SMOKE_BUILDING
44
+ #define BASE_SMOKE_EXPORT __declspec(dllexport)
45
+ #else
46
+ #define BASE_SMOKE_EXPORT __declspec(dllimport)
47
+ #endif
48
+ // Define this when building a smoke lib.
49
+ #ifdef SMOKE_BUILDING
50
+ #define SMOKE_EXPORT __declspec(dllexport)
51
+ #else
52
+ #define SMOKE_EXPORT __declspec(dllimport)
53
+ #endif
54
+ #define SMOKE_IMPORT __declspec(dllimport)
55
+ #else
56
+ #ifdef GCC_VISIBILITY
57
+ #define SMOKE_EXPORT __attribute__ ((visibility("default")))
58
+ #define BASE_SMOKE_EXPORT __attribute__ ((visibility("default")))
59
+ #else
60
+ #define SMOKE_EXPORT
61
+ #define BASE_SMOKE_EXPORT
62
+ #endif
63
+ #define SMOKE_IMPORT
64
+ #endif
65
+
66
+ class SmokeBinding;
67
+
68
+ class BASE_SMOKE_EXPORT Smoke {
69
+ private:
70
+ const char *module_name;
71
+
72
+ public:
73
+ union StackItem; // defined below
74
+ /**
75
+ * A stack is an array of arguments, passed to a method when calling it.
76
+ */
77
+ typedef StackItem* Stack;
78
+
79
+ enum EnumOperation {
80
+ EnumNew,
81
+ EnumDelete,
82
+ EnumFromLong,
83
+ EnumToLong
84
+ };
85
+
86
+ typedef short Index;
87
+ typedef void (*ClassFn)(Index method, void* obj, Stack args);
88
+ typedef void* (*CastFn)(void* obj, Index from, Index to);
89
+ typedef void (*EnumFn)(EnumOperation, Index, void*&, long&);
90
+
91
+ /**
92
+ * Describe one index in a given module.
93
+ */
94
+ struct ModuleIndex {
95
+ Smoke* smoke;
96
+ Index index;
97
+ ModuleIndex() : smoke(0), index(0) {}
98
+ ModuleIndex(Smoke * s, Index i) : smoke(s), index(i) {}
99
+
100
+ inline bool operator==(const Smoke::ModuleIndex& other) const {
101
+ return index == other.index && smoke == other.smoke;
102
+ }
103
+
104
+ inline bool operator!=(const Smoke::ModuleIndex& other) const {
105
+ return index != other.index || smoke != other.smoke;
106
+ }
107
+ };
108
+ /**
109
+ * A ModuleIndex with both fields set to 0.
110
+ */
111
+ static ModuleIndex NullModuleIndex;
112
+
113
+ typedef std::map<std::string, ModuleIndex> ClassMap;
114
+ static ClassMap classMap;
115
+
116
+ enum ClassFlags {
117
+ cf_constructor = 0x01, // has a constructor
118
+ cf_deepcopy = 0x02, // has copy constructor
119
+ cf_virtual = 0x04, // has virtual destructor
120
+ cf_namespace = 0x08, // is a namespace
121
+ cf_undefined = 0x10 // defined elsewhere
122
+ };
123
+ /**
124
+ * Describe one class.
125
+ */
126
+ struct Class {
127
+ const char *className; // Name of the class
128
+ bool external; // Whether the class is in another module
129
+ Index parents; // Index into inheritanceList
130
+ ClassFn classFn; // Calls any method in the class
131
+ EnumFn enumFn; // Handles enum pointers
132
+ unsigned short flags; // ClassFlags
133
+ unsigned int size;
134
+ };
135
+
136
+ enum MethodFlags {
137
+ mf_static = 0x01,
138
+ mf_const = 0x02,
139
+ mf_copyctor = 0x04, // Copy constructor
140
+ mf_internal = 0x08, // For internal use only
141
+ mf_enum = 0x10, // An enum value
142
+ mf_ctor = 0x20,
143
+ mf_dtor = 0x40,
144
+ mf_protected = 0x80,
145
+ mf_attribute = 0x100, // accessor method for a field
146
+ mf_property = 0x200, // accessor method of a property
147
+ mf_virtual = 0x400,
148
+ mf_purevirtual = 0x800,
149
+ mf_signal = 0x1000, // method is a signal
150
+ mf_slot = 0x2000, // method is a slot
151
+ mf_explicit = 0x4000 // method is an 'explicit' constructor
152
+ };
153
+ /**
154
+ * Describe one method of one class.
155
+ */
156
+ struct Method {
157
+ Index classId; // Index into classes
158
+ Index name; // Index into methodNames; real name
159
+ Index args; // Index into argumentList
160
+ unsigned char numArgs; // Number of arguments
161
+ unsigned short flags; // MethodFlags (const/static/etc...)
162
+ Index ret; // Index into types for the return type
163
+ Index method; // Passed to Class.classFn, to call method
164
+ };
165
+
166
+ /**
167
+ * One MethodMap entry maps the munged method prototype
168
+ * to the Method entry.
169
+ *
170
+ * The munging works this way:
171
+ * $ is a plain scalar
172
+ * # is an object
173
+ * ? is a non-scalar (reference to array or hash, undef)
174
+ *
175
+ * e.g. QApplication(int &, char **) becomes QApplication$?
176
+ */
177
+ struct MethodMap {
178
+ Index classId; // Index into classes
179
+ Index name; // Index into methodNames; munged name
180
+ Index method; // Index into methods
181
+ };
182
+
183
+ enum TypeFlags {
184
+ // The first 4 bits indicate the TypeId value, i.e. which field
185
+ // of the StackItem union is used.
186
+ tf_elem = 0x0F,
187
+
188
+ // Always only one of the next three flags should be set
189
+ tf_stack = 0x10, // Stored on the stack, 'type'
190
+ tf_ptr = 0x20, // Pointer, 'type*'
191
+ tf_ref = 0x30, // Reference, 'type&'
192
+ // Can | whatever ones of these apply
193
+ tf_const = 0x40 // const argument
194
+ };
195
+ /**
196
+ * One Type entry is one argument type needed by a method.
197
+ * Type entries are shared, there is only one entry for "int" etc.
198
+ */
199
+ struct Type {
200
+ const char *name; // Stringified type name
201
+ Index classId; // Index into classes. -1 for none
202
+ unsigned short flags; // TypeFlags
203
+ };
204
+
205
+ // We could just pass everything around using void* (pass-by-reference)
206
+ // I don't want to, though. -aw
207
+ union StackItem {
208
+ void* s_voidp;
209
+ bool s_bool;
210
+ signed char s_char;
211
+ unsigned char s_uchar;
212
+ short s_short;
213
+ unsigned short s_ushort;
214
+ int s_int;
215
+ unsigned int s_uint;
216
+ long s_long;
217
+ unsigned long s_ulong;
218
+ float s_float;
219
+ double s_double;
220
+ long s_enum;
221
+ void* s_class;
222
+ };
223
+ enum TypeId {
224
+ t_voidp,
225
+ t_bool,
226
+ t_char,
227
+ t_uchar,
228
+ t_short,
229
+ t_ushort,
230
+ t_int,
231
+ t_uint,
232
+ t_long,
233
+ t_ulong,
234
+ t_float,
235
+ t_double,
236
+ t_enum,
237
+ t_class,
238
+ t_last // number of pre-defined types
239
+ };
240
+
241
+ // Passed to constructor
242
+ /**
243
+ * The classes array defines every class for this module
244
+ */
245
+ Class *classes;
246
+ Index numClasses;
247
+
248
+ /**
249
+ * The methods array defines every method in every class for this module
250
+ */
251
+ Method *methods;
252
+ Index numMethods;
253
+
254
+ /**
255
+ * methodMaps maps the munged method prototypes
256
+ * to the methods entries.
257
+ */
258
+ MethodMap *methodMaps;
259
+ Index numMethodMaps;
260
+
261
+ /**
262
+ * Array of method names, for Method.name and MethodMap.name
263
+ */
264
+ const char **methodNames;
265
+ Index numMethodNames;
266
+
267
+ /**
268
+ * List of all types needed by the methods (arguments and return values)
269
+ */
270
+ Type *types;
271
+ Index numTypes;
272
+
273
+ /**
274
+ * Groups of Indexes (0 separated) used as super class lists.
275
+ * For classes with super classes: Class.parents = index into this array.
276
+ */
277
+ Index *inheritanceList;
278
+ /**
279
+ * Groups of type IDs (0 separated), describing the types of argument for a method.
280
+ * Method.args = index into this array.
281
+ */
282
+ Index *argumentList;
283
+ /**
284
+ * Groups of method prototypes with the same number of arguments, but different types.
285
+ * Used to resolve overloading.
286
+ */
287
+ Index *ambiguousMethodList;
288
+ /**
289
+ * Function used for casting from/to the classes defined by this module.
290
+ */
291
+ CastFn castFn;
292
+
293
+ /**
294
+ * Constructor
295
+ */
296
+ Smoke(const char *_moduleName,
297
+ Class *_classes, Index _numClasses,
298
+ Method *_methods, Index _numMethods,
299
+ MethodMap *_methodMaps, Index _numMethodMaps,
300
+ const char **_methodNames, Index _numMethodNames,
301
+ Type *_types, Index _numTypes,
302
+ Index *_inheritanceList,
303
+ Index *_argumentList,
304
+ Index *_ambiguousMethodList,
305
+ CastFn _castFn) :
306
+ module_name(_moduleName),
307
+ classes(_classes), numClasses(_numClasses),
308
+ methods(_methods), numMethods(_numMethods),
309
+ methodMaps(_methodMaps), numMethodMaps(_numMethodMaps),
310
+ methodNames(_methodNames), numMethodNames(_numMethodNames),
311
+ types(_types), numTypes(_numTypes),
312
+ inheritanceList(_inheritanceList),
313
+ argumentList(_argumentList),
314
+ ambiguousMethodList(_ambiguousMethodList),
315
+ castFn(_castFn)
316
+ {
317
+ for (Index i = 1; i <= numClasses; ++i) {
318
+ if (!classes[i].external) {
319
+ classMap[className(i)] = ModuleIndex(this, i);
320
+ }
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Returns the name of the module (e.g. "qt" or "kde")
326
+ */
327
+ inline const char *moduleName() {
328
+ return module_name;
329
+ }
330
+
331
+ inline void *cast(void *ptr, const ModuleIndex& from, const ModuleIndex& to) {
332
+ if (castFn == 0) {
333
+ return ptr;
334
+ }
335
+
336
+ if (from.smoke == to.smoke) {
337
+ return (*castFn)(ptr, from.index, to.index);
338
+ }
339
+
340
+ const Smoke::Class &klass = to.smoke->classes[to.index];
341
+ return (*castFn)(ptr, from.index, idClass(klass.className, true).index);
342
+ }
343
+
344
+ inline void *cast(void *ptr, Index from, Index to) {
345
+ if(!castFn) return ptr;
346
+ return (*castFn)(ptr, from, to);
347
+ }
348
+
349
+ // return classname directly
350
+ inline const char *className(Index classId) {
351
+ return classes[classId].className;
352
+ }
353
+
354
+ inline int leg(Index a, Index b) { // ala Perl's <=>
355
+ if(a == b) return 0;
356
+ return (a > b) ? 1 : -1;
357
+ }
358
+
359
+ inline Index idType(const char *t) {
360
+ Index imax = numTypes;
361
+ Index imin = 1;
362
+ Index icur = -1;
363
+ int icmp = -1;
364
+
365
+ while (imax >= imin) {
366
+ icur = (imin + imax) / 2;
367
+ icmp = strcmp(types[icur].name, t);
368
+ if (icmp == 0) {
369
+ return icur;
370
+ }
371
+
372
+ if (icmp > 0) {
373
+ imax = icur - 1;
374
+ } else {
375
+ imin = icur + 1;
376
+ }
377
+ }
378
+
379
+ return 0;
380
+ }
381
+
382
+ inline ModuleIndex idClass(const char *c, bool external = false) {
383
+ Index imax = numClasses;
384
+ Index imin = 1;
385
+ Index icur = -1;
386
+ int icmp = -1;
387
+
388
+ while (imax >= imin) {
389
+ icur = (imin + imax) / 2;
390
+ icmp = strcmp(classes[icur].className, c);
391
+ if (icmp == 0) {
392
+ if (classes[icur].external && !external) {
393
+ return NullModuleIndex;
394
+ } else {
395
+ return ModuleIndex(this, icur);
396
+ }
397
+ }
398
+
399
+ if (icmp > 0) {
400
+ imax = icur - 1;
401
+ } else {
402
+ imin = icur + 1;
403
+ }
404
+ }
405
+
406
+ return NullModuleIndex;
407
+ }
408
+
409
+ static inline ModuleIndex findClass(const char *c) {
410
+ ClassMap::iterator i = classMap.find(c);
411
+ if (i == classMap.end()) {
412
+ return NullModuleIndex;
413
+ } else {
414
+ return i->second;
415
+ }
416
+ }
417
+
418
+ inline ModuleIndex idMethodName(const char *m) {
419
+ Index imax = numMethodNames;
420
+ Index imin = 1;
421
+ Index icur = -1;
422
+ int icmp = -1;
423
+
424
+ while (imax >= imin) {
425
+ icur = (imin + imax) / 2;
426
+ icmp = strcmp(methodNames[icur], m);
427
+ if (icmp == 0) {
428
+ return ModuleIndex(this, icur);
429
+ }
430
+
431
+ if (icmp > 0) {
432
+ imax = icur - 1;
433
+ } else {
434
+ imin = icur + 1;
435
+ }
436
+ }
437
+
438
+ return NullModuleIndex;
439
+ }
440
+
441
+ inline ModuleIndex findMethodName(const char *c, const char *m) {
442
+ ModuleIndex mni = idMethodName(m);
443
+ if (mni.index) return mni;
444
+
445
+ ModuleIndex cmi = findClass(c);
446
+ if (cmi.smoke && cmi.smoke != this) {
447
+ return cmi.smoke->findMethodName(c, m);
448
+ } else if (cmi.smoke == this) {
449
+ if (!classes[cmi.index].parents) return NullModuleIndex;
450
+ for (Index p = classes[cmi.index].parents; inheritanceList[p]; p++) {
451
+ Index ci = inheritanceList[p];
452
+ const char* cName = className(ci);
453
+ ModuleIndex mi = classMap[cName].smoke->findMethodName(cName, m);
454
+ if (mi.index) return mi;
455
+ }
456
+ }
457
+ return NullModuleIndex;
458
+ }
459
+
460
+ inline ModuleIndex idMethod(Index c, Index name) {
461
+ Index imax = numMethodMaps;
462
+ Index imin = 1;
463
+ Index icur = -1;
464
+ int icmp = -1;
465
+
466
+ while (imax >= imin) {
467
+ icur = (imin + imax) / 2;
468
+ icmp = leg(methodMaps[icur].classId, c);
469
+ if (icmp == 0) {
470
+ icmp = leg(methodMaps[icur].name, name);
471
+ if (icmp == 0) {
472
+ return ModuleIndex(this, icur);
473
+ }
474
+ }
475
+
476
+ if (icmp > 0) {
477
+ imax = icur - 1;
478
+ } else {
479
+ imin = icur + 1;
480
+ }
481
+ }
482
+
483
+ return NullModuleIndex;
484
+ }
485
+
486
+ inline ModuleIndex findMethod(ModuleIndex c, ModuleIndex name) {
487
+ if (!c.index || !name.index) {
488
+ return NullModuleIndex;
489
+ } else if (name.smoke == this && c.smoke == this) {
490
+ ModuleIndex mi = idMethod(c.index, name.index);
491
+ if (mi.index) return mi;
492
+ } else if (c.smoke != this) {
493
+ return c.smoke->findMethod(c, name);
494
+ }
495
+
496
+ for (Index *i = inheritanceList + classes[c.index].parents; *i; ++i) {
497
+ const char *cName = className(*i);
498
+ ModuleIndex ci = findClass(cName);
499
+ if (!ci.smoke)
500
+ return NullModuleIndex;
501
+ ModuleIndex ni = ci.smoke->findMethodName(cName, name.smoke->methodNames[name.index]);
502
+ ModuleIndex mi = ci.smoke->findMethod(ci, ni);
503
+ if (mi.index) return mi;
504
+ }
505
+ return NullModuleIndex;
506
+ }
507
+
508
+ inline ModuleIndex findMethod(const char *c, const char *name) {
509
+ ModuleIndex idc = idClass(c);
510
+ if (!idc.smoke) idc = findClass(c);
511
+ if (!idc.smoke || !idc.index) return NullModuleIndex;
512
+ ModuleIndex idname = idc.smoke->findMethodName(c, name);
513
+ return idc.smoke->findMethod(idc, idname);
514
+ }
515
+
516
+ static inline bool isDerivedFrom(const ModuleIndex& classId, const ModuleIndex& baseClassId) {
517
+ return isDerivedFrom(classId.smoke, classId.index, baseClassId.smoke, baseClassId.index);
518
+ }
519
+
520
+ static inline bool isDerivedFrom(Smoke *smoke, Index classId, Smoke *baseSmoke, Index baseId) {
521
+ if (!classId || !baseId || !smoke || !baseSmoke)
522
+ return false;
523
+ if (smoke == baseSmoke && classId == baseId)
524
+ return true;
525
+
526
+ for(Index p = smoke->classes[classId].parents; smoke->inheritanceList[p]; p++) {
527
+ Class& cur = smoke->classes[smoke->inheritanceList[p]];
528
+ if (cur.external) {
529
+ ModuleIndex mi = findClass(cur.className);
530
+ if (isDerivedFrom(mi.smoke, mi.index, baseSmoke, baseId))
531
+ return true;
532
+ }
533
+ if (isDerivedFrom(smoke, smoke->inheritanceList[p], baseSmoke, baseId))
534
+ return true;
535
+ }
536
+ return false;
537
+ }
538
+
539
+ static inline bool isDerivedFrom(const char *className, const char *baseClassName) {
540
+ ModuleIndex classId = findClass(className);
541
+ ModuleIndex baseId = findClass(baseClassName);
542
+ return isDerivedFrom(classId.smoke, classId.index, baseId.smoke, baseId.index);
543
+ }
544
+ };
545
+
546
+ class SmokeBinding {
547
+ protected:
548
+ Smoke *smoke;
549
+ public:
550
+ SmokeBinding(Smoke *s) : smoke(s) {}
551
+ virtual void deleted(Smoke::Index classId, void *obj) = 0;
552
+ virtual bool callMethod(Smoke::Index method, void *obj, Smoke::Stack args, bool isAbstract = false) = 0;
553
+ virtual char* className(Smoke::Index classId) = 0;
554
+ virtual ~SmokeBinding() {}
555
+ };
556
+
557
+ #endif