int u0020_utf8pathnames__create_file(SG_context * pCtx, const SG_pathname * pPathnameTmpDir, _tableitem * pti) { // create a file in the given tmp dir using the given filename. SG_pathname * pPathnameNewFile; char * pBufUtf8; SG_uint32 lenUtf8; SG_file * pFile; int iResult; SG_bool bTest; // convert the utf32 string into utf8. VERIFY_ERR_CHECK_DISCARD( SG_utf8__from_utf32(pCtx, pti->pa32,&pBufUtf8,&lenUtf8) ); // we have to free pBufUtf8 // verify that the computed utf8 string matches what we thought it should be. // (this hopefully guards against the conversion layer playing NFC/NFD tricks.) iResult = SG_utf8__compare(pBufUtf8,(char *)pti->pa8); VERIFYP_COND("u0020_utf8pathnames",(iResult==0),("Compare failed [%s][%s]",pBufUtf8,pti->pa8)); // create full pathname to the file to create. VERIFY_ERR_CHECK_DISCARD( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathnameNewFile, pPathnameTmpDir,pBufUtf8) ); // create the file and close it. // on Linux when our locale is set to something other than UTF-8, we may // get an ICU(10) == U_INVALID_CHAR_FOUND error because the test data is // not necessarily friendly to any one locale and there are some NFD // cases too. we map ICU(10) to SG_ERR_UNMAPPABLE_UNICODE_CHAR SG_file__open__pathname(pCtx,pPathnameNewFile,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,0755,&pFile); #if defined(LINUX) bTest = ( (!SG_context__has_err(pCtx)) || (SG_context__err_equals(pCtx,SG_ERR_UNMAPPABLE_UNICODE_CHAR)) ); #else bTest = ( (!SG_context__has_err(pCtx)) ); #endif SG_context__err_reset(pCtx); VERIFYP_COND("u0020_utf8pathnames",bTest, ("Error Creating file [%s]",SG_pathname__sz(pPathnameNewFile))); VERIFY_ERR_CHECK_DISCARD( SG_file__close(pCtx, &pFile) ); SG_PATHNAME_NULLFREE(pCtx, pPathnameNewFile); SG_NULLFREE(pCtx, pBufUtf8); return 1; }
void MyFn(alloc__copy__deep)(SG_context * pCtx) { static const SG_uint32 uSize = 100u; SG_vector* pVector = NULL; SG_vector* pCopy = NULL; SG_uint32 uIndex = 0u; SG_uint32 uOutput1 = 0u; SG_uint32 uOutput2 = 0u; void* pOutput1 = NULL; void* pOutput2 = NULL; VERIFY_ERR_CHECK( SG_VECTOR__ALLOC(pCtx, &pVector, uSize) ); // add some allocated data to the vector for (uIndex = 0u; uIndex < uSize; ++uIndex) { SG_uint32* pValue = NULL; VERIFY_ERR_CHECK( SG_alloc1(pCtx, pValue) ); *pValue = uIndex; VERIFY_ERR_CHECK( SG_vector__append(pCtx, pVector, pValue, &uOutput1) ); VERIFY_COND("Added item has unexpected index.", uOutput1 == uIndex); } // copy the vector VERIFY_ERR_CHECK( SG_VECTOR__ALLOC__COPY(pCtx, pVector, MyFn(copy_uint32), MyFn(free_uint32), &pCopy) ); // verify that the copy matches the original VERIFY_ERR_CHECK( SG_vector__length(pCtx, pVector, &uOutput1) ); VERIFY_ERR_CHECK( SG_vector__length(pCtx, pCopy, &uOutput2) ); VERIFY_COND("Copied vector's length doesn't match added item count.", uOutput1 == uSize); VERIFY_COND("Copied vector's length doesn't match original.", uOutput1 == uOutput2); for (uIndex = 0u; uIndex < uOutput1; ++uIndex) { VERIFY_ERR_CHECK( SG_vector__get(pCtx, pVector, uIndex, &pOutput1) ); VERIFY_ERR_CHECK( SG_vector__get(pCtx, pCopy, uIndex, &pOutput2) ); VERIFYP_COND("Copied vector's pointer value matches original after deep copy.", pOutput1 != pOutput2, ("index(%d)", uIndex)); uOutput1 = *((SG_uint32*)pOutput1); uOutput2 = *((SG_uint32*)pOutput2); VERIFYP_COND("Copied vector's pointed-to value doesn't match original after deep copy.", uOutput1 == uOutput2, ("index(%d)", uIndex)); } fail: SG_context__push_level(pCtx); SG_vector__free__with_assoc(pCtx, pVector, MyFn(free_uint32)); SG_vector__free__with_assoc(pCtx, pCopy, MyFn(free_uint32)); SG_context__pop_level(pCtx); }
void MyFn(remove__value)(SG_context* pCtx) { SG_vector* pVector = NULL; SG_uint32 uSize = 0u; SG_uint32 uIndex = 0u; // create a test vector VERIFY_ERR_CHECK( MyFn(_create_test_vector)(pCtx, &pVector, &uSize) ); // run through each item and remove it by value // verify that we remove the number of values expected // also verify that the resulting size is as expected for (uIndex = 0u; uIndex < SG_NrElements(gaTestItems); ++uIndex) { test_item* pTestItem = gaTestItems + uIndex; SG_uint32 uRemoved = 0u; VERIFY_ERR_CHECK( SG_vector__remove__value(pCtx, pVector, (void*)pTestItem->szValue, &uRemoved, NULL) ); VERIFYP_COND("Removed wrong number of items.", uRemoved == pTestItem->uCount, ("Value(%s) Expected(%u) Removed(%u)", pTestItem->szValue, pTestItem->uCount, uRemoved)); uSize -= uRemoved; VERIFY_ERR_CHECK( MyFn(_verify_size)(pCtx, pVector, uSize) ); } fail: SG_VECTOR_NULLFREE(pCtx, pVector); return; }
void MyFn(_verify_size)( SG_context* pCtx, SG_vector* pVector, SG_uint32 uExpected ) { SG_uint32 uSize = 0u; VERIFY_ERR_CHECK( SG_vector__length(pCtx, pVector, &uSize) ); VERIFYP_COND("Incorrect size.", uSize == uExpected, ("Expected(%u) Actual(%u)", uExpected, uSize)); fail: return; }
int u0020_utf8pathnames__testfilename(SG_string * pStringFilename) { // verify that file name matches what we expect. // // WE RELY ON THE FACT THAT EACH FILENAME IN THE ARRAY STARTS // WITH A DIFFERENT LETTER. const char * szFilename = SG_string__sz(pStringFilename); char c = szFilename[0]; if (c == '.') // "." and ".." return 1; if ((c >= 'A') && (c <= 'Z')) { _tableitem * pti; size_t tableindex = (c - 'A'); SG_bool bTestIsNFC, bTestIsNFD; SG_bool bMatchGiven, bMatchNFC, bMatchNFD; VERIFYP_COND_RETURN("u0020_utf8pathnames",(tableindex < SG_NrElements(table)),("unexpected file [%s]",szFilename)); pti = &table[tableindex ]; // verify that we didn't mess up when creating the test case. bTestIsNFC = (strcmp((char *)pti->pa8,(char *)pti->paNfc) == 0); bTestIsNFD = (strcmp((char *)pti->pa8,(char *)pti->paNfd) == 0); VERIFYP_COND("u0020_utf8pathnames",(bTestIsNFC || bTestIsNFD),("Is tableitem[%c] NFC or NFD?",c)); // see if the filename we got from the system matches what we gave. // if not, see if it matches the NFC() version or the NFD() version. bMatchGiven = (strcmp(szFilename,(char *)pti->pa8) == 0); bMatchNFC = (strcmp(szFilename,(char *)pti->paNfc) == 0); bMatchNFD = (strcmp(szFilename,(char *)pti->paNfd) == 0); INFOP("u0020_utf8pathnames",("tableitem[%c] NFC[%d] [NFC %s NFD] : MatchGiven[%d] MatchNFC[%d] MatchNFD[%d]", c, bTestIsNFC,((bTestIsNFC == bTestIsNFD) ? "==" : "!="), bMatchGiven,bMatchNFC,bMatchNFD)); // // TODO fix this test based upon what we know about the platform. // VERIFYP_COND("u0020_utf8pathnames",(strcmp(szFilename,(char *)pti->pa8)==0),("Received [%s] expected [%s]",szFilename,pti->pa8)); return 1; } VERIFYP_COND_RETURN("u0020_utf8pathnames",(0),("unexpected file [%s]",szFilename)); }
void MyFn(alloc__copy__shallow)(SG_context * pCtx) { static const SG_uint32 uSize = 100u; SG_vector* pVector = NULL; SG_vector* pCopy = NULL; SG_uint32 uIndex = 0u; SG_uint32 uOutput1 = 0u; SG_uint32 uOutput2 = 0u; void* pOutput1 = NULL; void* pOutput2 = NULL; VERIFY_ERR_CHECK( SG_VECTOR__ALLOC(pCtx, &pVector, uSize) ); // add some random stack data to the vector for (uIndex = 0u; uIndex < uSize; ++uIndex) { VERIFY_ERR_CHECK( SG_vector__append(pCtx, pVector, &uIndex + uIndex, &uOutput1) ); VERIFY_COND("Added item has unexpected index.", uOutput1 == uIndex); } // copy the vector VERIFY_ERR_CHECK( SG_VECTOR__ALLOC__COPY(pCtx, pVector, NULL, NULL, &pCopy) ); // verify that the copy matches the original VERIFY_ERR_CHECK( SG_vector__length(pCtx, pVector, &uOutput1) ); VERIFY_ERR_CHECK( SG_vector__length(pCtx, pCopy, &uOutput2) ); VERIFY_COND("Copied vector's length doesn't match added item count.", uOutput1 == uSize); VERIFY_COND("Copied vector's length doesn't match original.", uOutput1 == uOutput2); for (uIndex = 0u; uIndex < uOutput1; ++uIndex) { VERIFY_ERR_CHECK( SG_vector__get(pCtx, pVector, uIndex, &pOutput1) ); VERIFY_ERR_CHECK( SG_vector__get(pCtx, pCopy, uIndex, &pOutput2) ); VERIFYP_COND("Copied vector's value doesn't match original.", pOutput1 == pOutput2, ("index(%d", uIndex)); } fail: SG_VECTOR_NULLFREE(pCtx, pVector); SG_VECTOR_NULLFREE(pCtx, pCopy); }
void MyFn(remove__if)(SG_context* pCtx) { static SG_uint32 uItemCount = 20u; static const char* szItemValue = "abc"; static SG_uint32 uStartDivisor = 5u; SG_vector* pVector = NULL; SG_uint32 uIndex = 0u; SG_uint32 uCount = uItemCount; SG_uint32 uDivisor = 0u; SG_uint32 uRemoved = 0u; // create a vector with test data VERIFY_ERR_CHECK( SG_VECTOR__ALLOC(pCtx, &pVector, 10u) ); for (uIndex = 0u; uIndex < uItemCount; ++uIndex) { VERIFY_ERR_CHECK( SG_vector__append(pCtx, pVector, (void*)szItemValue, NULL) ); } // run tests, removing every Nth, then every (N-1)th item, etc // the last iteration (every 1th item) will remove every remaining item for (uDivisor = uStartDivisor; uDivisor > 0u; --uDivisor) { SG_uint32 uExpected = uCount / uDivisor; VERIFY_ERR_CHECK( SG_vector__remove__if(pCtx, pVector, MyFn(remove__if__predicate), (void*)&uDivisor, &uRemoved, NULL) ); VERIFYP_COND("Wrong number of items removed.", uRemoved == uExpected, ("Removed(%u) Expected(%u)", uRemoved, uExpected)); uCount -= uExpected; } VERIFY_COND("Expected size should be zero.", uCount == 0u); // verify that the vector is empty VERIFY_ERR_CHECK( MyFn(_verify_size)(pCtx, pVector, 0u) ); fail: SG_VECTOR_NULLFREE(pCtx, pVector); return; }
void MyFn(_verify_offset_values)( SG_context* pCtx, SG_vector* pVector, SG_uint32 uBegin, SG_uint32 uEnd, SG_int32 iOffset ) { SG_uint32 uIndex = 0u; for (uIndex = uBegin; uIndex < uEnd; ++uIndex) { SG_uint32* pValue = NULL; SG_uint32 uExpected = uIndex + iOffset; VERIFY_ERR_CHECK( SG_vector__get(pCtx, pVector, uIndex, (void**)&pValue) ); VERIFYP_COND("Incorrect value.", *pValue == uExpected, ("Expected(%u) Actual (%u) Index(%u)", uExpected, *pValue, uIndex)); } fail: return; }
int u0020_utf8pathnames__readdir(SG_context * pCtx, const SG_pathname * pPathnameTmpDir) { // open the tmp dir for reading and read the filename of each file in it. // compare these with the version of the filename that we used to create // the file. // // WE RELY ON THE FACT THAT EACH FILENAME IN THE ARRAY STARTS // WITH A DIFFERENT LETTER. SG_error errRead; SG_dir * pDir; SG_string * pStringFilename = NULL; VERIFY_ERR_CHECK_DISCARD( SG_STRING__ALLOC(pCtx, &pStringFilename) ); // opendir gives us the first file automatically. VERIFY_ERR_CHECK_DISCARD( SG_dir__open(pCtx,pPathnameTmpDir,&pDir,&errRead,pStringFilename,NULL) ); VERIFYP_COND("u0020_utf8pathnames",(SG_IS_OK(errRead)),("Reading first file in directory.")); do { u0020_utf8pathnames__testfilename(pStringFilename); SG_dir__read(pCtx,pDir,pStringFilename,NULL); SG_context__get_err(pCtx,&errRead); } while (SG_IS_OK(errRead)); VERIFY_CTX_ERR_EQUALS("u0020_utf8pathnames",pCtx,SG_ERR_NOMOREFILES); SG_context__err_reset(pCtx); SG_DIR_NULLCLOSE(pCtx, pDir); SG_STRING_NULLFREE(pCtx, pStringFilename); return 1; }