static void uevent_msg(void) { k_u8 buf[8192];//presume 8kB is enough for one message u_memset(buf,0,sizeof(buf)); struct k_io_vec io_vec; io_vec.base=buf; io_vec.len=sizeof(buf); struct k_msg_hdr msg; u_memset(&msg,0,sizeof(msg)); msg.iov=&io_vec; msg.iov_len=1; k_l r; do r=sysc(recvmsg,3,s,&msg,0); while(r==-K_EINTR); if(K_ISERR(r)){ OUT("ERROR(%ld):unable to receive the uevent\n",r); sysc(exit_group,1,-1); } if(msg.flgs&K_MSG_TRUNC){ OUT("ERROR:the uevent was truncated(flags=0x%x)\n",msg.flgs); sysc(exit_group,1,-1); } uevent_process(&buf[0],(k_i)r); }
static void TestJitterbug1098(){ UChar rule[1000]; UCollator* c1 = NULL; UErrorCode status = U_ZERO_ERROR; UParseError parseError; char preContext[200]={0}; char postContext[200]={0}; int i=0; const char* rules[] = { "&''<\\\\", "&\\'<\\\\", "&\\\"<'\\'", "&'\"'<\\'", '\0' }; const UCollationResult results1098[] = { UCOL_LESS, UCOL_LESS, UCOL_LESS, UCOL_LESS, }; const UChar input[][2]= { {0x0027,0x005c}, {0x0027,0x005c}, {0x0022,0x005c}, {0x0022,0x0027}, }; UChar X[2] ={0}; UChar Y[2] ={0}; u_memset(parseError.preContext,0x0000,U_PARSE_CONTEXT_LEN); u_memset(parseError.postContext,0x0000,U_PARSE_CONTEXT_LEN); for(;rules[i]!=0;i++){ u_uastrcpy(rule, rules[i]); c1 = ucol_openRules(rule, u_strlen(rule), UCOL_OFF, UCOL_DEFAULT_STRENGTH, &parseError, &status); if(U_FAILURE(status)){ log_err("Could not parse the rules syntax. Error: %s ", u_errorName(status)); if (status == U_PARSE_ERROR) { u_UCharsToChars(parseError.preContext,preContext,20); u_UCharsToChars(parseError.postContext,postContext,20); log_verbose("\n\tPre-Context: %s \n\tPost-Context:%s \n",preContext,postContext); } return; } X[0] = input[i][0]; Y[0] = input[i][1]; doTest(c1,X,Y,results1098[i]); ucol_close(c1); } }
static int32_t u_sprintf_pad_and_justify(void *context, const u_printf_spec_info *info, const UChar *result, int32_t resultLen) { u_localized_print_string *output = (u_localized_print_string *)context; int32_t written = 0; int32_t lengthOfResult = resultLen; resultLen = ufmt_min(resultLen, output->available); /* pad and justify, if needed */ if(info->fWidth != -1 && resultLen < info->fWidth) { int32_t paddingLeft = info->fWidth - resultLen; int32_t outputPos = output->len - output->available; if (paddingLeft + resultLen > output->available) { paddingLeft = output->available - resultLen; if (paddingLeft < 0) { paddingLeft = 0; } /* paddingLeft = output->available - resultLen;*/ } written += paddingLeft; /* left justify */ if(info->fLeft) { written += u_sprintf_write(output, result, resultLen); u_memset(&output->str[outputPos + resultLen], info->fPadChar, paddingLeft); output->available -= paddingLeft; } /* right justify */ else { u_memset(&output->str[outputPos], info->fPadChar, paddingLeft); output->available -= paddingLeft; written += u_sprintf_write(output, result, resultLen); } } /* just write the formatted output */ else { written = u_sprintf_write(output, result, resultLen); } if (written >= 0 && lengthOfResult > written) { return lengthOfResult; } return written; }
void wl_display_req_sync(k_u32 callback_id) { k_u32 req[REQ_SYNC_DWS]; req[0]=WL_DISPLAY_ID; req[1]=((REQ_SYNC_DWS*sizeof(k_u32))<<16)|WL_DISPLAY_SYNC; req[2]=callback_id; struct k_io_vec iov; iov.base=&req; iov.len=sizeof(req); struct k_msg_hdr msg; u_memset(&msg,0,sizeof(msg)); msg.iov=&iov; msg.iov_len=1; k_l r; do r=sysc(sendmsg,3,srv_so,&msg,0);while(r==-K_EINTR); if(K_ISERR(r)){ PERR("FATAL(%d):unable to send the sync request\n",r); sysc(exit_group,1,-1); } if(!r) sysc(exit_group,1,0);//server is gone }
/* *### TODO: Add more invalid rules to test all different scenarios. * */ static void TestInvalidRules(){ #define MAX_ERROR_STATES 2 static const char* rulesArr[MAX_ERROR_STATES] = { "& C < ch, cH, Ch[this should fail]<d", "& C < ch, cH, & Ch[variable top]" }; static const char* preContextArr[MAX_ERROR_STATES] = { " C < ch, cH, Ch", "& C < ch, cH", }; static const char* postContextArr[MAX_ERROR_STATES] = { "[this should fa", ", & Ch[variable" }; int i; for(i = 0;i<MAX_ERROR_STATES;i++){ UChar rules[1000] = { '\0' }; UChar preContextExp[1000] = { '\0' }; UChar postContextExp[1000] = { '\0' }; UParseError parseError; UErrorCode status = U_ZERO_ERROR; UCollator* coll=0; u_charsToUChars(rulesArr[i],rules,uprv_strlen(rulesArr[i])+1); u_charsToUChars(preContextArr[i],preContextExp,uprv_strlen(preContextArr[i])+1); u_charsToUChars(postContextArr[i],postContextExp,uprv_strlen(postContextArr[i])+1); /* clean up stuff in parseError */ u_memset(parseError.preContext,0x0000,U_PARSE_CONTEXT_LEN); u_memset(parseError.postContext,0x0000,U_PARSE_CONTEXT_LEN); /* open the rules and test */ coll = ucol_openRules(rules,u_strlen(rules),UCOL_OFF,UCOL_DEFAULT_STRENGTH,&parseError,&status); (void)coll; /* Suppress set but not used warning. */ if(u_strcmp(parseError.preContext,preContextExp)!=0){ log_err_status(status, "preContext in UParseError for ucol_openRules does not match: \"%s\"\n", aescstrdup(parseError.preContext, -1)); } if(u_strcmp(parseError.postContext,postContextExp)!=0){ log_err_status(status, "postContext in UParseError for ucol_openRules does not match: \"%s\"\n", aescstrdup(parseError.postContext, -1)); } } }
void wl_shm_req_create_pool(k_u32 shm,k_u32 shm_pool,k_i fd,k_u32 sz) { k_u32 req[REQ_PAYLOAD_CREATE_POOL_DWS]; req[0]=shm; req[1]=(REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32))<<16|WL_SHM_CREATE_POOL; req[2]=shm_pool; req[3]=sz; struct k_io_vec iov; iov.base=&req; iov.len=REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32); struct k_msg_hdr msg; k_u8 cmsg_buf[K_CMSG_SPACE(sizeof(fd))]; u_memset(&msg,0,sizeof(msg)); u_memset(cmsg_buf,0,sizeof(cmsg_buf)); msg.ctl=cmsg_buf; msg.ctl_len=sizeof(cmsg_buf); struct k_cmsg_hdr *cmsg=K_CMSG_FIRSTHDR(&msg); cmsg->lvl=K_SOL_SOCKET; cmsg->type=K_SCM_RIGHTS; cmsg->len=K_CMSG_LEN(sizeof(fd)); msg.iov=&iov; msg.iov_len=1; *((k_i*)(K_CMSG_DATA(K_CMSG_FIRSTHDR(&msg))))=fd; k_l r; do r=sysc(sendmsg,3,srv_so,&msg,0);while(r==-K_EINTR); if(K_ISERR(r)){ PERR("FATAL(%ld):unable to send the shm create_pool request\n",r); sysc(exit_group,1,-1); } if(r!=REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32)){ PERR("FATAL:shm::create_pool request only %ld/%ld was sent\n",r, REQ_PAYLOAD_CREATE_POOL_DWS*sizeof(k_u32)); sysc(exit_group,1,-1); } if(!r) sysc(exit_group,1,0);//server is gone }
void uevents_setup(void) { OUTC(PRE "setting up uevent..."); ep_fd=(k_i)sysc(epoll_create1,1,0); if(K_ISERR(ep_fd)){ OUT("ERROR(%d):unable to create epoll fd\n",ep_fd); sysc(exit_group,1,-1); } //---------------------------------------------------------------------------- //blocking socket s=(k_i)sysc(socket,3,K_PF_NETLINK,K_SOCK_RAW, K_NETLINK_KOBJECT_UEVENT); if(K_ISERR(s)){ OUT("ERROR(%d):unable to create uevent netlink socket\n",s); sysc(exit_group,1,-1); } //---------------------------------------------------------------------------- k_i recv_buf_sz=128*1024;//128k for kernel buffering k_l r=sysc(setsockopt,5,s,K_SOL_SOCKET,K_SO_RCVBUFFORCE,&recv_buf_sz, sizeof(recv_buf_sz)); if(K_ISERR(r)){ OUT("ERROR(%ld):unable to force the size of the socket buffer\n",r); sysc(exit_group,1,-1); } //---------------------------------------------------------------------------- //uevent groups-->only one: 1 struct k_sockaddr_nl addr={K_AF_NETLINK,0,0,1}; r=sysc(bind,3,s,&addr,sizeof(addr)); if(K_ISERR(r)){ OUT("ERROR(%ld):unable to bind address to uevent netlink socket\n",r); sysc(exit_group,1,-1); } //---------------------------------------------------------------------------- struct k_epoll_event ep_evt; u_memset(&ep_evt,0,sizeof(ep_evt)); ep_evt.events=K_EPOLLIN; ep_evt.data.fd=s; r=sysc(epoll_ctl,4,ep_fd,K_EPOLL_CTL_ADD,s,&ep_evt); if(K_ISERR(r)){ OUT("ERROR(%ld):unable to register uevent netlink socket to epoll\n",r); sysc(exit_group,1,-1); } OUTC("done\n"); }
static void TestBreakIteratorRefresh(void) { /* * RefreshInput changes out the input of a Break Iterator without * changing anything else in the iterator's state. Used with Java JNI, * when Java moves the underlying string storage. This test * runs a ubrk_next() repeatedly, moving the text in the middle of the sequence. * The right set of boundaries should still be found. */ UChar testStr[] = {0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, 0x44, 0x0}; /* = " A B C D" */ UChar movedStr[] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0}; UErrorCode status = U_ZERO_ERROR; UBreakIterator *bi; UText ut1 = UTEXT_INITIALIZER; UText ut2 = UTEXT_INITIALIZER; bi = ubrk_open(UBRK_LINE, "en_US", NULL, 0, &status); TEST_ASSERT_SUCCESS(status); if (U_FAILURE(status)) { return; } utext_openUChars(&ut1, testStr, -1, &status); TEST_ASSERT_SUCCESS(status); ubrk_setUText(bi, &ut1, &status); TEST_ASSERT_SUCCESS(status); if (U_SUCCESS(status)) { /* Line boundaries will occur before each letter in the original string */ TEST_ASSERT(1 == ubrk_next(bi)); TEST_ASSERT(3 == ubrk_next(bi)); /* Move the string, kill the original string. */ u_strcpy(movedStr, testStr); u_memset(testStr, 0x20, u_strlen(testStr)); utext_openUChars(&ut2, movedStr, -1, &status); TEST_ASSERT_SUCCESS(status); ubrk_refreshUText(bi, &ut2, &status); TEST_ASSERT_SUCCESS(status); /* Find the following matches, now working in the moved string. */ TEST_ASSERT(5 == ubrk_next(bi)); TEST_ASSERT(7 == ubrk_next(bi)); TEST_ASSERT(8 == ubrk_next(bi)); TEST_ASSERT(UBRK_DONE == ubrk_next(bi)); TEST_ASSERT_SUCCESS(status); utext_close(&ut1); utext_close(&ut2); } ubrk_close(bi); }
void RBBIAPITest::TestRefreshInputText() { /* * RefreshInput changes out the input of a Break Iterator without * changing anything else in the iterator's state. Used with Java JNI, * when Java moves the underlying string storage. This test * runs BreakIterator::next() repeatedly, moving the text in the middle of the sequence. * The right set of boundaries should still be found. */ UChar testStr[] = {0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, 0x44, 0x0}; /* = " A B C D" */ UChar movedStr[] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0}; UErrorCode status = U_ZERO_ERROR; UText ut1 = UTEXT_INITIALIZER; UText ut2 = UTEXT_INITIALIZER; RuleBasedBreakIterator *bi = (RuleBasedBreakIterator *)BreakIterator::createLineInstance(Locale::getEnglish(), status); TEST_ASSERT_SUCCESS(status); utext_openUChars(&ut1, testStr, -1, &status); TEST_ASSERT_SUCCESS(status); if (U_SUCCESS(status)) { bi->setText(&ut1, status); TEST_ASSERT_SUCCESS(status); /* Line boundaries will occur before each letter in the original string */ TEST_ASSERT(1 == bi->next()); TEST_ASSERT(3 == bi->next()); /* Move the string, kill the original string. */ u_strcpy(movedStr, testStr); u_memset(testStr, 0x20, u_strlen(testStr)); utext_openUChars(&ut2, movedStr, -1, &status); TEST_ASSERT_SUCCESS(status); RuleBasedBreakIterator *returnedBI = &bi->refreshInputText(&ut2, status); TEST_ASSERT_SUCCESS(status); TEST_ASSERT(bi == returnedBI); /* Find the following matches, now working in the moved string. */ TEST_ASSERT(5 == bi->next()); TEST_ASSERT(7 == bi->next()); TEST_ASSERT(8 == bi->next()); TEST_ASSERT(UBRK_DONE == bi->next()); utext_close(&ut1); utext_close(&ut2); } delete bi; }
void pelet::UCharBufferedFileClass::GrowBuffer(int minCapacity) { int newCapacity = minCapacity < (2 * BufferCapacity) ? (2 * BufferCapacity) : minCapacity; UChar* newBuffer = new UChar[newCapacity]; u_memcpy(newBuffer, Buffer, BufferCapacity); u_memset(newBuffer + BufferCapacity, 'i', newCapacity / 2); // change all of the pointers TokenStart = newBuffer + (TokenStart - Buffer); Current = newBuffer + (Current - Buffer); // leave Limit at the place where the last good character is located Limit = newBuffer + (Limit - Buffer); Marker = newBuffer + (Marker - Buffer); delete[] Buffer; Buffer = newBuffer; BufferCapacity = newCapacity; }
static void addUnfolding(UChar32 c, const UChar *s, int32_t length) { int32_t i; if(length>UGENCASE_UNFOLD_STRING_WIDTH) { fprintf(stderr, "gencase error: case folding too long (length=%ld>%d=UGENCASE_UNFOLD_STRING_WIDTH)\n", (long)length, UGENCASE_UNFOLD_STRING_WIDTH); exit(U_INTERNAL_PROGRAM_ERROR); } if(unfoldTop >= (LENGTHOF(unfold) - UGENCASE_UNFOLD_STRING_WIDTH)) { fprintf(stderr, "gencase error: too many multi-character case foldings\n"); exit(U_BUFFER_OVERFLOW_ERROR); } u_memset(unfold+unfoldTop, 0, UGENCASE_UNFOLD_WIDTH); u_memcpy(unfold+unfoldTop, s, length); i=unfoldTop+UGENCASE_UNFOLD_STRING_WIDTH; U16_APPEND_UNSAFE(unfold, i, c); ++unfoldRows; unfoldTop+=UGENCASE_UNFOLD_WIDTH; }
void uevents_process(void) { OUTC(PRE "processing uevents...\n"); while(1){ k_l r; static struct k_epoll_event evts;//uevent netlink event do{ u_memset(&evts,0,sizeof(evts)); r=sysc(epoll_wait,4,ep_fd,&evts,1,UEVENTS_TIMEOUT); }while(r==-K_EINTR); if(K_ISERR(r)){ OUT(PRE "ERROR(%ld):error epolling uevent netlink socket\n",r); sysc(exit_group,1,-1); } if(!r) break;//assume no more uevents if(evts.events&K_EPOLLIN) uevent_msg(); else{ OUT(PRE "ERROR:unmanaged epolling event on uevent netlink socket" "(events=%u)\n",evts.events); sysc(exit_group,1,-1); } } OUTC(PRE "uevents processed\n"); }
U_CDECL_END U_CDECL_BEGIN static void U_CALLCONV DataDrivenPrintfPrecision(void) { #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO UErrorCode errorCode; TestDataModule *dataModule; TestData *testData; const DataMap *testCase; DataDrivenLogger logger; UChar uBuffer[512]; char cBuffer[512]; char cFormat[sizeof(cBuffer)]; char cExpected[sizeof(cBuffer)]; UnicodeString tempStr; UChar format[512]; UChar expectedResult[512]; UChar argument[512]; int32_t precision; int32_t i; int8_t i8; int16_t i16; int32_t i32; int64_t i64; double dbl; int32_t uBufferLenReturned; errorCode=U_ZERO_ERROR; dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode); if(U_SUCCESS(errorCode)) { testData=dataModule->createTestData("printfPrecision", errorCode); if(U_SUCCESS(errorCode)) { for(i=0; testData->nextCase(testCase, errorCode); ++i) { if(U_FAILURE(errorCode)) { log_err("error retrieving icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } u_memset(uBuffer, 0x2A, UPRV_LENGTHOF(uBuffer)); uBuffer[UPRV_LENGTHOF(uBuffer)-1] = 0; tempStr=testCase->getString("format", errorCode); tempStr.extract(format, UPRV_LENGTHOF(format), errorCode); tempStr=testCase->getString("result", errorCode); tempStr.extract(expectedResult, UPRV_LENGTHOF(expectedResult), errorCode); tempStr=testCase->getString("argument", errorCode); tempStr.extract(argument, UPRV_LENGTHOF(argument), errorCode); precision=testCase->getInt28("precision", errorCode); u_austrncpy(cBuffer, format, sizeof(cBuffer)); if(U_FAILURE(errorCode)) { log_err("error retrieving icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } log_verbose("Test %d: format=\"%s\"\n", i, cBuffer); switch (testCase->getString("argumentType", errorCode)[0]) { case 0x64: // 'd' double dbl = atof(u_austrcpy(cBuffer, argument)); uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, dbl); break; case 0x31: // '1' int8_t i8 = (int8_t)uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i8); break; case 0x32: // '2' int16_t i16 = (int16_t)uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i16); break; case 0x34: // '4' int32_t i32 = (int32_t)uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i32); break; case 0x38: // '8' int64_t i64 = uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i64); break; case 0x73: // 's' char * u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, cBuffer); break; case 0x53: // 'S' UChar * uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, argument); break; default: uBufferLenReturned = 0; log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i); } if (u_strcmp(uBuffer, expectedResult) != 0) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); u_austrncpy(cFormat, format, sizeof(cFormat)); u_austrncpy(cExpected, expectedResult, sizeof(cExpected)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n", i, cFormat, cBuffer, cExpected); } if (uBufferLenReturned <= 0) { log_err("FAILURE test case %d - \"%s\" is an empty string.\n", i, cBuffer); } else if (uBuffer[uBufferLenReturned-1] == 0 || uBuffer[uBufferLenReturned] != 0 || uBuffer[uBufferLenReturned+1] != 0x2A || uBuffer[uBufferLenReturned+2] != 0x2A) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n", i, cBuffer, uBufferLenReturned); } if(U_FAILURE(errorCode)) { log_err("error running icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } } delete testData; } delete dataModule; } else { log_data_err("Failed: could not load test icuio data\n"); } #endif }
U_CDECL_END U_CDECL_BEGIN static void U_CALLCONV DataDrivenScanf(void) { #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO UErrorCode errorCode; TestDataModule *dataModule; TestData *testData; const DataMap *testCase; DataDrivenLogger logger; UChar uBuffer[512]; char cBuffer[512]; char cExpected[sizeof(cBuffer)]; UnicodeString tempStr; UChar format[512]; UChar expectedResult[512]; UChar argument[512]; int32_t i; int8_t i8, expected8; int16_t i16, expected16; int32_t i32, expected32; int64_t i64, expected64; double dbl, expectedDbl; volatile float flt, expectedFlt; // Use volatile in order to get around an Intel compiler issue. int32_t uBufferLenReturned; //const char *fileLocale = "en_US_POSIX"; //int32_t uFileBufferLenReturned; //UFILE *testFile; errorCode=U_ZERO_ERROR; dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode); if(U_SUCCESS(errorCode)) { testData=dataModule->createTestData("scanf", errorCode); if(U_SUCCESS(errorCode)) { for(i=0; testData->nextCase(testCase, errorCode); ++i) { if(U_FAILURE(errorCode)) { log_err("error retrieving icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8"); if (!testFile) { log_err("Can't open test file - %s\n", STANDARD_TEST_FILE); }*/ u_memset(uBuffer, 0x2A, UPRV_LENGTHOF(uBuffer)); uBuffer[UPRV_LENGTHOF(uBuffer)-1] = 0; tempStr=testCase->getString("format", errorCode); tempStr.extract(format, UPRV_LENGTHOF(format), errorCode); tempStr=testCase->getString("result", errorCode); tempStr.extract(expectedResult, UPRV_LENGTHOF(expectedResult), errorCode); tempStr=testCase->getString("argument", errorCode); tempStr.extract(argument, UPRV_LENGTHOF(argument), errorCode); u_austrncpy(cBuffer, format, sizeof(cBuffer)); if(U_FAILURE(errorCode)) { log_err("error retrieving icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } log_verbose("Test %d: format=\"%s\"\n", i, cBuffer); switch (testCase->getString("argumentType", errorCode)[0]) { case 0x64: // 'd' double expectedDbl = atof(u_austrcpy(cBuffer, expectedResult)); uBufferLenReturned = u_sscanf_u(argument, format, &dbl); //uFileBufferLenReturned = u_fscanf_u(testFile, format, dbl); if (dbl != expectedDbl) { log_err("error in scanf test case[%d] Got: %f Exp: %f\n", i, dbl, expectedDbl); } break; case 0x66: // 'f' float expectedFlt = (float)atof(u_austrcpy(cBuffer, expectedResult)); uBufferLenReturned = u_sscanf_u(argument, format, &flt); //uFileBufferLenReturned = u_fscanf_u(testFile, format, flt); if (flt != expectedFlt) { log_err("error in scanf test case[%d] Got: %f Exp: %f\n", i, flt, expectedFlt); } break; case 0x31: // '1' int8_t expected8 = (int8_t)uto64(expectedResult); uBufferLenReturned = u_sscanf_u(argument, format, &i8); //uFileBufferLenReturned = u_fscanf_u(testFile, format, i8); if (i8 != expected8) { log_err("error in scanf test case[%d] Got: %02X Exp: %02X\n", i, i8, expected8); } break; case 0x32: // '2' int16_t expected16 = (int16_t)uto64(expectedResult); uBufferLenReturned = u_sscanf_u(argument, format, &i16); //uFileBufferLenReturned = u_fscanf_u(testFile, format, i16); if (i16 != expected16) { log_err("error in scanf test case[%d] Got: %04X Exp: %04X\n", i, i16, expected16); } break; case 0x34: // '4' int32_t expected32 = (int32_t)uto64(expectedResult); uBufferLenReturned = u_sscanf_u(argument, format, &i32); //uFileBufferLenReturned = u_fscanf_u(testFile, format, i32); if (i32 != expected32) { log_err("error in scanf test case[%d] Got: %08X Exp: %08X\n", i, i32, expected32); } break; case 0x38: // '8' int64_t expected64 = uto64(expectedResult); uBufferLenReturned = u_sscanf_u(argument, format, &i64); //uFileBufferLenReturned = u_fscanf_u(testFile, format, i64); if (i64 != expected64) { log_err("error in scanf 64-bit. Test case = %d\n", i); } break; case 0x73: // 's' char * u_austrcpy(cExpected, expectedResult); uBufferLenReturned = u_sscanf_u(argument, format, cBuffer); //uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer); if (strcmp(cBuffer, cExpected) != 0) { log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer, cExpected, i); } break; case 0x53: // 'S' UChar * uBufferLenReturned = u_sscanf_u(argument, format, uBuffer); //uFileBufferLenReturned = u_fscanf_u(testFile, format, argument); if (u_strcmp(uBuffer, expectedResult) != 0) { u_austrcpy(cExpected, format); u_austrcpy(cBuffer, uBuffer); log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected, cBuffer, i); } break; default: uBufferLenReturned = 0; //uFileBufferLenReturned = 0; log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i); } if (uBufferLenReturned != 1) { log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned, i); } /* if (u_strcmp(uBuffer, expectedResult) != 0) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); u_austrncpy(cFormat, format, sizeof(cFormat)); u_austrncpy(cExpected, expectedResult, sizeof(cExpected)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n", i, cFormat, cBuffer, cExpected); } if (uBuffer[uBufferLenReturned-1] == 0 || uBuffer[uBufferLenReturned] != 0 || uBuffer[uBufferLenReturned+1] != 0x2A || uBuffer[uBufferLenReturned+2] != 0x2A) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n", i, cBuffer, uBufferLenReturned); }*/ /* u_fclose(testFile); testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8"); if (!testFile) { log_err("Can't open test file - %s\n", STANDARD_TEST_FILE); } uBuffer[0]; u_fgets(uBuffer, UPRV_LENGTHOF(uBuffer), testFile); if (u_strcmp(uBuffer, expectedResult) != 0) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); u_austrncpy(cFormat, format, sizeof(cFormat)); u_austrncpy(cExpected, expectedResult, sizeof(cExpected)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n", i, cFormat, cBuffer, cExpected); } if (uFileBufferLenReturned != uBufferLenReturned) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n", uFileBufferLenReturned, uBufferLenReturned); } */ if(U_FAILURE(errorCode)) { log_err("error running icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } // u_fclose(testFile); } delete testData; } delete dataModule; } else { log_data_err("Failed: could not load test icuio data\n"); } #endif }
U_CDECL_BEGIN static void U_CALLCONV DataDrivenPrintf(void) { #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO UErrorCode errorCode; TestDataModule *dataModule; TestData *testData; const DataMap *testCase; DataDrivenLogger logger; UChar uBuffer[512]; char cBuffer[512]; char cFormat[sizeof(cBuffer)]; char cExpected[sizeof(cBuffer)]; UnicodeString tempStr; UChar format[512]; UChar expectedResult[512]; UChar argument[512]; int32_t i; int8_t i8; int16_t i16; int32_t i32; int64_t i64; double dbl; int32_t uBufferLenReturned; const char *fileLocale = "en_US_POSIX"; int32_t uFileBufferLenReturned; LocalUFILEPointer testFile; errorCode=U_ZERO_ERROR; dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode); if(U_SUCCESS(errorCode)) { testData=dataModule->createTestData("printf", errorCode); if(U_SUCCESS(errorCode)) { for(i=0; testData->nextCase(testCase, errorCode); ++i) { if(U_FAILURE(errorCode)) { log_err("error retrieving icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8")); if (testFile.isNull()) { log_err("Can't open test file - %s\n", STANDARD_TEST_FILE); continue; } u_memset(uBuffer, 0x2A, sizeof(uBuffer)/sizeof(uBuffer[0])); uBuffer[sizeof(uBuffer)/sizeof(uBuffer[0])-1] = 0; tempStr=testCase->getString("format", errorCode); tempStr.extract(format, sizeof(format)/sizeof(format[0]), errorCode); tempStr=testCase->getString("result", errorCode); tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(expectedResult[0]), errorCode); tempStr=testCase->getString("argument", errorCode); tempStr.extract(argument, sizeof(argument)/sizeof(argument[0]), errorCode); u_austrncpy(cBuffer, format, sizeof(cBuffer)); if(U_FAILURE(errorCode)) { log_err("error retrieving icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } log_verbose("Test %d: format=\"%s\"\n", i, cBuffer); switch (testCase->getString("argumentType", errorCode)[0]) { case 0x64: // 'd' double dbl = atof(u_austrcpy(cBuffer, argument)); uBufferLenReturned = u_sprintf_u(uBuffer, format, dbl); uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, dbl); break; case 0x31: // '1' int8_t i8 = (int8_t)uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, i8); uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i8); break; case 0x32: // '2' int16_t i16 = (int16_t)uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, i16); uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i16); break; case 0x34: // '4' int32_t i32 = (int32_t)uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, i32); uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i32); break; case 0x38: // '8' int64_t i64 = uto64(argument); uBufferLenReturned = u_sprintf_u(uBuffer, format, i64); uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i64); break; case 0x73: // 's' char * u_austrncpy(cBuffer, argument, sizeof(cBuffer)); uBufferLenReturned = u_sprintf_u(uBuffer, format, cBuffer); uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, cBuffer); break; case 0x53: // 'S' UChar * uBufferLenReturned = u_sprintf_u(uBuffer, format, argument); uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, argument); break; default: uBufferLenReturned = 0; uFileBufferLenReturned = 0; log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i); } if (u_strcmp(uBuffer, expectedResult) != 0) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); u_austrncpy(cFormat, format, sizeof(cFormat)); u_austrncpy(cExpected, expectedResult, sizeof(cExpected)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n", i, cFormat, cBuffer, cExpected); } if (uBufferLenReturned <= 0) { log_err("FAILURE test case %d - \"%s\" is an empty string.\n", i, cBuffer); } else if (uBuffer[uBufferLenReturned-1] == 0 || uBuffer[uBufferLenReturned] != 0 || uBuffer[uBufferLenReturned+1] != 0x2A || uBuffer[uBufferLenReturned+2] != 0x2A) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n", i, cBuffer, uBufferLenReturned); } testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8")); if (testFile.isNull()) { log_err("Can't open test file - %s\n", STANDARD_TEST_FILE); } uBuffer[0]=0; u_fgets(uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]), testFile.getAlias()); if (u_strcmp(uBuffer, expectedResult) != 0) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); u_austrncpy(cFormat, format, sizeof(cFormat)); u_austrncpy(cExpected, expectedResult, sizeof(cExpected)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n", i, cFormat, cBuffer, cExpected); } if (uFileBufferLenReturned != uBufferLenReturned) { u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer)); cBuffer[sizeof(cBuffer)-1] = 0; log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n", uFileBufferLenReturned, uBufferLenReturned); } if(U_FAILURE(errorCode)) { log_err("error running icuio/printf test case %d - %s\n", i, u_errorName(errorCode)); errorCode=U_ZERO_ERROR; continue; } } delete testData; } delete dataModule; } else { log_data_err("Failed: could not load test icuio data\n"); } #endif }
static jobjectArray getContentImpl(JNIEnv* env, jclass clazz, jstring locale, jboolean needsTZ) { UErrorCode status = U_ZERO_ERROR; const char *loc = env->GetStringUTFChars(locale, NULL); UResourceBundle *root = ures_openU(NULL, loc, &status); env->ReleaseStringUTFChars(locale, loc); if(U_FAILURE(status)) { LOGI("Error getting resources"); status = U_ZERO_ERROR; return NULL; } jclass obj_class = env->FindClass("java/lang/Object"); jclass integer_class = env->FindClass("java/lang/Integer"); jmethodID integerInit = env->GetMethodID(integer_class, "<init>", "(I)V"); jobjectArray result; jobject firstDayOfWeek = NULL; jobject minimalDaysInFirstWeek = NULL; jobjectArray amPmMarkers = NULL; jobjectArray eras = NULL; jstring localPatternChars = NULL; jobjectArray weekdays = NULL; jobjectArray shortWeekdays = NULL; jobjectArray months = NULL; jobjectArray shortMonths = NULL; jstring time_SHORT = NULL; jstring time_MEDIUM = NULL; jstring time_LONG = NULL; jstring time_FULL = NULL; jstring date_SHORT = NULL; jstring date_MEDIUM = NULL; jstring date_LONG = NULL; jstring date_FULL = NULL; jstring decimalPatternChars = NULL; jstring naN = NULL; jstring infinity = NULL; jstring currencySymbol = NULL; jstring intCurrencySymbol = NULL; jstring numberPattern = NULL; jstring integerPattern = NULL; jstring currencyPattern = NULL; jstring percentPattern = NULL; jobjectArray zones = NULL; int counter = 0; int firstDayVals[2] = {-1, -1}; const jchar* nan = (const jchar *)NULL; const jchar* inf = (const jchar *)NULL; int nanL, infL; UResourceBundle *gregorian; UResourceBundle *gregorianElems; UResourceBundle *rootElems; // get the resources needed rootElems = ures_getByKey(root, "calendar", NULL, &status); if(U_FAILURE(status)) { return NULL; } gregorian = ures_getByKey(rootElems, "gregorian", NULL, &status); if(U_FAILURE(status)) { ures_close(rootElems); return NULL; } // adding the first day of week and minimal days in first week values getDayInitVector(env, gregorian, firstDayVals); if((firstDayVals[0] != -1) && (firstDayVals[1] != -1)) { firstDayOfWeek = env->NewObject(integer_class, integerInit, firstDayVals[0]); minimalDaysInFirstWeek = env->NewObject(integer_class, integerInit, firstDayVals[1]); // adding First_Day and Minimal_Days integer to the result counter += 2; } // adding ampm string array to the result"); amPmMarkers = getAmPmMarkers(env, gregorian); if(amPmMarkers != NULL) { counter++; } // adding eras string array to the result eras = getEras(env, gregorian); if(eras != NULL) { counter++; } // local pattern chars are initially always the same localPatternChars = env->NewStringUTF("GyMdkHmsSEDFwWahKzZ"); // adding local pattern chars string to the result counter++; // adding month names string array to the result months = getMonthNames(env, gregorian); if(months != NULL) { counter++; } // adding short month names string array to the result shortMonths = getShortMonthNames(env, gregorian); if(shortMonths != NULL) { counter++; } // adding day names string array to the result weekdays = getWeekdayNames(env, gregorian); if(weekdays != NULL) { counter++; } // adding short day names string array to the result shortWeekdays = getShortWeekdayNames(env, gregorian); if(shortWeekdays != NULL) { counter++; } const UChar *pattern; jchar check[2] = {0, 0}; u_uastrcpy(check, "v"); jchar replacement[2] = {0, 0}; u_uastrcpy(replacement, "z"); jchar *pos; jchar *patternCopy; int patternLength; // adding date and time format patterns to the result gregorianElems = ures_getByKey(gregorian, "DateTimePatterns", NULL, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } pattern = ures_getStringByIndex(gregorianElems, 0, &patternLength, &status); // there are some patterns in icu that use the pattern character 'v' // java doesn't accept this, so it gets replaced by 'z' which has // about the same result as 'v', the timezone name. // 'v' -> "PT", 'z' -> "PST", v is the generic timezone and z the standard tz // "vvvv" -> "Pacific Time", "zzzz" -> "Pacific Standard Time" patternCopy = (jchar *) malloc((patternLength + 1) * sizeof(jchar)); u_strcpy(patternCopy, pattern); if(U_FAILURE(status)) { free(patternCopy); status = U_ZERO_ERROR; goto endOfCalendar; } while((pos = u_strchr(patternCopy, check[0])) != NULL) { u_memset(pos, replacement[0], 1); } time_FULL = env->NewString(patternCopy, patternLength); free(patternCopy); counter++; pattern = ures_getStringByIndex(gregorianElems, 1, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } time_LONG = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 2, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } time_MEDIUM = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 3, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } time_SHORT = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 4, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_FULL = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 5, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_LONG = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 6, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_MEDIUM = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 7, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_SHORT = env->NewString(pattern, patternLength); counter++; endOfCalendar: if(gregorianElems != NULL) { ures_close(gregorianElems); } ures_close(gregorian); ures_close(rootElems); rootElems = ures_getByKey(root, "NumberElements", NULL, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; } if(ures_getSize(rootElems) >= 11) { // adding decimal pattern chars to the result decimalPatternChars = getDecimalPatternChars(env, rootElems); if(decimalPatternChars != NULL) { counter++; } // adding NaN pattern char to the result nan = ures_getStringByIndex(rootElems, 10, &nanL, &status); if(U_SUCCESS(status)) { naN = env->NewString(nan, nanL); counter++; } status = U_ZERO_ERROR; // adding infinity pattern char to the result inf = ures_getStringByIndex(rootElems, 9, &infL, &status); if(U_SUCCESS(status)) { infinity = env->NewString(inf, infL); counter++; } status = U_ZERO_ERROR; } ures_close(rootElems); // adding intl currency code to result intCurrencySymbol = getIntCurrencyCode(env, clazz, locale); if(intCurrencySymbol != NULL) { // adding currency symbol to result currencySymbol = getCurrencySymbol(env, clazz, locale, intCurrencySymbol); } else { intCurrencySymbol = env->NewStringUTF("XXX"); } if(currencySymbol == NULL) { currencySymbol = env->NewStringUTF("\u00a4"); } counter += 2; // adding number format patterns to the result int numOfEntries; int decSepOffset; NumberFormat *nf; jchar *tmpPattern; rootElems = ures_getByKey(root, "NumberPatterns", NULL, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto zones; } numOfEntries = ures_getSize(rootElems); if(numOfEntries < 3) { ures_close(rootElems); goto zones; } // number pattern pattern = ures_getStringByIndex(rootElems, 0, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; ures_close(rootElems); goto zones; } numberPattern = env->NewString(pattern, patternLength); counter++; // integer pattern derived from number pattern decSepOffset = u_strcspn(pattern, (jchar *)".\0"); tmpPattern = (jchar *) malloc((decSepOffset + 1) * sizeof(jchar)); u_strncpy(tmpPattern, pattern, decSepOffset); integerPattern = env->NewString(tmpPattern, decSepOffset); free(tmpPattern); counter++; // currency pattern pattern = ures_getStringByIndex(rootElems, 1, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; ures_close(rootElems); goto zones; } currencyPattern = env->NewString(pattern, patternLength); counter++; // percent pattern pattern = ures_getStringByIndex(rootElems, 2, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; ures_close(rootElems); goto zones; } percentPattern = env->NewString(pattern, patternLength); counter++; ures_close(rootElems); zones: ures_close(root); if(needsTZ == JNI_TRUE) { counter++; //add empty timezone } // collect all content and put it into an array result = env->NewObjectArray(counter, obj_class, NULL); int index = 0; if(needsTZ == JNI_TRUE) { addObject(env, result, "timezones", NULL, index++); } if(firstDayOfWeek != NULL && index < counter) { addObject(env, result, "First_Day", firstDayOfWeek, index++); } if(minimalDaysInFirstWeek != NULL && index < counter) { addObject(env, result, "Minimal_Days", minimalDaysInFirstWeek, index++); } if(amPmMarkers != NULL && index < counter) { addObject(env, result, "ampm", amPmMarkers, index++); } if(eras != NULL && index < counter) { addObject(env, result, "eras", eras, index++); } if(localPatternChars != NULL && index < counter) { addObject(env, result, "LocalPatternChars", localPatternChars, index++); } if(weekdays != NULL && index < counter) { addObject(env, result, "weekdays", weekdays, index++); } if(shortWeekdays != NULL && index < counter) { addObject(env, result, "shortWeekdays", shortWeekdays, index++); } if(months != NULL && index < counter) { addObject(env, result, "months", months, index++); } if(shortMonths != NULL && index < counter) { addObject(env, result, "shortMonths", shortMonths, index++); } if(time_SHORT != NULL && index < counter) { addObject(env, result, "Time_SHORT", time_SHORT, index++); } if(time_MEDIUM != NULL && index < counter) { addObject(env, result, "Time_MEDIUM", time_MEDIUM, index++); } if(time_LONG != NULL && index < counter) { addObject(env, result, "Time_LONG", time_LONG, index++); } if(time_FULL != NULL && index < counter) { addObject(env, result, "Time_FULL", time_FULL, index++); } if(date_SHORT != NULL && index < counter) { addObject(env, result, "Date_SHORT", date_SHORT, index++); } if(date_MEDIUM != NULL && index < counter) { addObject(env, result, "Date_MEDIUM", date_MEDIUM, index++); } if(date_LONG != NULL && index < counter) { addObject(env, result, "Date_LONG", date_LONG, index++); } if(date_FULL != NULL && index < counter) { addObject(env, result, "Date_FULL", date_FULL, index++); } if(decimalPatternChars != NULL && index < counter) { addObject(env, result, "DecimalPatternChars", decimalPatternChars, index++); } if(naN != NULL && index < counter) { addObject(env, result, "NaN", naN, index++); } if(infinity != NULL && index < counter) { addObject(env, result, "Infinity", infinity, index++); } if(currencySymbol != NULL && index < counter) { addObject(env, result, "CurrencySymbol", currencySymbol, index++); } if(intCurrencySymbol != NULL && index < counter) { addObject(env, result, "IntCurrencySymbol", intCurrencySymbol, index++); } if(numberPattern != NULL && index < counter) { addObject(env, result, "Number", numberPattern, index++); } if(integerPattern != NULL && index < counter) { addObject(env, result, "Integer", integerPattern, index++); } if(currencyPattern != NULL && index < counter) { addObject(env, result, "Currency", currencyPattern, index++); } if(percentPattern != NULL && index < counter) { addObject(env, result, "Percent", percentPattern, index++); } return result; }