test/testautomation_platform.c
author Edward Rudd <urkle@outoforder.cc>
Wed, 03 Dec 2014 12:47:39 -0500
changeset 9262 b3df9db209b0
parent 9260 039714172dc3
child 10782 1de6d4633ee6
permissions -rw-r--r--
ugh.. stray character
     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    int 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              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    int 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", 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              SDL_strlen(testError),
   313              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    int 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              SDL_strlen(testError),
   351              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    int len;
   377 
   378    /* Reset */
   379    SDL_ClearError();
   380    SDLTest_AssertPass("SDL_ClearError()");
   381 
   382    /* Check for no-op */
   383    result = SDL_SetError(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              len);
   395    }
   396 
   397    /* Set */
   398    result = SDL_SetError(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(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              len);
   415    }
   416 
   417    /* Reset */
   418    SDL_ClearError();
   419    SDLTest_AssertPass("SDL_ClearError()");
   420 
   421    /* Set and check */
   422    result = SDL_SetError(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              SDL_strlen(probeError),
   434              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 };