6cb836c6d3ac21e7a24aa96bb7e23949dcabf549
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qdeclarativeinstruction / tst_qdeclarativeinstruction.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <qtest.h>
43 #include <private/qdeclarativecompiler_p.h>
44
45 class tst_qdeclarativeinstruction : public QObject
46 {
47     Q_OBJECT
48 public:
49     tst_qdeclarativeinstruction() {}
50
51 private slots:
52     void dump();
53
54     void point();
55     void pointf();
56     void size();
57     void sizef();
58     void rect();
59     void rectf();
60     void vector3d();
61     void vector4d();
62     void time();
63 };
64
65 static QStringList messages;
66 static void msgHandler(QtMsgType, const char *msg)
67 {
68     messages << QLatin1String(msg);
69 }
70
71 void tst_qdeclarativeinstruction::dump()
72 {
73     QDeclarativeEngine engine;
74     QDeclarativeCompiledData *data = new QDeclarativeCompiledData(&engine);
75
76     {
77         QDeclarativeCompiledData::Instruction::Init i;
78         i.bindingsSize = 0;
79         i.parserStatusSize = 3;
80         i.contextCache = -1;
81         i.compiledBinding = -1;
82         data->addInstruction(i);
83     }
84
85     {
86         QDeclarativeCompiledData::TypeReference ref;
87         ref.className = "Test";
88         data->types << ref;
89
90         QDeclarativeCompiledData::Instruction::CreateCppObject i;
91         i.type = 0;
92         i.data = -1;
93         i.column = 10;
94         data->addInstruction(i);
95     }
96
97     {
98         data->primitives << "testId";
99
100         QDeclarativeCompiledData::Instruction::SetId i;
101         i.value = data->primitives.count() - 1;
102         i.index = 0;
103         data->addInstruction(i);
104     }
105
106     {
107         QDeclarativeCompiledData::Instruction::SetDefault i;
108         data->addInstruction(i);
109     }
110
111     {
112         QDeclarativeCompiledData::Instruction::CreateComponent i;
113         i.count = 3;
114         i.column = 4;
115         i.endLine = 14;
116         i.metaObject = 0;
117
118         data->addInstruction(i);
119     }
120
121     {
122         QDeclarativeCompiledData::Instruction::StoreMetaObject i;
123         i.data = 3;
124         i.aliasData = 6;
125         i.propertyCache = 7;
126
127         data->addInstruction(i);
128     }
129
130     {
131         QDeclarativeCompiledData::Instruction::StoreFloat i;
132         i.propertyIndex = 3;
133         i.value = 11.3;
134         data->addInstruction(i);
135     }
136
137     {
138         QDeclarativeCompiledData::Instruction::StoreDouble i;
139         i.propertyIndex = 4;
140         i.value = 14.8;
141         data->addInstruction(i);
142     }
143
144     {
145         QDeclarativeCompiledData::Instruction::StoreInteger i;
146         i.propertyIndex = 5;
147         i.value = 9;
148         data->addInstruction(i);
149     }
150
151     {
152         QDeclarativeCompiledData::Instruction::StoreBool i;
153         i.propertyIndex = 6;
154         i.value = true;
155
156         data->addInstruction(i);
157     }
158
159     {
160         data->primitives << "Test String";
161         QDeclarativeCompiledData::Instruction::StoreString i;
162         i.propertyIndex = 7;
163         i.value = data->primitives.count() - 1;
164         data->addInstruction(i);
165     }
166
167     {
168         data->urls << QUrl("http://www.nokia.com");
169         QDeclarativeCompiledData::Instruction::StoreUrl i;
170         i.propertyIndex = 8;
171         i.value = data->urls.count() - 1;
172         data->addInstruction(i);
173     }
174
175     {
176         QDeclarativeCompiledData::Instruction::StoreColor i;
177         i.propertyIndex = 9;
178         i.value = 0xFF00FF00;
179         data->addInstruction(i);
180     }
181
182     {
183         QDeclarativeCompiledData::Instruction::StoreDate i;
184         i.propertyIndex = 10;
185         i.value = 9;
186         data->addInstruction(i);
187     }
188
189     {
190         QDeclarativeCompiledData::Instruction::StoreTime i;
191         i.propertyIndex = 11;
192         data->addInstruction(i);
193     }
194
195     {
196         QDeclarativeCompiledData::Instruction::StoreDateTime i;
197         i.propertyIndex = 12;
198         data->addInstruction(i);
199     }
200
201     {
202         QDeclarativeCompiledData::Instruction::StorePoint i;
203         i.propertyIndex = 13;
204         i.point.xp = 3;
205         i.point.yp = 7;
206         data->addInstruction(i);
207     }
208
209     {
210         QDeclarativeCompiledData::Instruction::StorePointF i;
211         i.propertyIndex = 13;
212         i.point.xp = 3;
213         i.point.yp = 7;
214         data->addInstruction(i);
215     }
216
217     {
218         QDeclarativeCompiledData::Instruction::StoreSize i;
219         i.propertyIndex = 15;
220         i.size.wd = 8;
221         i.size.ht = 11;
222         data->addInstruction(i);
223     }
224
225     {
226         QDeclarativeCompiledData::Instruction::StoreSizeF i;
227         i.propertyIndex = 15;
228         i.size.wd = 8;
229         i.size.ht = 11;
230         data->addInstruction(i);
231     }
232
233     {
234         QDeclarativeCompiledData::Instruction::StoreRect i;
235         i.propertyIndex = 17;
236         i.rect.x1 = 7;
237         i.rect.y1 = 9;
238         i.rect.x2 = 11;
239         i.rect.y2 = 13;
240         data->addInstruction(i);
241     }
242
243     {
244         QDeclarativeCompiledData::Instruction::StoreRectF i;
245         i.propertyIndex = 18;
246         i.rect.xp = 11.3;
247         i.rect.yp = 9.8;
248         i.rect.w = 3;
249         i.rect.h = 2.1;
250         data->addInstruction(i);
251     }
252
253     {
254         QDeclarativeCompiledData::Instruction::StoreVector3D i;
255         i.propertyIndex = 19;
256         i.vector.xp = 9;
257         i.vector.yp = 3;
258         i.vector.zp = 92;
259         data->addInstruction(i);
260     }
261
262     {
263         data->primitives << "color(1, 1, 1, 1)";
264         QDeclarativeCompiledData::Instruction::StoreVariant i;
265         i.propertyIndex = 20;
266         i.value = data->primitives.count() - 1;
267
268         data->addInstruction(i);
269     }
270
271     {
272         QDeclarativeCompiledData::Instruction::StoreObject i;
273         i.propertyIndex = 21;
274         data->addInstruction(i);
275     }
276
277     {
278         QDeclarativeCompiledData::Instruction::StoreVariantObject i;
279         i.propertyIndex = 22;
280         data->addInstruction(i);
281     }
282
283     {
284         QDeclarativeCompiledData::Instruction::StoreInterface i;
285         i.propertyIndex = 23;
286         data->addInstruction(i);
287     }
288
289     {
290         data->primitives << "console.log(1921)";
291
292         QDeclarativeCompiledData::Instruction::StoreSignal i;
293         i.signalIndex = 2;
294         i.value = data->primitives.count() - 1;
295         data->addInstruction(i);
296     }
297
298     {
299         QDeclarativeCompiledData::Instruction::StoreScriptString i;
300         i.propertyIndex = 24;
301         i.value = 3;
302         i.scope = 1;
303         i.bindingId = 4;
304         data->addInstruction(i);
305     }
306
307     {
308         data->primitives << "mySignal";
309
310         QDeclarativeCompiledData::Instruction::AssignSignalObject i;
311         i.signal = data->primitives.count() - 1;
312         data->addInstruction(i);
313     }
314
315     {
316         QDeclarativeCompiledData::Instruction::AssignCustomType i;
317         i.propertyIndex = 25;
318         i.primitive = 6;
319         i.type = 9;
320         data->addInstruction(i);
321     }
322
323     {
324         QDeclarativeCompiledData::Instruction::StoreBinding i;
325         i.property.coreIndex = 26;
326         i.value = 3;
327         i.context = 2;
328         i.owner = 0;
329         data->addInstruction(i);
330     }
331
332     {
333         QDeclarativeCompiledData::Instruction::StoreV4Binding i;
334         i.property = 27;
335         i.value = 2;
336         i.context = 4;
337         i.owner = 0;
338         data->addInstruction(i);
339     }
340
341     {
342         QDeclarativeCompiledData::Instruction::StoreValueSource i;
343         i.property.coreIndex = 29;
344         i.owner = 1;
345         i.castValue = 4;
346         data->addInstruction(i);
347     }
348
349     {
350         QDeclarativeCompiledData::Instruction::StoreValueInterceptor i;
351         i.property.coreIndex = 30;
352         i.owner = 2;
353         i.castValue = -4;
354         data->addInstruction(i);
355     }
356
357     {
358         QDeclarativeCompiledData::Instruction::BeginObject i;
359         i.castValue = 4;
360         data->addInstruction(i);
361     }
362
363     {
364         QDeclarativeCompiledData::Instruction::StoreObjectQList i;
365         data->addInstruction(i);
366     }
367
368     {
369         QDeclarativeCompiledData::Instruction::AssignObjectList i;
370         data->addInstruction(i);
371     }
372
373     {
374         QDeclarativeCompiledData::Instruction::FetchAttached i;
375         i.id = 23;
376         data->addInstruction(i);
377     }
378
379     {
380         QDeclarativeCompiledData::Instruction::FetchQList i;
381         i.property = 32;
382         data->addInstruction(i);
383     }
384
385     {
386         QDeclarativeCompiledData::Instruction::FetchObject i;
387         i.property = 33;
388         data->addInstruction(i);
389     }
390
391     {
392         QDeclarativeCompiledData::Instruction::FetchValueType i;
393         i.property = 34;
394         i.type = 6;
395         i.bindingSkipList = 7;
396         data->addInstruction(i);
397     }
398
399     {
400         QDeclarativeCompiledData::Instruction::PopFetchedObject i;
401         data->addInstruction(i);
402     }
403
404     {
405         QDeclarativeCompiledData::Instruction::PopQList i;
406         data->addInstruction(i);
407     }
408
409     {
410         QDeclarativeCompiledData::Instruction::PopValueType i;
411         i.property = 35;
412         i.type = 8;
413         data->addInstruction(i);
414     }
415
416     {
417         QDeclarativeCompiledData::Instruction::Defer i;
418         i.deferCount = 7;
419         data->addInstruction(i);
420     }
421
422     {
423         QDeclarativeCompiledData::Instruction::Defer i;
424         i.deferCount = 7;
425         data->addInstruction(i);
426     }
427
428     {
429         QDeclarativeCompiledData::Instruction::StoreImportedScript i;
430         i.value = 2;
431         data->addInstruction(i);
432     }
433
434     {
435         QDeclarativeCompiledData::Instruction::StoreVariantInteger i;
436         i.value = 11;
437         i.propertyIndex = 32;
438         data->addInstruction(i);
439     }
440
441     {
442         QDeclarativeCompiledData::Instruction::StoreVariantDouble i;
443         i.value = 33.7;
444         i.propertyIndex = 19;
445         data->addInstruction(i);
446     }
447
448     {
449         QDeclarativeCompiledData::Instruction::Done i;
450         data->addInstruction(i);
451     }
452
453     {
454         QDeclarativeCompiledData::Instruction::StoreTrString i;
455         i.propertyIndex = 99;
456         i.context = 3;
457         i.text = 14;
458         i.comment = 14;
459         i.n = 2;
460         data->addInstruction(i);
461     }
462
463     {
464         QDeclarativeCompiledData::Instruction::StoreTrIdString i;
465         i.propertyIndex = 78;
466         i.text = 7;
467         i.n = -1;
468         data->addInstruction(i);
469     }
470
471     QStringList expect;
472     expect 
473         << "Index\tOperation\t\tData1\tData2\tData3\tComments"
474         << "-------------------------------------------------------------------------------"
475         << "0\t\tINIT\t\t\t0\t3\t-1\t-1"
476         << "1\t\tCREATECPP\t\t\t0\t\t\t\"Test\""
477         << "2\t\tSETID\t\t\t0\t\t\t\"testId\""
478         << "3\t\tSET_DEFAULT"
479         << "4\t\tCREATE_COMPONENT\t3"
480         << "5\t\tSTORE_META\t\t3"
481         << "6\t\tSTORE_FLOAT\t\t3\t11.3"
482         << "7\t\tSTORE_DOUBLE\t\t4\t14.8"
483         << "8\t\tSTORE_INTEGER\t\t5\t9"
484         << "9\t\tSTORE_BOOL\t\t6\ttrue"
485         << "10\t\tSTORE_STRING\t\t7\t1\t\t\"Test String\""
486         << "11\t\tSTORE_URL\t\t8\t0\t\tQUrl(\"http://www.nokia.com\") "
487         << "12\t\tSTORE_COLOR\t\t9\t\t\t\"ff00ff00\""
488         << "13\t\tSTORE_DATE\t\t10\t9"
489         << "14\t\tSTORE_TIME\t\t11"
490         << "15\t\tSTORE_DATETIME\t\t12"
491         << "16\t\tSTORE_POINT\t\t13\t3\t7"
492         << "17\t\tSTORE_POINTF\t\t13\t3\t7"
493         << "18\t\tSTORE_SIZE\t\t15\t8\t11"
494         << "19\t\tSTORE_SIZEF\t\t15\t8\t11"
495         << "20\t\tSTORE_RECT\t\t17\t7\t9\t11\t13"
496         << "21\t\tSTORE_RECTF\t\t18\t11.3\t9.8\t3\t2.1"
497         << "22\t\tSTORE_VECTOR3D\t\t19\t9\t3\t92"
498         << "23\t\tSTORE_VARIANT\t\t20\t2\t\t\"color(1, 1, 1, 1)\""
499         << "24\t\tSTORE_OBJECT\t\t21"
500         << "25\t\tSTORE_VARIANT_OBJECT\t22"
501         << "26\t\tSTORE_INTERFACE\t\t23"
502         << "27\t\tSTORE_SIGNAL\t\t2\t3\t\t\"console.log(1921)\""
503         << "28\t\tSTORE_SCRIPT_STRING\t24\t3\t1\t4"
504         << "29\t\tASSIGN_SIGNAL_OBJECT\t4\t\t\t\"mySignal\""
505         << "30\t\tASSIGN_CUSTOMTYPE\t25\t6\t9"
506         << "31\t\tSTORE_BINDING\t26\t3\t2"
507         << "32\t\tSTORE_COMPILED_BINDING\t27\t2\t4"
508         << "33\t\tSTORE_VALUE_SOURCE\t29\t4"
509         << "34\t\tSTORE_VALUE_INTERCEPTOR\t30\t-4"
510         << "35\t\tBEGIN\t\t\t4"
511         << "36\t\tSTORE_OBJECT_QLIST"
512         << "37\t\tASSIGN_OBJECT_LIST"
513         << "38\t\tFETCH_ATTACHED\t\t23"
514         << "39\t\tFETCH_QLIST\t\t32"
515         << "40\t\tFETCH\t\t\t33"
516         << "41\t\tFETCH_VALUE\t\t34\t6\t7"
517         << "42\t\tPOP"
518         << "43\t\tPOP_QLIST"
519         << "44\t\tPOP_VALUE\t\t35\t8"
520         << "45\t\tDEFER\t\t\t7"
521         << "46\t\tDEFER\t\t\t7"
522         << "47\t\tSTORE_IMPORTED_SCRIPT\t2"
523         << "48\t\tSTORE_VARIANT_INTEGER\t\t32\t11"
524         << "49\t\tSTORE_VARIANT_DOUBLE\t\t19\t33.7"
525         << "50\t\tDONE"
526         << "51\t\tSTORE_TR_STRING\t99\t3\t14\t14\t2"
527         << "52\t\tSTORE_TRID_STRING\t78\t7\t-1"
528         << "-------------------------------------------------------------------------------";
529
530     messages = QStringList();
531     QtMsgHandler old = qInstallMsgHandler(msgHandler);
532
533     data->dumpInstructions();
534     qInstallMsgHandler(old);
535
536     QCOMPARE(messages.count(), expect.count());
537     for (int ii = 0; ii < messages.count(); ++ii) {
538         QCOMPARE(messages.at(ii), expect.at(ii));
539     }
540
541     data->release();
542 }
543
544 void tst_qdeclarativeinstruction::point()
545 {
546     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storePoint::QPoint), sizeof(QPoint));
547     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storePoint::QPoint), Q_ALIGNOF(QPoint));
548
549     QDeclarativeInstruction i;
550     i.storePoint.point.xp = 8;
551     i.storePoint.point.yp = 11;
552
553     const QPoint &point = (const QPoint &)(i.storePoint.point);
554     QCOMPARE(point.x(), 8);
555     QCOMPARE(point.y(), 11);
556 }
557
558 void tst_qdeclarativeinstruction::pointf()
559 {
560     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storePointF::QPointF), sizeof(QPointF));
561     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storePointF::QPointF), Q_ALIGNOF(QPointF));
562
563     QDeclarativeInstruction i;
564     i.storePointF.point.xp = 8.7;
565     i.storePointF.point.yp = 11.3;
566
567     const QPointF &point = (const QPointF &)(i.storePointF.point);
568     QCOMPARE(point.x(), 8.7);
569     QCOMPARE(point.y(), 11.3);
570 }
571
572 void tst_qdeclarativeinstruction::size()
573 {
574     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storeSize::QSize), sizeof(QSize));
575     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storeSize::QSize), Q_ALIGNOF(QSize));
576
577     QDeclarativeInstruction i;
578     i.storeSize.size.wd = 8;
579     i.storeSize.size.ht = 11;
580
581     const QSize &size = (const QSize &)(i.storeSize.size);
582     QCOMPARE(size.width(), 8);
583     QCOMPARE(size.height(), 11);
584 }
585
586 void tst_qdeclarativeinstruction::sizef()
587 {
588     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storeSizeF::QSizeF), sizeof(QSizeF));
589     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storeSizeF::QSizeF), Q_ALIGNOF(QSizeF));
590
591     QDeclarativeInstruction i;
592     i.storeSizeF.size.wd = 8;
593     i.storeSizeF.size.ht = 11;
594
595     const QSizeF &size = (const QSizeF &)(i.storeSizeF.size);
596     QCOMPARE(size.width(), (qreal)8);
597     QCOMPARE(size.height(), (qreal)11);
598 }
599
600 void tst_qdeclarativeinstruction::rect()
601 {
602     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storeRect::QRect), sizeof(QRect));
603     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storeRect::QRect), Q_ALIGNOF(QRect));
604
605     QDeclarativeInstruction i;
606     i.storeRect.rect.x1 = 8;
607     i.storeRect.rect.y1 = 11;
608     i.storeRect.rect.x2 = 13;
609     i.storeRect.rect.y2 = 19;
610
611     const QRect &rect = (const QRect &)(i.storeRect.rect);
612     QCOMPARE(rect.left(), 8);
613     QCOMPARE(rect.top(), 11);
614     QCOMPARE(rect.right(), 13);
615     QCOMPARE(rect.bottom(), 19);
616 }
617
618 void tst_qdeclarativeinstruction::rectf()
619 {
620     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storeRectF::QRectF), sizeof(QRectF));
621     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storeRectF::QRectF), Q_ALIGNOF(QRectF));
622
623     QDeclarativeInstruction i;
624     i.storeRectF.rect.xp = 8;
625     i.storeRectF.rect.yp = 11;
626     i.storeRectF.rect.w = 13;
627     i.storeRectF.rect.h = 19;
628
629     const QRectF &rect = (const QRectF &)(i.storeRectF.rect);
630     QCOMPARE(rect.left(), (qreal)8);
631     QCOMPARE(rect.top(), (qreal)11);
632     QCOMPARE(rect.width(), (qreal)13);
633     QCOMPARE(rect.height(), (qreal)19);
634 }
635
636 void tst_qdeclarativeinstruction::vector3d()
637 {
638     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storeVector3D::QVector3D), sizeof(QVector3D));
639     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storeVector3D::QVector3D), Q_ALIGNOF(QVector3D));
640
641     QDeclarativeInstruction i;
642     i.storeVector3D.vector.xp = 8.2;
643     i.storeVector3D.vector.yp = 99.3;
644     i.storeVector3D.vector.zp = 12.0;
645
646     const QVector3D &vector = (const QVector3D &)(i.storeVector3D.vector);
647     QCOMPARE(vector.x(), (qreal)(float)8.2);
648     QCOMPARE(vector.y(), (qreal)(float)99.3);
649     QCOMPARE(vector.z(), (qreal)(float)12.0);
650 }
651
652 void tst_qdeclarativeinstruction::vector4d()
653 {
654     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storeVector4D::QVector4D), sizeof(QVector4D));
655     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storeVector4D::QVector4D), Q_ALIGNOF(QVector4D));
656
657     QDeclarativeInstruction i;
658     i.storeVector4D.vector.xp = 8.2;
659     i.storeVector4D.vector.yp = 99.3;
660     i.storeVector4D.vector.zp = 12.0;
661     i.storeVector4D.vector.wp = 121.1;
662
663     const QVector4D &vector = (const QVector4D &)(i.storeVector4D.vector);
664     QCOMPARE(vector.x(), (qreal)(float)8.2);
665     QCOMPARE(vector.y(), (qreal)(float)99.3);
666     QCOMPARE(vector.z(), (qreal)(float)12.0);
667     QCOMPARE(vector.w(), (qreal)(float)121.1);
668 }
669
670 void tst_qdeclarativeinstruction::time()
671 {
672     QCOMPARE(sizeof(QDeclarativeInstruction::instr_storeTime::QTime), sizeof(QTime));
673     QCOMPARE(Q_ALIGNOF(QDeclarativeInstruction::instr_storeTime::QTime), Q_ALIGNOF(QTime));
674 }
675
676 QTEST_MAIN(tst_qdeclarativeinstruction)
677
678 #include "tst_qdeclarativeinstruction.moc"