File:  [Qemu by Fabrice Bellard] / qemu / check-qjson.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:34:41 2018 UTC (3 years, 5 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, HEAD
qemu 0.12.0

    1: /*
    2:  * Copyright IBM, Corp. 2009
    3:  *
    4:  * Authors:
    5:  *  Anthony Liguori   <aliguori@us.ibm.com>
    6:  *
    7:  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
    8:  * See the COPYING.LIB file in the top-level directory.
    9:  *
   10:  */
   11: #include <check.h>
   12: #include <stdbool.h>
   13: 
   14: #include "qstring.h"
   15: #include "qint.h"
   16: #include "qdict.h"
   17: #include "qlist.h"
   18: #include "qfloat.h"
   19: #include "qbool.h"
   20: #include "qjson.h"
   21: 
   22: #include "qemu-common.h"
   23: 
   24: START_TEST(escaped_string)
   25: {
   26:     int i;
   27:     struct {
   28:         const char *encoded;
   29:         const char *decoded;
   30:         int skip;
   31:     } test_cases[] = {
   32:         { "\"\\\"\"", "\"" },
   33:         { "\"hello world \\\"embedded string\\\"\"",
   34:           "hello world \"embedded string\"" },
   35:         { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
   36:         { "\"single byte utf-8 \\u0020\"", "single byte utf-8  ", .skip = 1 },
   37:         { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
   38:         { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
   39:         {}
   40:     };
   41: 
   42:     for (i = 0; test_cases[i].encoded; i++) {
   43:         QObject *obj;
   44:         QString *str;
   45: 
   46:         obj = qobject_from_json(test_cases[i].encoded);
   47: 
   48:         fail_unless(obj != NULL);
   49:         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
   50:         
   51:         str = qobject_to_qstring(obj);
   52:         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
   53: 
   54:         if (test_cases[i].skip == 0) {
   55:             str = qobject_to_json(obj);
   56:             fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
   57: 
   58:             qobject_decref(obj);
   59:         }
   60: 
   61:         QDECREF(str);
   62:     }
   63: }
   64: END_TEST
   65: 
   66: START_TEST(simple_string)
   67: {
   68:     int i;
   69:     struct {
   70:         const char *encoded;
   71:         const char *decoded;
   72:     } test_cases[] = {
   73:         { "\"hello world\"", "hello world" },
   74:         { "\"the quick brown fox jumped over the fence\"",
   75:           "the quick brown fox jumped over the fence" },
   76:         {}
   77:     };
   78: 
   79:     for (i = 0; test_cases[i].encoded; i++) {
   80:         QObject *obj;
   81:         QString *str;
   82: 
   83:         obj = qobject_from_json(test_cases[i].encoded);
   84: 
   85:         fail_unless(obj != NULL);
   86:         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
   87:         
   88:         str = qobject_to_qstring(obj);
   89:         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
   90: 
   91:         str = qobject_to_json(obj);
   92:         fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
   93: 
   94:         qobject_decref(obj);
   95:         
   96:         QDECREF(str);
   97:     }
   98: }
   99: END_TEST
  100: 
  101: START_TEST(single_quote_string)
  102: {
  103:     int i;
  104:     struct {
  105:         const char *encoded;
  106:         const char *decoded;
  107:     } test_cases[] = {
  108:         { "'hello world'", "hello world" },
  109:         { "'the quick brown fox \\' jumped over the fence'",
  110:           "the quick brown fox ' jumped over the fence" },
  111:         {}
  112:     };
  113: 
  114:     for (i = 0; test_cases[i].encoded; i++) {
  115:         QObject *obj;
  116:         QString *str;
  117: 
  118:         obj = qobject_from_json(test_cases[i].encoded);
  119: 
  120:         fail_unless(obj != NULL);
  121:         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
  122:         
  123:         str = qobject_to_qstring(obj);
  124:         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
  125: 
  126:         QDECREF(str);
  127:     }
  128: }
  129: END_TEST
  130: 
  131: START_TEST(vararg_string)
  132: {
  133:     int i;
  134:     struct {
  135:         const char *decoded;
  136:     } test_cases[] = {
  137:         { "hello world" },
  138:         { "the quick brown fox jumped over the fence" },
  139:         {}
  140:     };
  141: 
  142:     for (i = 0; test_cases[i].decoded; i++) {
  143:         QObject *obj;
  144:         QString *str;
  145: 
  146:         obj = qobject_from_jsonf("%s", test_cases[i].decoded);
  147: 
  148:         fail_unless(obj != NULL);
  149:         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
  150:         
  151:         str = qobject_to_qstring(obj);
  152:         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
  153: 
  154:         QDECREF(str);
  155:     }
  156: }
  157: END_TEST
  158: 
  159: START_TEST(simple_number)
  160: {
  161:     int i;
  162:     struct {
  163:         const char *encoded;
  164:         int64_t decoded;
  165:         int skip;
  166:     } test_cases[] = {
  167:         { "0", 0 },
  168:         { "1234", 1234 },
  169:         { "1", 1 },
  170:         { "-32", -32 },
  171:         { "-0", 0, .skip = 1 },
  172:         { },
  173:     };
  174: 
  175:     for (i = 0; test_cases[i].encoded; i++) {
  176:         QObject *obj;
  177:         QInt *qint;
  178: 
  179:         obj = qobject_from_json(test_cases[i].encoded);
  180:         fail_unless(obj != NULL);
  181:         fail_unless(qobject_type(obj) == QTYPE_QINT);
  182: 
  183:         qint = qobject_to_qint(obj);
  184:         fail_unless(qint_get_int(qint) == test_cases[i].decoded);
  185:         if (test_cases[i].skip == 0) {
  186:             QString *str;
  187: 
  188:             str = qobject_to_json(obj);
  189:             fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
  190:             QDECREF(str);
  191:         }
  192: 
  193:         QDECREF(qint);
  194:     }
  195: }
  196: END_TEST
  197: 
  198: START_TEST(float_number)
  199: {
  200:     int i;
  201:     struct {
  202:         const char *encoded;
  203:         double decoded;
  204:         int skip;
  205:     } test_cases[] = {
  206:         { "32.43", 32.43 },
  207:         { "0.222", 0.222 },
  208:         { "-32.12313", -32.12313 },
  209:         { "-32.20e-10", -32.20e-10, .skip = 1 },
  210:         { },
  211:     };
  212: 
  213:     for (i = 0; test_cases[i].encoded; i++) {
  214:         QObject *obj;
  215:         QFloat *qfloat;
  216: 
  217:         obj = qobject_from_json(test_cases[i].encoded);
  218:         fail_unless(obj != NULL);
  219:         fail_unless(qobject_type(obj) == QTYPE_QFLOAT);
  220: 
  221:         qfloat = qobject_to_qfloat(obj);
  222:         fail_unless(qfloat_get_double(qfloat) == test_cases[i].decoded);
  223: 
  224:         if (test_cases[i].skip == 0) {
  225:             QString *str;
  226: 
  227:             str = qobject_to_json(obj);
  228:             fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
  229:             QDECREF(str);
  230:         }
  231: 
  232:         QDECREF(qfloat);
  233:     }
  234: }
  235: END_TEST
  236: 
  237: START_TEST(vararg_number)
  238: {
  239:     QObject *obj;
  240:     QInt *qint;
  241:     QFloat *qfloat;
  242:     int value = 0x2342;
  243:     int64_t value64 = 0x2342342343LL;
  244:     double valuef = 2.323423423;
  245: 
  246:     obj = qobject_from_jsonf("%d", value);
  247:     fail_unless(obj != NULL);
  248:     fail_unless(qobject_type(obj) == QTYPE_QINT);
  249: 
  250:     qint = qobject_to_qint(obj);
  251:     fail_unless(qint_get_int(qint) == value);
  252: 
  253:     QDECREF(qint);
  254: 
  255:     obj = qobject_from_jsonf("%" PRId64, value64);
  256:     fail_unless(obj != NULL);
  257:     fail_unless(qobject_type(obj) == QTYPE_QINT);
  258: 
  259:     qint = qobject_to_qint(obj);
  260:     fail_unless(qint_get_int(qint) == value64);
  261: 
  262:     QDECREF(qint);
  263: 
  264:     obj = qobject_from_jsonf("%f", valuef);
  265:     fail_unless(obj != NULL);
  266:     fail_unless(qobject_type(obj) == QTYPE_QFLOAT);
  267: 
  268:     qfloat = qobject_to_qfloat(obj);
  269:     fail_unless(qfloat_get_double(qfloat) == valuef);
  270: 
  271:     QDECREF(qfloat);
  272: }
  273: END_TEST
  274: 
  275: START_TEST(keyword_literal)
  276: {
  277:     QObject *obj;
  278:     QBool *qbool;
  279:     QString *str;
  280: 
  281:     obj = qobject_from_json("true");
  282:     fail_unless(obj != NULL);
  283:     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
  284: 
  285:     qbool = qobject_to_qbool(obj);
  286:     fail_unless(qbool_get_int(qbool) != 0);
  287: 
  288:     str = qobject_to_json(obj);
  289:     fail_unless(strcmp(qstring_get_str(str), "true") == 0);
  290:     QDECREF(str);
  291: 
  292:     QDECREF(qbool);
  293: 
  294:     obj = qobject_from_json("false");
  295:     fail_unless(obj != NULL);
  296:     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
  297: 
  298:     qbool = qobject_to_qbool(obj);
  299:     fail_unless(qbool_get_int(qbool) == 0);
  300: 
  301:     str = qobject_to_json(obj);
  302:     fail_unless(strcmp(qstring_get_str(str), "false") == 0);
  303:     QDECREF(str);
  304: 
  305:     QDECREF(qbool);
  306: 
  307:     obj = qobject_from_jsonf("%i", false);
  308:     fail_unless(obj != NULL);
  309:     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
  310: 
  311:     qbool = qobject_to_qbool(obj);
  312:     fail_unless(qbool_get_int(qbool) == 0);
  313: 
  314:     QDECREF(qbool);
  315:     
  316:     obj = qobject_from_jsonf("%i", true);
  317:     fail_unless(obj != NULL);
  318:     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
  319: 
  320:     qbool = qobject_to_qbool(obj);
  321:     fail_unless(qbool_get_int(qbool) != 0);
  322: 
  323:     QDECREF(qbool);
  324: }
  325: END_TEST
  326: 
  327: typedef struct LiteralQDictEntry LiteralQDictEntry;
  328: typedef struct LiteralQObject LiteralQObject;
  329: 
  330: struct LiteralQObject
  331: {
  332:     int type;
  333:     union {
  334:         int64_t qint;
  335:         const char *qstr;
  336:         LiteralQDictEntry *qdict;
  337:         LiteralQObject *qlist;
  338:     } value;
  339: };
  340: 
  341: struct LiteralQDictEntry
  342: {
  343:     const char *key;
  344:     LiteralQObject value;
  345: };
  346: 
  347: #define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)}
  348: #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
  349: #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
  350: #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
  351: 
  352: typedef struct QListCompareHelper
  353: {
  354:     int index;
  355:     LiteralQObject *objs;
  356:     int result;
  357: } QListCompareHelper;
  358: 
  359: static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
  360: 
  361: static void compare_helper(QObject *obj, void *opaque)
  362: {
  363:     QListCompareHelper *helper = opaque;
  364: 
  365:     if (helper->result == 0) {
  366:         return;
  367:     }
  368: 
  369:     if (helper->objs[helper->index].type == QTYPE_NONE) {
  370:         helper->result = 0;
  371:         return;
  372:     }
  373: 
  374:     helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
  375: }
  376: 
  377: static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
  378: {
  379:     if (lhs->type != qobject_type(rhs)) {
  380:         return 0;
  381:     }
  382: 
  383:     switch (lhs->type) {
  384:     case QTYPE_QINT:
  385:         return lhs->value.qint == qint_get_int(qobject_to_qint(rhs));
  386:     case QTYPE_QSTRING:
  387:         return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
  388:     case QTYPE_QDICT: {
  389:         int i;
  390: 
  391:         for (i = 0; lhs->value.qdict[i].key; i++) {
  392:             QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key);
  393: 
  394:             if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
  395:                 return 0;
  396:             }
  397:         }
  398: 
  399:         return 1;
  400:     }
  401:     case QTYPE_QLIST: {
  402:         QListCompareHelper helper;
  403: 
  404:         helper.index = 0;
  405:         helper.objs = lhs->value.qlist;
  406:         helper.result = 1;
  407:         
  408:         qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
  409: 
  410:         return helper.result;
  411:     }
  412:     default:
  413:         break;
  414:     }
  415: 
  416:     return 0;
  417: }
  418: 
  419: START_TEST(simple_dict)
  420: {
  421:     int i;
  422:     struct {
  423:         const char *encoded;
  424:         LiteralQObject decoded;
  425:     } test_cases[] = {
  426:         {
  427:             .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
  428:             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
  429:                         { "foo", QLIT_QINT(42) },
  430:                         { "bar", QLIT_QSTR("hello world") },
  431:                         { }
  432:                     })),
  433:         }, {
  434:             .encoded = "{}",
  435:             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
  436:                         { }
  437:                     })),
  438:         }, {
  439:             .encoded = "{\"foo\": 43}",
  440:             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
  441:                         { "foo", QLIT_QINT(43) },
  442:                         { }
  443:                     })),
  444:         },
  445:         { }
  446:     };
  447: 
  448:     for (i = 0; test_cases[i].encoded; i++) {
  449:         QObject *obj;
  450:         QString *str;
  451: 
  452:         obj = qobject_from_json(test_cases[i].encoded);
  453:         fail_unless(obj != NULL);
  454:         fail_unless(qobject_type(obj) == QTYPE_QDICT);
  455: 
  456:         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
  457: 
  458:         str = qobject_to_json(obj);
  459:         qobject_decref(obj);
  460: 
  461:         obj = qobject_from_json(qstring_get_str(str));
  462:         fail_unless(obj != NULL);
  463:         fail_unless(qobject_type(obj) == QTYPE_QDICT);
  464: 
  465:         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
  466:         qobject_decref(obj);
  467:         QDECREF(str);
  468:     }
  469: }
  470: END_TEST
  471: 
  472: START_TEST(simple_list)
  473: {
  474:     int i;
  475:     struct {
  476:         const char *encoded;
  477:         LiteralQObject decoded;
  478:     } test_cases[] = {
  479:         {
  480:             .encoded = "[43,42]",
  481:             .decoded = QLIT_QLIST(((LiteralQObject[]){
  482:                         QLIT_QINT(43),
  483:                         QLIT_QINT(42),
  484:                         { }
  485:                     })),
  486:         },
  487:         {
  488:             .encoded = "[43]",
  489:             .decoded = QLIT_QLIST(((LiteralQObject[]){
  490:                         QLIT_QINT(43),
  491:                         { }
  492:                     })),
  493:         },
  494:         {
  495:             .encoded = "[]",
  496:             .decoded = QLIT_QLIST(((LiteralQObject[]){
  497:                         { }
  498:                     })),
  499:         },
  500:         {
  501:             .encoded = "[{}]",
  502:             .decoded = QLIT_QLIST(((LiteralQObject[]){
  503:                         QLIT_QDICT(((LiteralQDictEntry[]){
  504:                                     {},
  505:                                         })),
  506:                         {},
  507:                             })),
  508:         },
  509:         { }
  510:     };
  511: 
  512:     for (i = 0; test_cases[i].encoded; i++) {
  513:         QObject *obj;
  514:         QString *str;
  515: 
  516:         obj = qobject_from_json(test_cases[i].encoded);
  517:         fail_unless(obj != NULL);
  518:         fail_unless(qobject_type(obj) == QTYPE_QLIST);
  519: 
  520:         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
  521: 
  522:         str = qobject_to_json(obj);
  523:         qobject_decref(obj);
  524: 
  525:         obj = qobject_from_json(qstring_get_str(str));
  526:         fail_unless(obj != NULL);
  527:         fail_unless(qobject_type(obj) == QTYPE_QLIST);
  528: 
  529:         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
  530:         qobject_decref(obj);
  531:         QDECREF(str);
  532:     }
  533: }
  534: END_TEST
  535: 
  536: START_TEST(simple_whitespace)
  537: {
  538:     int i;
  539:     struct {
  540:         const char *encoded;
  541:         LiteralQObject decoded;
  542:     } test_cases[] = {
  543:         {
  544:             .encoded = " [ 43 , 42 ]",
  545:             .decoded = QLIT_QLIST(((LiteralQObject[]){
  546:                         QLIT_QINT(43),
  547:                         QLIT_QINT(42),
  548:                         { }
  549:                     })),
  550:         },
  551:         {
  552:             .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
  553:             .decoded = QLIT_QLIST(((LiteralQObject[]){
  554:                         QLIT_QINT(43),
  555:                         QLIT_QDICT(((LiteralQDictEntry[]){
  556:                                     { "h", QLIT_QSTR("b") },
  557:                                     { }})),
  558:                         QLIT_QLIST(((LiteralQObject[]){
  559:                                     { }})),
  560:                         QLIT_QINT(42),
  561:                         { }
  562:                     })),
  563:         },
  564:         {
  565:             .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
  566:             .decoded = QLIT_QLIST(((LiteralQObject[]){
  567:                         QLIT_QINT(43),
  568:                         QLIT_QDICT(((LiteralQDictEntry[]){
  569:                                     { "h", QLIT_QSTR("b") },
  570:                                     { "a", QLIT_QINT(32) },
  571:                                     { }})),
  572:                         QLIT_QLIST(((LiteralQObject[]){
  573:                                     { }})),
  574:                         QLIT_QINT(42),
  575:                         { }
  576:                     })),
  577:         },
  578:         { }
  579:     };
  580: 
  581:     for (i = 0; test_cases[i].encoded; i++) {
  582:         QObject *obj;
  583:         QString *str;
  584: 
  585:         obj = qobject_from_json(test_cases[i].encoded);
  586:         fail_unless(obj != NULL);
  587:         fail_unless(qobject_type(obj) == QTYPE_QLIST);
  588: 
  589:         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
  590: 
  591:         str = qobject_to_json(obj);
  592:         qobject_decref(obj);
  593: 
  594:         obj = qobject_from_json(qstring_get_str(str));
  595:         fail_unless(obj != NULL);
  596:         fail_unless(qobject_type(obj) == QTYPE_QLIST);
  597: 
  598:         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
  599: 
  600:         qobject_decref(obj);
  601:         QDECREF(str);
  602:     }
  603: }
  604: END_TEST
  605: 
  606: START_TEST(simple_varargs)
  607: {
  608:     QObject *embedded_obj;
  609:     QObject *obj;
  610:     LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
  611:             QLIT_QINT(1),
  612:             QLIT_QINT(2),
  613:             QLIT_QLIST(((LiteralQObject[]){
  614:                         QLIT_QINT(32),
  615:                         QLIT_QINT(42),
  616:                         {}})),
  617:             {}}));
  618: 
  619:     embedded_obj = qobject_from_json("[32, 42]");
  620:     fail_unless(embedded_obj != NULL);
  621: 
  622:     obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
  623:     fail_unless(obj != NULL);
  624: 
  625:     fail_unless(compare_litqobj_to_qobj(&decoded, obj) == 1);
  626: 
  627:     qobject_decref(obj);
  628: }
  629: END_TEST
  630: 
  631: static Suite *qjson_suite(void)
  632: {
  633:     Suite *suite;
  634:     TCase *string_literals, *number_literals, *keyword_literals;
  635:     TCase *dicts, *lists, *whitespace, *varargs;
  636: 
  637:     string_literals = tcase_create("String Literals");
  638:     tcase_add_test(string_literals, simple_string);
  639:     tcase_add_test(string_literals, escaped_string);
  640:     tcase_add_test(string_literals, single_quote_string);
  641:     tcase_add_test(string_literals, vararg_string);
  642: 
  643:     number_literals = tcase_create("Number Literals");
  644:     tcase_add_test(number_literals, simple_number);
  645:     tcase_add_test(number_literals, float_number);
  646:     tcase_add_test(number_literals, vararg_number);
  647: 
  648:     keyword_literals = tcase_create("Keywords");
  649:     tcase_add_test(keyword_literals, keyword_literal);
  650:     dicts = tcase_create("Objects");
  651:     tcase_add_test(dicts, simple_dict);
  652:     lists = tcase_create("Lists");
  653:     tcase_add_test(lists, simple_list);
  654: 
  655:     whitespace = tcase_create("Whitespace");
  656:     tcase_add_test(whitespace, simple_whitespace);
  657: 
  658:     varargs = tcase_create("Varargs");
  659:     tcase_add_test(varargs, simple_varargs);
  660: 
  661:     suite = suite_create("QJSON test-suite");
  662:     suite_add_tcase(suite, string_literals);
  663:     suite_add_tcase(suite, number_literals);
  664:     suite_add_tcase(suite, keyword_literals);
  665:     suite_add_tcase(suite, dicts);
  666:     suite_add_tcase(suite, lists);
  667:     suite_add_tcase(suite, whitespace);
  668:     suite_add_tcase(suite, varargs);
  669: 
  670:     return suite;
  671: }
  672: 
  673: int main(void)
  674: {
  675:     int nf;
  676:     Suite *s;
  677:     SRunner *sr;
  678: 
  679:     s = qjson_suite();
  680:     sr = srunner_create(s);
  681:         
  682:     srunner_run_all(sr, CK_NORMAL);
  683:     nf = srunner_ntests_failed(sr);
  684:     srunner_free(sr);
  685:     
  686:     return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  687: }

unix.superglobalmegacorp.com