sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

testautomation_platform.c (17533B)


      1 /**
      2  * Original code: automated SDL platform test written by Edgar Simo "bobbens"
      3  * Extended and updated by aschiffler at ferzkopp dot net
      4  */
      5 
      6 #include <stdio.h>
      7 
      8 #include "SDL.h"
      9 #include "SDL_test.h"
     10 
     11 /* ================= Test Case Implementation ================== */
     12 
     13 /* Helper functions */
     14 
     15 /**
     16  * @brief Compare sizes of types.
     17  *
     18  * @note Watcom C flags these as Warning 201: "Unreachable code" if you just
     19  *  compare them directly, so we push it through a function to keep the
     20  *  compiler quiet.  --ryan.
     21  */
     22 static int _compareSizeOfType( size_t sizeoftype, size_t hardcodetype )
     23 {
     24     return sizeoftype != hardcodetype;
     25 }
     26 
     27 /* Test case functions */
     28 
     29 /**
     30  * @brief Tests type sizes.
     31  */
     32 int platform_testTypes(void *arg)
     33 {
     34    int ret;
     35 
     36    ret = _compareSizeOfType( sizeof(Uint8), 1 );
     37    SDLTest_AssertCheck( ret == 0, "sizeof(Uint8) = %lu, expected  1", (unsigned long)sizeof(Uint8) );
     38 
     39    ret = _compareSizeOfType( sizeof(Uint16), 2 );
     40    SDLTest_AssertCheck( ret == 0, "sizeof(Uint16) = %lu, expected 2", (unsigned long)sizeof(Uint16) );
     41 
     42    ret = _compareSizeOfType( sizeof(Uint32), 4 );
     43    SDLTest_AssertCheck( ret == 0, "sizeof(Uint32) = %lu, expected 4", (unsigned long)sizeof(Uint32) );
     44 
     45    ret = _compareSizeOfType( sizeof(Uint64), 8 );
     46    SDLTest_AssertCheck( ret == 0, "sizeof(Uint64) = %lu, expected 8", (unsigned long)sizeof(Uint64) );
     47 
     48    return TEST_COMPLETED;
     49 }
     50 
     51 /**
     52  * @brief Tests platform endianness and SDL_SwapXY functions.
     53  */
     54 int platform_testEndianessAndSwap(void *arg)
     55 {
     56     int real_byteorder;
     57     Uint16 value = 0x1234;
     58     Uint16 value16 = 0xCDAB;
     59     Uint16 swapped16 = 0xABCD;
     60     Uint32 value32 = 0xEFBEADDE;
     61     Uint32 swapped32 = 0xDEADBEEF;
     62 
     63     Uint64 value64, swapped64;
     64     value64 = 0xEFBEADDE;
     65     value64 <<= 32;
     66     value64 |= 0xCDAB3412;
     67     swapped64 = 0x1234ABCD;
     68     swapped64 <<= 32;
     69     swapped64 |= 0xDEADBEEF;
     70 
     71     if ((*((char *) &value) >> 4) == 0x1) {
     72         real_byteorder = SDL_BIG_ENDIAN;
     73     } else {
     74         real_byteorder = SDL_LIL_ENDIAN;
     75     }
     76 
     77     /* Test endianness. */
     78     SDLTest_AssertCheck( real_byteorder == SDL_BYTEORDER,
     79              "Machine detected as %s endian, appears to be %s endian.",
     80              (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big",
     81              (real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big" );
     82 
     83     /* Test 16 swap. */
     84     SDLTest_AssertCheck( SDL_Swap16(value16) == swapped16,
     85              "SDL_Swap16(): 16 bit swapped: 0x%X => 0x%X",
     86              value16, SDL_Swap16(value16) );
     87 
     88     /* Test 32 swap. */
     89     SDLTest_AssertCheck( SDL_Swap32(value32) == swapped32,
     90              "SDL_Swap32(): 32 bit swapped: 0x%X => 0x%X",
     91              value32, SDL_Swap32(value32) );
     92 
     93     /* Test 64 swap. */
     94     SDLTest_AssertCheck( SDL_Swap64(value64) == swapped64,
     95              "SDL_Swap64(): 64 bit swapped: 0x%"SDL_PRIX64" => 0x%"SDL_PRIX64,
     96              value64, SDL_Swap64(value64) );
     97 
     98    return TEST_COMPLETED;
     99 }
    100 
    101 /* !
    102  * \brief Tests SDL_GetXYZ() functions
    103  * \sa
    104  * http://wiki.libsdl.org/moin.cgi/SDL_GetPlatform
    105  * http://wiki.libsdl.org/moin.cgi/SDL_GetCPUCount
    106  * http://wiki.libsdl.org/moin.cgi/SDL_GetCPUCacheLineSize
    107  * http://wiki.libsdl.org/moin.cgi/SDL_GetRevision
    108  * http://wiki.libsdl.org/moin.cgi/SDL_GetRevisionNumber
    109  */
    110 int platform_testGetFunctions (void *arg)
    111 {
    112    char *platform;
    113    char *revision;
    114    int ret;
    115    size_t len;
    116 
    117    platform = (char *)SDL_GetPlatform();
    118    SDLTest_AssertPass("SDL_GetPlatform()");
    119    SDLTest_AssertCheck(platform != NULL, "SDL_GetPlatform() != NULL");
    120    if (platform != NULL) {
    121      len = SDL_strlen(platform);
    122      SDLTest_AssertCheck(len > 0,
    123              "SDL_GetPlatform(): expected non-empty platform, was platform: '%s', len: %i",
    124              platform,
    125              (int) len);
    126    }
    127 
    128    ret = SDL_GetCPUCount();
    129    SDLTest_AssertPass("SDL_GetCPUCount()");
    130    SDLTest_AssertCheck(ret > 0,
    131              "SDL_GetCPUCount(): expected count > 0, was: %i",
    132              ret);
    133 
    134    ret = SDL_GetCPUCacheLineSize();
    135    SDLTest_AssertPass("SDL_GetCPUCacheLineSize()");
    136    SDLTest_AssertCheck(ret >= 0,
    137              "SDL_GetCPUCacheLineSize(): expected size >= 0, was: %i",
    138              ret);
    139 
    140    revision = (char *)SDL_GetRevision();
    141    SDLTest_AssertPass("SDL_GetRevision()");
    142    SDLTest_AssertCheck(revision != NULL, "SDL_GetRevision() != NULL");
    143 
    144    ret = SDL_GetRevisionNumber();
    145    SDLTest_AssertPass("SDL_GetRevisionNumber()");
    146 
    147    return TEST_COMPLETED;
    148 }
    149 
    150 /* !
    151  * \brief Tests SDL_HasXYZ() functions
    152  * \sa
    153  * http://wiki.libsdl.org/moin.cgi/SDL_Has3DNow
    154  * http://wiki.libsdl.org/moin.cgi/SDL_HasAltiVec
    155  * http://wiki.libsdl.org/moin.cgi/SDL_HasMMX
    156  * http://wiki.libsdl.org/moin.cgi/SDL_HasRDTSC
    157  * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE
    158  * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE2
    159  * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE3
    160  * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE41
    161  * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE42
    162  * http://wiki.libsdl.org/moin.cgi/SDL_HasAVX
    163  */
    164 int platform_testHasFunctions (void *arg)
    165 {
    166    int ret;
    167 
    168    /* TODO: independently determine and compare values as well */
    169 
    170    ret = SDL_HasRDTSC();
    171    SDLTest_AssertPass("SDL_HasRDTSC()");
    172 
    173    ret = SDL_HasAltiVec();
    174    SDLTest_AssertPass("SDL_HasAltiVec()");
    175 
    176    ret = SDL_HasMMX();
    177    SDLTest_AssertPass("SDL_HasMMX()");
    178 
    179    ret = SDL_Has3DNow();
    180    SDLTest_AssertPass("SDL_Has3DNow()");
    181 
    182    ret = SDL_HasSSE();
    183    SDLTest_AssertPass("SDL_HasSSE()");
    184 
    185    ret = SDL_HasSSE2();
    186    SDLTest_AssertPass("SDL_HasSSE2()");
    187 
    188    ret = SDL_HasSSE3();
    189    SDLTest_AssertPass("SDL_HasSSE3()");
    190 
    191    ret = SDL_HasSSE41();
    192    SDLTest_AssertPass("SDL_HasSSE41()");
    193 
    194    ret = SDL_HasSSE42();
    195    SDLTest_AssertPass("SDL_HasSSE42()");
    196 
    197    ret = SDL_HasAVX();
    198    SDLTest_AssertPass("SDL_HasAVX()");
    199 
    200    return TEST_COMPLETED;
    201 }
    202 
    203 /* !
    204  * \brief Tests SDL_GetVersion
    205  * \sa
    206  * http://wiki.libsdl.org/moin.cgi/SDL_GetVersion
    207  */
    208 int platform_testGetVersion(void *arg)
    209 {
    210    SDL_version linked;
    211    int major = SDL_MAJOR_VERSION;
    212    int minor = SDL_MINOR_VERSION;
    213 
    214    SDL_GetVersion(&linked);
    215    SDLTest_AssertCheck( linked.major >= major,
    216              "SDL_GetVersion(): returned major %i (>= %i)",
    217              linked.major,
    218              major);
    219    SDLTest_AssertCheck( linked.minor >= minor,
    220              "SDL_GetVersion(): returned minor %i (>= %i)",
    221              linked.minor,
    222              minor);
    223 
    224    return TEST_COMPLETED;
    225 }
    226 
    227 
    228 /* !
    229  * \brief Tests SDL_VERSION macro
    230  */
    231 int platform_testSDLVersion(void *arg)
    232 {
    233    SDL_version compiled;
    234    int major = SDL_MAJOR_VERSION;
    235    int minor = SDL_MINOR_VERSION;
    236 
    237    SDL_VERSION(&compiled);
    238    SDLTest_AssertCheck( compiled.major >= major,
    239              "SDL_VERSION() returned major %i (>= %i)",
    240              compiled.major,
    241              major);
    242    SDLTest_AssertCheck( compiled.minor >= minor,
    243              "SDL_VERSION() returned minor %i (>= %i)",
    244              compiled.minor,
    245              minor);
    246 
    247    return TEST_COMPLETED;
    248 }
    249 
    250 
    251 /* !
    252  * \brief Tests default SDL_Init
    253  */
    254 int platform_testDefaultInit(void *arg)
    255 {
    256    int ret;
    257    int subsystem;
    258 
    259    subsystem = SDL_WasInit(SDL_INIT_EVERYTHING);
    260    SDLTest_AssertCheck( subsystem != 0,
    261              "SDL_WasInit(0): returned %i, expected != 0",
    262              subsystem);
    263 
    264    ret = SDL_Init(SDL_WasInit(SDL_INIT_EVERYTHING));
    265    SDLTest_AssertCheck( ret == 0,
    266              "SDL_Init(0): returned %i, expected 0, error: %s",
    267              ret,
    268              SDL_GetError());
    269 
    270    return TEST_COMPLETED;
    271 }
    272 
    273 /* !
    274  * \brief Tests SDL_Get/Set/ClearError
    275  * \sa
    276  * http://wiki.libsdl.org/moin.cgi/SDL_GetError
    277  * http://wiki.libsdl.org/moin.cgi/SDL_SetError
    278  * http://wiki.libsdl.org/moin.cgi/SDL_ClearError
    279  */
    280 int platform_testGetSetClearError(void *arg)
    281 {
    282    int result;
    283    const char *testError = "Testing";
    284    char *lastError;
    285    size_t len;
    286 
    287    SDL_ClearError();
    288    SDLTest_AssertPass("SDL_ClearError()");
    289 
    290    lastError = (char *)SDL_GetError();
    291    SDLTest_AssertPass("SDL_GetError()");
    292    SDLTest_AssertCheck(lastError != NULL,
    293              "SDL_GetError() != NULL");
    294    if (lastError != NULL)
    295    {
    296      len = SDL_strlen(lastError);
    297      SDLTest_AssertCheck(len == 0,
    298              "SDL_GetError(): no message expected, len: %i", (int) len);
    299    }
    300 
    301    result = SDL_SetError("%s", testError);
    302    SDLTest_AssertPass("SDL_SetError()");
    303    SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result);
    304    lastError = (char *)SDL_GetError();
    305    SDLTest_AssertCheck(lastError != NULL,
    306              "SDL_GetError() != NULL");
    307    if (lastError != NULL)
    308    {
    309      len = SDL_strlen(lastError);
    310      SDLTest_AssertCheck(len == SDL_strlen(testError),
    311              "SDL_GetError(): expected message len %i, was len: %i",
    312              (int) SDL_strlen(testError),
    313              (int) len);
    314      SDLTest_AssertCheck(SDL_strcmp(lastError, testError) == 0,
    315              "SDL_GetError(): expected message %s, was message: %s",
    316              testError,
    317              lastError);
    318    }
    319 
    320    /* Clean up */
    321    SDL_ClearError();
    322    SDLTest_AssertPass("SDL_ClearError()");
    323 
    324    return TEST_COMPLETED;
    325 }
    326 
    327 /* !
    328  * \brief Tests SDL_SetError with empty input
    329  * \sa
    330  * http://wiki.libsdl.org/moin.cgi/SDL_SetError
    331  */
    332 int platform_testSetErrorEmptyInput(void *arg)
    333 {
    334    int result;
    335    const char *testError = "";
    336    char *lastError;
    337    size_t len;
    338 
    339    result = SDL_SetError("%s", testError);
    340    SDLTest_AssertPass("SDL_SetError()");
    341    SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result);
    342    lastError = (char *)SDL_GetError();
    343    SDLTest_AssertCheck(lastError != NULL,
    344              "SDL_GetError() != NULL");
    345    if (lastError != NULL)
    346    {
    347      len = SDL_strlen(lastError);
    348      SDLTest_AssertCheck(len == SDL_strlen(testError),
    349              "SDL_GetError(): expected message len %i, was len: %i",
    350              (int) SDL_strlen(testError),
    351              (int) len);
    352      SDLTest_AssertCheck(SDL_strcmp(lastError, testError) == 0,
    353              "SDL_GetError(): expected message '%s', was message: '%s'",
    354              testError,
    355              lastError);
    356    }
    357 
    358    /* Clean up */
    359    SDL_ClearError();
    360    SDLTest_AssertPass("SDL_ClearError()");
    361 
    362    return TEST_COMPLETED;
    363 }
    364 
    365 /* !
    366  * \brief Tests SDL_SetError with invalid input
    367  * \sa
    368  * http://wiki.libsdl.org/moin.cgi/SDL_SetError
    369  */
    370 int platform_testSetErrorInvalidInput(void *arg)
    371 {
    372    int result;
    373    const char *invalidError = NULL;
    374    const char *probeError = "Testing";
    375    char *lastError;
    376    size_t len;
    377 
    378    /* Reset */
    379    SDL_ClearError();
    380    SDLTest_AssertPass("SDL_ClearError()");
    381 
    382    /* Check for no-op */
    383    result = SDL_SetError("%s", invalidError);
    384    SDLTest_AssertPass("SDL_SetError()");
    385    SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result);
    386    lastError = (char *)SDL_GetError();
    387    SDLTest_AssertCheck(lastError != NULL,
    388              "SDL_GetError() != NULL");
    389    if (lastError != NULL)
    390    {
    391      len = SDL_strlen(lastError);
    392      SDLTest_AssertCheck(len == 0,
    393              "SDL_GetError(): expected message len 0, was len: %i",
    394              (int) len);
    395    }
    396 
    397    /* Set */
    398    result = SDL_SetError("%s", probeError);
    399    SDLTest_AssertPass("SDL_SetError('%s')", probeError);
    400    SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result);
    401 
    402    /* Check for no-op */
    403    result = SDL_SetError("%s", invalidError);
    404    SDLTest_AssertPass("SDL_SetError(NULL)");
    405    SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result);
    406    lastError = (char *)SDL_GetError();
    407    SDLTest_AssertCheck(lastError != NULL,
    408              "SDL_GetError() != NULL");
    409    if (lastError != NULL)
    410    {
    411      len = SDL_strlen(lastError);
    412      SDLTest_AssertCheck(len == 0,
    413              "SDL_GetError(): expected message len 0, was len: %i",
    414              (int) len);
    415    }
    416 
    417    /* Reset */
    418    SDL_ClearError();
    419    SDLTest_AssertPass("SDL_ClearError()");
    420 
    421    /* Set and check */
    422    result = SDL_SetError("%s", probeError);
    423    SDLTest_AssertPass("SDL_SetError()");
    424    SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result);
    425    lastError = (char *)SDL_GetError();
    426    SDLTest_AssertCheck(lastError != NULL,
    427              "SDL_GetError() != NULL");
    428    if (lastError != NULL)
    429    {
    430      len = SDL_strlen(lastError);
    431      SDLTest_AssertCheck(len == SDL_strlen(probeError),
    432              "SDL_GetError(): expected message len %i, was len: %i",
    433              (int) SDL_strlen(probeError),
    434              (int) len);
    435      SDLTest_AssertCheck(SDL_strcmp(lastError, probeError) == 0,
    436              "SDL_GetError(): expected message '%s', was message: '%s'",
    437              probeError,
    438              lastError);
    439    }
    440    
    441    /* Clean up */
    442    SDL_ClearError();
    443    SDLTest_AssertPass("SDL_ClearError()");
    444 
    445    return TEST_COMPLETED;
    446 }
    447 
    448 /* !
    449  * \brief Tests SDL_GetPowerInfo
    450  * \sa
    451  * http://wiki.libsdl.org/moin.cgi/SDL_GetPowerInfo
    452  */
    453 int platform_testGetPowerInfo(void *arg)
    454 {
    455    SDL_PowerState state;
    456    SDL_PowerState stateAgain;
    457    int secs;
    458    int secsAgain;
    459    int pct;
    460    int pctAgain;
    461 
    462    state = SDL_GetPowerInfo(&secs, &pct);
    463    SDLTest_AssertPass("SDL_GetPowerInfo()");
    464    SDLTest_AssertCheck(
    465        state==SDL_POWERSTATE_UNKNOWN ||
    466        state==SDL_POWERSTATE_ON_BATTERY ||
    467        state==SDL_POWERSTATE_NO_BATTERY ||
    468        state==SDL_POWERSTATE_CHARGING ||
    469        state==SDL_POWERSTATE_CHARGED,
    470        "SDL_GetPowerInfo(): state %i is one of the expected values",
    471        (int)state);
    472 
    473    if (state==SDL_POWERSTATE_ON_BATTERY)
    474    {
    475       SDLTest_AssertCheck(
    476          secs >= 0,
    477          "SDL_GetPowerInfo(): on battery, secs >= 0, was: %i",
    478          secs);
    479       SDLTest_AssertCheck(
    480          (pct >= 0) && (pct <= 100),
    481          "SDL_GetPowerInfo(): on battery, pct=[0,100], was: %i",
    482          pct);
    483    }
    484 
    485    if (state==SDL_POWERSTATE_UNKNOWN ||
    486        state==SDL_POWERSTATE_NO_BATTERY)
    487    {
    488       SDLTest_AssertCheck(
    489          secs == -1,
    490          "SDL_GetPowerInfo(): no battery, secs == -1, was: %i",
    491          secs);
    492       SDLTest_AssertCheck(
    493          pct == -1,
    494          "SDL_GetPowerInfo(): no battery, pct == -1, was: %i",
    495          pct);
    496    }
    497 
    498    /* Partial return value variations */
    499    stateAgain = SDL_GetPowerInfo(&secsAgain, NULL);
    500    SDLTest_AssertCheck(
    501         state==stateAgain,
    502         "State %i returned when only 'secs' requested",
    503         stateAgain);
    504    SDLTest_AssertCheck(
    505         secs==secsAgain,
    506         "Value %i matches when only 'secs' requested",
    507         secsAgain);
    508    stateAgain = SDL_GetPowerInfo(NULL, &pctAgain);
    509    SDLTest_AssertCheck(
    510         state==stateAgain,
    511         "State %i returned when only 'pct' requested",
    512         stateAgain);
    513    SDLTest_AssertCheck(
    514         pct==pctAgain,
    515         "Value %i matches when only 'pct' requested",
    516         pctAgain);
    517    stateAgain = SDL_GetPowerInfo(NULL, NULL);
    518    SDLTest_AssertCheck(
    519         state==stateAgain,
    520         "State %i returned when no value requested",
    521         stateAgain);
    522 
    523    return TEST_COMPLETED;
    524 }
    525 
    526 /* ================= Test References ================== */
    527 
    528 /* Platform test cases */
    529 static const SDLTest_TestCaseReference platformTest1 =
    530         { (SDLTest_TestCaseFp)platform_testTypes, "platform_testTypes", "Tests predefined types", TEST_ENABLED};
    531 
    532 static const SDLTest_TestCaseReference platformTest2 =
    533         { (SDLTest_TestCaseFp)platform_testEndianessAndSwap, "platform_testEndianessAndSwap", "Tests endianess and swap functions", TEST_ENABLED};
    534 
    535 static const SDLTest_TestCaseReference platformTest3 =
    536         { (SDLTest_TestCaseFp)platform_testGetFunctions, "platform_testGetFunctions", "Tests various SDL_GetXYZ functions", TEST_ENABLED};
    537 
    538 static const SDLTest_TestCaseReference platformTest4 =
    539         { (SDLTest_TestCaseFp)platform_testHasFunctions, "platform_testHasFunctions", "Tests various SDL_HasXYZ functions", TEST_ENABLED};
    540 
    541 static const SDLTest_TestCaseReference platformTest5 =
    542         { (SDLTest_TestCaseFp)platform_testGetVersion, "platform_testGetVersion", "Tests SDL_GetVersion function", TEST_ENABLED};
    543 
    544 static const SDLTest_TestCaseReference platformTest6 =
    545         { (SDLTest_TestCaseFp)platform_testSDLVersion, "platform_testSDLVersion", "Tests SDL_VERSION macro", TEST_ENABLED};
    546 
    547 static const SDLTest_TestCaseReference platformTest7 =
    548         { (SDLTest_TestCaseFp)platform_testDefaultInit, "platform_testDefaultInit", "Tests default SDL_Init", TEST_ENABLED};
    549 
    550 static const SDLTest_TestCaseReference platformTest8 =
    551         { (SDLTest_TestCaseFp)platform_testGetSetClearError, "platform_testGetSetClearError", "Tests SDL_Get/Set/ClearError", TEST_ENABLED};
    552 
    553 static const SDLTest_TestCaseReference platformTest9 =
    554         { (SDLTest_TestCaseFp)platform_testSetErrorEmptyInput, "platform_testSetErrorEmptyInput", "Tests SDL_SetError with empty input", TEST_ENABLED};
    555 
    556 static const SDLTest_TestCaseReference platformTest10 =
    557         { (SDLTest_TestCaseFp)platform_testSetErrorInvalidInput, "platform_testSetErrorInvalidInput", "Tests SDL_SetError with invalid input", TEST_ENABLED};
    558 
    559 static const SDLTest_TestCaseReference platformTest11 =
    560         { (SDLTest_TestCaseFp)platform_testGetPowerInfo, "platform_testGetPowerInfo", "Tests SDL_GetPowerInfo function", TEST_ENABLED };
    561 
    562 /* Sequence of Platform test cases */
    563 static const SDLTest_TestCaseReference *platformTests[] =  {
    564     &platformTest1,
    565     &platformTest2,
    566     &platformTest3,
    567     &platformTest4,
    568     &platformTest5,
    569     &platformTest6,
    570     &platformTest7,
    571     &platformTest8,
    572     &platformTest9,
    573     &platformTest10,
    574     &platformTest11,
    575     NULL
    576 };
    577 
    578 /* Platform test suite (global) */
    579 SDLTest_TestSuiteReference platformTestSuite = {
    580     "Platform",
    581     NULL,
    582     platformTests,
    583     NULL
    584 };