QtBase  v6.3.1
language.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #include "language.h"
30 
31 #include <QtCore/qtextstream.h>
32 
33 namespace language {
34 
35 static Encoding encoding = Encoding::Utf8;
36 static Language _language = Language::Cpp;
37 
38 Language language() { return _language; }
39 
41 {
42  _language = l;
43  switch (_language) {
44  case Language::Cpp:
46  listStart = '{';
47  listEnd = '}';
48  nullPtr = QLatin1String("nullptr");
49  operatorNew = QLatin1String("new ");
50  qtQualifier = QLatin1String("Qt::");
51  qualifier = QLatin1String("::");
52  self = QLatin1String(""); // for testing: change to "this->";
53  eol = QLatin1String(";\n");
54  emptyString = QLatin1String("QString()");
55  encoding = Encoding::Utf8;
56  break;
57  case Language::Python:
59  listStart = '[';
60  listEnd = ']';
61  nullPtr = QLatin1String("None");
63  qtQualifier = QLatin1String("Qt.");
64  qualifier = QLatin1String(".");
65  self = QLatin1String("self.");
66  eol = QLatin1String("\n");
67  emptyString = QLatin1String("\"\"");
68  encoding = Encoding::Unicode;
69  break;
70  }
71 }
72 
74 char listStart;
75 char listEnd;
80 QString self;
83 
87 
89 {
90  str << "QT_CONFIG(" << c.parameter() << ')';
91  return str;
92 }
93 
95 {
96  str << "#if " << qtConfig(c.parameter()) << '\n';
97  return str;
98 }
99 
101 {
102  str << "#endif // " << qtConfig(c.parameter()) << '\n';
103  return str;
104 }
105 
107 {
108  int value;
109  const char *valueString;
110 };
111 
112 template <int N>
113 const char *lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex = 0)
114 {
115  for (int i = 0; i < N; ++i) {
116  if (value == array[i].value)
117  return array[i].valueString;
118  }
119  const char *defaultValue = array[defaultIndex].valueString;
120  qWarning("uic: Warning: Invalid enumeration value %d, defaulting to %s",
121  value, defaultValue);
122  return defaultValue;
123 }
124 
126 {
127  if (language() == Language::Python)
128  className.replace(cppQualifier, QLatin1String("_"));
129  return className;
130 }
131 
132 const char *toolbarArea(int v)
133 {
134  static const EnumLookup toolBarAreas[] =
135  {
136  {0, "NoToolBarArea"},
137  {0x1, "LeftToolBarArea"},
138  {0x2, "RightToolBarArea"},
139  {0x4, "TopToolBarArea"},
140  {0x8, "BottomToolBarArea"},
141  {0xf, "AllToolBarAreas"}
142  };
143  return lookupEnum(toolBarAreas, v);
144 }
145 
146 const char *sizePolicy(int v)
147 {
148  static const EnumLookup sizePolicies[] =
149  {
150  {0, "Fixed"},
151  {0x1, "Minimum"},
152  {0x4, "Maximum"},
153  {0x5, "Preferred"},
154  {0x3, "MinimumExpanding"},
155  {0x7, "Expanding"},
156  {0xD, "Ignored"}
157  };
158  return lookupEnum(sizePolicies, v, 3);
159 }
160 
161 const char *dockWidgetArea(int v)
162 {
163  static const EnumLookup dockWidgetAreas[] =
164  {
165  {0, "NoDockWidgetArea"},
166  {0x1, "LeftDockWidgetArea"},
167  {0x2, "RightDockWidgetArea"},
168  {0x4, "TopDockWidgetArea"},
169  {0x8, "BottomDockWidgetArea"},
170  {0xf, "AllDockWidgetAreas"}
171  };
172  return lookupEnum(dockWidgetAreas, v);
173 }
174 
175 const char *paletteColorRole(int v)
176 {
177  static const EnumLookup colorRoles[] =
178  {
179  {0, "WindowText"},
180  {1, "Button"},
181  {2, "Light"},
182  {3, "Midlight"},
183  {4, "Dark"},
184  {5, "Mid"},
185  {6, "Text"},
186  {7, "BrightText"},
187  {8, "ButtonText"},
188  {9, "Base"},
189  {10, "Window"},
190  {11, "Shadow"},
191  {12, "Highlight"},
192  {13, "HighlightedText"},
193  {14, "Link"},
194  {15, "LinkVisited"},
195  {16, "AlternateBase"},
196  {17, "NoRole"},
197  {18, "ToolTipBase"},
198  {19, "ToolTipText"},
199  {20, "PlaceholderText"},
200  };
201  return lookupEnum(colorRoles, v);
202 }
203 
204 // Helpers for formatting a character sequences
205 
206 // Format a special character like '\x0a'
207 static int formatEscapedNumber(QTextStream &str, ushort value, int base, int width,
208  char prefix = 0)
209 {
210  int length = 1 + width;
211  str << '\\';
212  if (prefix) {
213  str << prefix;
214  ++length;
215  }
216  const auto oldPadChar = str.padChar();
217  const auto oldFieldWidth = str.fieldWidth();
218  const auto oldFieldAlignment = str.fieldAlignment();
219  const auto oldIntegerBase = str.integerBase();
220  str.setPadChar(QLatin1Char('0'));
221  str.setFieldWidth(width);
222  str.setFieldAlignment(QTextStream::AlignRight);
223  str.setIntegerBase(base);
224  str << value;
225  str.setIntegerBase(oldIntegerBase);
226  str.setFieldAlignment(oldFieldAlignment);
227  str.setFieldWidth(oldFieldWidth);
228  str.setPadChar(oldPadChar);
229  return length;
230 }
231 
232 static int formatSpecialCharacter(QTextStream &str, ushort value)
233 {
234  int length = 0;
235  switch (value) {
236  case '\\':
237  str << "\\\\";
238  length += 2;
239  break;
240  case '\"':
241  str << "\\\"";
242  length += 2;
243  break;
244  case '\n':
245  str << "\\n\"\n\"";
246  length += 5;
247  break;
248  default:
249  break;
250  }
251  return length;
252 }
253 
254 // Format a sequence of characters for C++ with special characters numerically
255 // escaped (non-raw string literals), wrappped at maxSegmentSize. FormattingTraits
256 // are used to transform characters into (unsigned) codes, which can be used
257 // for either normal escapes or Unicode code points as used in Unicode literals.
258 
259 enum : int { maxSegmentSize = 1024 };
260 
261 template <Encoding e>
263 {
264 };
265 
266 template <>
268 {
269  static ushort code(char c) { return uchar(c); }
270 };
271 
272 template <>
274 {
275  static ushort code(QChar c) { return c.unicode(); }
276 };
277 
278 template <Encoding e, class Iterator>
279 static void formatStringSequence(QTextStream &str, Iterator it, Iterator end,
280  const QString &indent,
281  int escapeIntegerBase, int escapeWidth,
282  char escapePrefix = 0)
283 {
284  str << '"';
285  int length = 0;
286  while (it != end) {
287  const auto code = FormattingTraits<e>::code(*it);
288  if (code >= 0x80) {
289  length += formatEscapedNumber(str, code, escapeIntegerBase, escapeWidth, escapePrefix);
290  } else if (const int l = formatSpecialCharacter(str, code)) {
291  length += l;
292  } else if (code != '\r') {
293  str << *it;
294  ++length;
295  }
296  ++it;
297  if (it != end && length > maxSegmentSize) {
298  str << "\"\n" << indent << indent << '"';
299  length = 0;
300  }
301  }
302  str << '"';
303 }
304 
305 void _formatString(QTextStream &str, const QString &value, const QString &indent,
306  bool qString)
307 {
308  switch (encoding) {
309  // Special characters as 3 digit octal escapes (u8"\303\234mlaut")
310  case Encoding::Utf8: {
311  if (qString && _language == Language::Cpp)
312  str << "QString::fromUtf8(";
313  const QByteArray utf8 = value.toUtf8();
314  formatStringSequence<Encoding::Utf8>(str, utf8.cbegin(), utf8.cend(), indent,
315  8, 3);
316  if (qString && _language == Language::Cpp)
317  str << ')';
318  }
319  break;
320  // Special characters as 4 digit hex Unicode points (u8"\u00dcmlaut")
321  case Encoding::Unicode:
322  str << 'u'; // Python Unicode literal (would be UTF-16 in C++)
323  formatStringSequence<Encoding::Unicode>(str, value.cbegin(), value.cend(), indent,
324  16, 4, 'u');
325  break;
326  }
327 }
328 
330 {
331  for (int i = 0; i < r.m_count; ++i)
332  str << r.m_char;
333  return str;
334 }
335 
337  const QString &parameterName,
338  const QString &indent,
339  const char *returnType) :
340  m_name(name), m_parameterType(parameterType), m_parameterName(parameterName),
341  m_indent(indent), m_return(returnType)
342 {
343 }
344 
346 {
347  switch (language()) {
348  case Language::Cpp:
349  str << (f.m_return ? f.m_return : "void") << ' ' << f.m_name << '('
350  << f.m_parameterType;
351  if (f.m_parameterType.cend()->isLetter())
352  str << ' ';
353  str << f.m_parameterName << ')' << '\n' << f.m_indent << "{\n";
354  break;
355  case Language::Python:
356  str << "def " << f.m_name << "(self, " << f.m_parameterName << "):\n";
357  break;
358  }
359  return str;
360 }
361 
363 {
364 }
365 
367 {
368  switch (language()) {
369  case Language::Cpp:
370  str << "} // " << f.m_name << "\n\n";
371  break;
372  case Language::Python:
373  str << "# " << f.m_name << "\n\n";
374  break;
375  }
376  return str;
377 }
378 
380  bool withInitParameters)
381 {
382  switch (language()) {
383  case Language::Cpp:
384  str << className << ' ' << varName;
385  if (withInitParameters)
386  str << '(';
387  break;
388  case Language::Python:
389  str << varName << " = " << className << '(';
390  if (!withInitParameters)
391  str << ')';
392  break;
393  }
394 }
395 
398  UseOverloadWhenNoArguments, // Use overload only when the argument list is empty,
399  // in this case there is no chance of connecting
400  // mismatching T against const T &
402 };
403 
404 // Format a member function for a signal slot connection
405 static void formatMemberFnPtr(QTextStream &str, const SignalSlot &s,
406  OverloadUse useQOverload = DontUseOverload)
407 {
408  const int parenPos = s.signature.indexOf(QLatin1Char('('));
409  Q_ASSERT(parenPos >= 0);
410  const auto functionName = QStringView{s.signature}.left(parenPos);
411 
412  const auto parameters = QStringView{s.signature}.mid(parenPos + 1,
413  s.signature.size() - parenPos - 2);
414  const bool withOverload = useQOverload == UseOverload ||
415  (useQOverload == UseOverloadWhenNoArguments && parameters.isEmpty());
416 
417  if (withOverload)
418  str << "qOverload<" << parameters << ">(";
419 
420  str << '&' << s.className << "::" << functionName;
421 
422  if (withOverload)
423  str << ')';
424 }
425 
426 static void formatMemberFnPtrConnection(QTextStream &str,
427  const SignalSlot &sender,
428  const SignalSlot &receiver)
429 {
430  str << "QObject::connect(" << sender.name << ", ";
431  formatMemberFnPtr(str, sender);
432  str << ", " << receiver.name << ", ";
433  formatMemberFnPtr(str, receiver, UseOverloadWhenNoArguments);
434  str << ')';
435 }
436 
437 static void formatStringBasedConnection(QTextStream &str,
438  const SignalSlot &sender,
439  const SignalSlot &receiver)
440 {
441  str << "QObject::connect(" << sender.name << ", SIGNAL("<< sender.signature
442  << "), " << receiver.name << ", SLOT(" << receiver.signature << "))";
443 }
444 
445 void formatConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver,
447 {
448  switch (language()) {
449  case Language::Cpp:
450  switch (connectionSyntax) {
452  formatMemberFnPtrConnection(str, sender, receiver);
453  break;
455  formatStringBasedConnection(str, sender, receiver);
456  break;
457  }
458  break;
459  case Language::Python: {
460  const auto paren = sender.signature.indexOf(u'(');
461  auto senderSignature = QStringView{sender.signature};
462  str << sender.name << '.' << senderSignature.left(paren);
463  // Signals like "QAbstractButton::clicked(checked=false)" require
464  // the parameter if it is used.
465  if (sender.options.testFlag(SignalSlotOption::Ambiguous)) {
466  const QStringView parameters =
467  senderSignature.mid(paren + 1, senderSignature.size() - paren - 2);
468  if (!parameters.isEmpty() && !parameters.contains(u','))
469  str << "[\"" << parameters << "\"]";
470  }
471  str << ".connect(" << receiver.name << '.'
472  << QStringView{receiver.signature}.left(receiver.signature.indexOf(QLatin1Char('(')))
473  << ')';
474  }
475  break;
476  }
477 }
478 
480 {
481  switch (language()) {
482  case Language::Cpp:
483  return v ? cppTrue : cppFalse;
484  case Language::Python:
485  return v ? QStringLiteral("True") : QStringLiteral("False");
486  }
487  Q_UNREACHABLE();
488 }
489 
490 static inline QString dot() { return QStringLiteral("."); }
491 
493 {
494  if (language() == Language::Cpp || !value.contains(cppQualifier))
495  return value;
496  QString fixed = value;
497  fixed.replace(cppQualifier, dot());
498  return fixed;
499 }
500 
501 } // namespace language
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
const_iterator cbegin() const noexcept
Definition: qbytearray.h:427
const_iterator cend() const noexcept
Definition: qbytearray.h:431
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
The QString class provides a Unicode character string.
Definition: qstring.h:388
const_iterator cbegin() const
Definition: qstring.h:1335
QString left(qsizetype n) const
Definition: qstring.cpp:4951
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:4197
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition: qstringview.h:334
constexpr bool isEmpty() const noexcept
Definition: qstringview.h:463
constexpr QStringView left(qsizetype n) const noexcept
Definition: qstringview.h:267
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Definition: qstringview.h:261
The QTextStream class provides a convenient interface for reading and writing text.
Definition: qtextstream.h:62
Definition: base.h:37
endFunctionDefinition(const char *name)
Definition: language.cpp:362
startFunctionDefinition1(const char *name, const QString &parameterType, const QString &parameterName, const QString &indent, const char *returnType=nullptr)
Definition: language.cpp:336
QString str
[2]
ConnectionSyntax
Definition: language.h:40
Language
Definition: language.h:38
QTextStream & fixed(QTextStream &stream)
Language language()
Definition: language.cpp:38
QString qtQualifier
Definition: language.cpp:78
QString enumValue(const QString &value)
Definition: language.cpp:492
char listStart
Definition: language.cpp:74
QString emptyString
Definition: language.cpp:82
QString nullPtr
Definition: language.cpp:76
const char * toolbarArea(int v)
Definition: language.cpp:132
const char * dockWidgetArea(int v)
Definition: language.cpp:161
void _formatStackVariable(QTextStream &str, const char *className, QStringView varName, bool withInitParameters)
Definition: language.cpp:379
void _formatString(QTextStream &str, const QString &value, const QString &indent, bool qString)
Definition: language.cpp:305
QString eol
Definition: language.cpp:81
char listEnd
Definition: language.cpp:75
QString qualifier
Definition: language.cpp:79
QString cppFalse
Definition: language.cpp:86
void setLanguage(Language l)
Definition: language.cpp:40
ConnectionSyntax connectionSyntax()
@ UseOverload
Definition: language.cpp:397
@ DontUseOverload
Definition: language.cpp:401
@ UseOverloadWhenNoArguments
Definition: language.cpp:398
const char * sizePolicy(int v)
Definition: language.cpp:146
QString fixClassName(QString className)
Definition: language.cpp:125
const char * paletteColorRole(int v)
Definition: language.cpp:175
QString cppTrue
Definition: language.cpp:85
QTextStream & operator<<(QTextStream &str, const qtConfig &c)
Definition: language.cpp:88
void formatConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver, ConnectionSyntax connectionSyntax)
Definition: language.cpp:445
QString cppQualifier
Definition: language.cpp:84
QString operatorNew
Definition: language.cpp:77
const char * lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex=0)
Definition: language.cpp:113
@ maxSegmentSize
Definition: language.cpp:259
QString derefPointer
Definition: language.cpp:73
QString boolValue(bool v)
Definition: language.cpp:479
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
[3]
#define Q_UNREACHABLE()
EGLOutputLayerEXT EGLint EGLAttrib value
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
Definition: qglobal.h:332
unsigned short ushort
Definition: qglobal.h:333
#define qWarning
Definition: qlogging.h:179
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLsizei const GLfloat * v
[13]
GLboolean r
[2]
GLuint GLuint end
GLfloat GLfloat f
GLint GLsizei width
GLuint name
const GLubyte * c
Definition: qopenglext.h:12701
GLenum array
Definition: qopenglext.h:7028
GLdouble s
[6]
Definition: qopenglext.h:235
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
#define QStringLiteral(str)
const char className[16]
[1]
Definition: qwizard.cpp:135
QStringList::Iterator it
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53
Definition: inftrees.h:24
const char * valueString
Definition: language.cpp:109
SignalSlotOptions options
Definition: language.h:213