1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <qscriptengine.h>
44 #include <QFile>
45 #include <QTest>
46
47 #include <qlocalsocket.h>
48 #include <qlocalserver.h>
49
50 class QScriptLocalSocket : public QObject
51 {
52 Q_OBJECT
53 Q_PROPERTY(QString serverName WRITE connectToServer READ serverName)
54
55 public:
QScriptLocalSocket(QObject * parent=0)56 QScriptLocalSocket(QObject *parent = 0) : QObject(parent)
57 {
58 lc = new QLocalSocket(this);
59 }
60
61 public slots:
serverName()62 QString serverName()
63 {
64 return lc->serverName();
65 }
66
connectToServer(const QString & name)67 void connectToServer(const QString &name) {
68 lc->connectToServer(name);
69 }
70
sleep(int x) const71 void sleep(int x) const
72 {
73 QTest::qSleep(x);
74 }
75
isConnected()76 bool isConnected() {
77 return (lc->state() == QLocalSocket::ConnectedState);
78 }
79
open()80 void open() {
81 lc->open(QIODevice::ReadWrite);
82 }
83
waitForConnected()84 bool waitForConnected() {
85 return lc->waitForConnected(100000);
86 }
waitForReadyRead()87 void waitForReadyRead() {
88 lc->waitForReadyRead();
89 }
90
write(const QString & string)91 void write(const QString &string) {
92 QTextStream out(lc);
93 out << string << endl;
94 }
95
waitForBytesWritten(int t=3000)96 bool waitForBytesWritten(int t = 3000) {
97 return lc->waitForBytesWritten(t);
98 }
99
readLine()100 QString readLine() {
101 QTextStream in(lc);
102 return in.readLine();
103 }
104
errorString()105 QString errorString() {
106 return lc->errorString();
107 }
108
close()109 void close() {
110 lc->close();
111 }
112
113 public:
114 QLocalSocket *lc;
115 };
116
117 class QScriptLocalServer : public QLocalServer
118 {
119 Q_OBJECT
120 Q_PROPERTY(int maxPendingConnections WRITE setMaxPendingConnections READ maxPendingConnections)
121 Q_PROPERTY(QString name WRITE listen READ serverName)
122 Q_PROPERTY(bool listening READ isListening)
123
124 public:
QScriptLocalServer(QObject * parent=0)125 QScriptLocalServer(QObject *parent = 0) : QLocalServer(parent)
126 {
127 }
128
129 public slots:
listen(const QString & name)130 bool listen(const QString &name) {
131 if (!QLocalServer::listen(name)) {
132 if (serverError() == QAbstractSocket::AddressInUseError) {
133 QFile::remove(serverName());
134 return QLocalServer::listen(name);
135 }
136 return false;
137 }
138 return true;
139 }
140
nextConnection()141 QScriptLocalSocket *nextConnection() {
142 QLocalSocket *other = nextPendingConnection();
143 QScriptLocalSocket *s = new QScriptLocalSocket(this);
144 delete s->lc;
145 s->lc = other;
146 return s;
147 }
148
waitForNewConnection()149 bool waitForNewConnection() {
150 return QLocalServer::waitForNewConnection(30000);
151 }
152
errorString()153 QString errorString() {
154 return QLocalServer::errorString();
155 }
156
157
158 };
159
160 template <typename T>
_q_ScriptValueFromQObject(QScriptEngine * engine,T * const & in)161 static QScriptValue _q_ScriptValueFromQObject(QScriptEngine *engine, T* const &in)
162 {
163 return engine->newQObject(in);
164 }
165 template <typename T>
_q_ScriptValueToQObject(const QScriptValue & v,T * & out)166 static void _q_ScriptValueToQObject(const QScriptValue &v, T* &out)
167 { out = qobject_cast<T*>(v.toQObject());
168 }
169 template <typename T>
_q_ScriptRegisterQObjectMetaType(QScriptEngine * engine,const QScriptValue & prototype)170 static int _q_ScriptRegisterQObjectMetaType(QScriptEngine *engine, const QScriptValue &prototype)
171 {
172 return qScriptRegisterMetaType<T*>(engine, _q_ScriptValueFromQObject<T>, _q_ScriptValueToQObject<T>, prototype);
173 }
174
175 QT_BEGIN_NAMESPACE
176 Q_SCRIPT_DECLARE_QMETAOBJECT(QScriptLocalSocket, QObject*);
177 Q_SCRIPT_DECLARE_QMETAOBJECT(QScriptLocalServer, QObject*);
178 QT_END_NAMESPACE
179
interactive(QScriptEngine & eng)180 static void interactive(QScriptEngine &eng)
181 {
182 QTextStream qin(stdin, QFile::ReadOnly);
183
184 const char *qscript_prompt = "qs> ";
185 const char *dot_prompt = ".... ";
186 const char *prompt = qscript_prompt;
187
188 QString code;
189
190 forever {
191 QString line;
192
193 printf("%s", prompt);
194 fflush(stdout);
195
196 line = qin.readLine();
197 if (line.isNull())
198 break;
199
200 code += line;
201 code += QLatin1Char('\n');
202
203 if (line.trimmed().isEmpty()) {
204 continue;
205
206 } else if (! eng.canEvaluate(code)) {
207 prompt = dot_prompt;
208
209 } else {
210 QScriptValue result = eng.evaluate(code);
211 code.clear();
212 prompt = qscript_prompt;
213 if (!result.isUndefined())
214 fprintf(stderr, "%s\n", qPrintable(result.toString()));
215 }
216 }
217 }
218 Q_DECLARE_METATYPE(QScriptLocalSocket*)
Q_DECLARE_METATYPE(QScriptLocalServer *)219 Q_DECLARE_METATYPE(QScriptLocalServer*)
220 int main(int argc, char *argv[])
221 {
222 QCoreApplication app(argc, argv);
223 QScriptEngine eng;
224 QScriptValue globalObject = eng.globalObject();
225
226 _q_ScriptRegisterQObjectMetaType<QScriptLocalServer>(&eng, QScriptValue());
227
228 QScriptValue lss = qScriptValueFromQMetaObject<QScriptLocalServer>(&eng);
229 eng.globalObject().setProperty("QScriptLocalServer", lss);
230
231 _q_ScriptRegisterQObjectMetaType<QScriptLocalSocket>(&eng, QScriptValue());
232
233 QScriptValue lsc = qScriptValueFromQMetaObject<QScriptLocalSocket>(&eng);
234 eng.globalObject().setProperty("QScriptLocalSocket", lsc);
235
236 if (! *++argv) {
237 interactive(eng);
238 return EXIT_SUCCESS;
239 }
240
241 QStringList arguments;
242 for (int i = 0; i < argc - 1; ++i)
243 arguments << QString::fromLocal8Bit(argv[i]);
244
245 while (!arguments.isEmpty()) {
246 QString fn = arguments.takeFirst();
247
248 if (fn == QLatin1String("-i")) {
249 interactive(eng);
250 break;
251 }
252
253 QString contents;
254
255 if (fn == QLatin1String("-")) {
256 QTextStream stream(stdin, QFile::ReadOnly);
257 contents = stream.readAll();
258 } else {
259 QFile file(fn);
260 if (!file.exists()) {
261 fprintf(stderr, "%s doesn't exists\n", qPrintable(fn));
262 return EXIT_FAILURE;
263 }
264 if (file.open(QFile::ReadOnly)) {
265 QTextStream stream(&file);
266 contents = stream.readAll();
267 file.close();
268 }
269 }
270
271 if (contents.isEmpty())
272 continue;
273
274 if (contents[0] == '#') {
275 contents.prepend("//");
276 QScriptValue args = eng.newArray();
277 args.setProperty("0", QScriptValue(&eng, fn));
278 int i = 1;
279 while (!arguments.isEmpty())
280 args.setProperty(i++, QScriptValue(&eng, arguments.takeFirst()));
281 eng.currentContext()->activationObject().setProperty("args", args);
282 }
283 QScriptValue r = eng.evaluate(contents);
284 if (eng.hasUncaughtException()) {
285 int line = eng.uncaughtExceptionLineNumber();
286 fprintf(stderr, "%d: %s\n\t%s\n\n", line, qPrintable(fn), qPrintable(r.toString()));
287 return EXIT_FAILURE;
288 }
289 if (r.isNumber())
290 return r.toInt32();
291 }
292
293 return EXIT_SUCCESS;
294 }
295
296 #include "main.moc"
297