static BOOL HasUfagBeenLoaded( __in DWORD ProcessId ) { JPFSV_ENUM_HANDLE Enum; HRESULT Hr; JPFSV_MODULE_INFO Mod; BOOL UfagLoaded = FALSE; TEST_OK( JpfsvEnumModules( 0, ProcessId, &Enum ) ); for ( ;; ) { Mod.Size = sizeof( JPFSV_MODULE_INFO ); Hr = JpfsvGetNextItem( Enum, &Mod ); if ( S_FALSE == Hr ) { break; } else if ( 0 == _wcsicmp( Mod.ModuleName, L"jpufag.dll" ) ) { UfagLoaded = TRUE; break; } } TEST_OK( JpfsvCloseEnum( Enum ) ); return UfagLoaded; }
void AllocatorCheck() { unsigned char *pdata = (unsigned char *)os_malloc(1024, 0, "alloc"); if (!pdata) failed("os_malloc"); else { succeeded("os_malloc"); int i; char fail = 0; for (i=0;i<1024;i++) { pdata[i] = i % 255; if (pdata[i] != i % 255) { fail = 1; } } TEST_OK("os_malloc : mem read/write check", fail); TEST_OK("os_free check", os_free(pdata)); } }
static void TestLoadModules() { JPFSV_HANDLE ResolverOwn; JPFSV_HANDLE ResolverNp; PROCESS_INFORMATION pi; LaunchNotepad( &pi ); TEST_OK( JpfsvCreateSymbolResolver( pi.hProcess, NULL, &ResolverNp ) ); TEST_OK( JpfsvCreateSymbolResolver( GetCurrentProcess(), NULL, &ResolverOwn ) ); TEST_OK( JpfsvLoadModule( ResolverOwn, L"jpfsv.dll", ( DWORD_PTR ) GetModuleHandle( L"jpfsv.dll" ), 0 ) ); LoadAllModulesOfProcess( pi.dwProcessId, ResolverNp ); TEST_OK( JpfsvCloseSymbolResolver( ResolverOwn ) ); TEST_OK( JpfsvCloseSymbolResolver( ResolverNp ) ); TEST( TerminateProcess( pi.hProcess, 0 ) ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); }
static void LoadAllModulesOfProcess( __in DWORD ProcId, __in JPFSV_HANDLE Resolver ) { JPFSV_ENUM_HANDLE Enum; HRESULT Hr = E_UNEXPECTED; TEST_OK( JpfsvEnumModules( 0, ProcId, &Enum ) ); do { JPFSV_MODULE_INFO Mod; Mod.Size = sizeof( JPFSV_MODULE_INFO ); Hr = JpfsvGetNextItem( Enum, &Mod ); TEST( SUCCEEDED( Hr ) ); TEST_OK( JpfsvLoadModule( Resolver, Mod.ModulePath, Mod.LoadAddress, Mod.ModuleSize ) ); } while ( S_OK == Hr ); }
static int populate_table(ft_instance_t ft, int count, of_match_t *match) { int idx; of_flow_add_t *flow_add_base; of_flow_add_t *flow_add; ft_entry_t *entry; flow_add_base = of_flow_add_new(OF_VERSION_1_0); TEST_ASSERT(of_flow_add_OF_VERSION_1_0_populate(flow_add_base, 1) != 0); of_flow_add_flags_set(flow_add_base, 0); TEST_OK(of_flow_add_match_get(flow_add_base, match)); for (idx = 0; idx < count; ++idx) { TEST_ASSERT((flow_add = of_object_dup((of_object_t *)flow_add_base)) != NULL); match->fields.eth_type = TEST_ETH_TYPE(idx); TEST_OK(of_flow_add_match_set(flow_add, match)); TEST_INDIGO_OK(FT_ADD(ft, TEST_KEY(idx), flow_add, &entry)); TEST_ASSERT(check_table_entry_states(ft) == 0); } CHECK_FLOW_COUNT(&ft->status, TEST_FLOW_COUNT); of_flow_add_delete(flow_add_base); return 0; }
void ThreadOne(unsigned int a, void *b) { TEST_OK("os_semaphore_obtain", os_semaphore_obtain(&sem1)); flag = 1; TEST_OK("os_semaphore_release", os_semaphore_release(&sem1)); }
void test_timezone () { ADD_TESTS(2); typedef pfs::timezone timezone_t; TEST_OK(pfs::timezone::offset_to_string(0L) == string_t("+0000")); TEST_OK(pfs::timezone::offset_to_string(18000L) == string_t("+0500")); }
/*---------------------------------------------------------------------- * * Test Kernel. * */ static VOID TestAttachDetachKernel() { HRESULT Hr; JPFSV_HANDLE KernelCtx; JPFSV_TRACING_TYPE TracingType; ULONG TypesTested= 0; for ( TracingType = JpfsvTracingTypeDefault; TracingType <= JpfsvTracingTypeMax; TracingType++ ) { Hr = JpfsvLoadContext( JPFSV_KERNEL, NULL, &KernelCtx ); if ( Hr == JPFSV_E_UNSUP_ON_WOW64 ) { CFIX_INCONCLUSIVE( L"Not supported on WOW64" ); return; } TEST_OK( Hr ); TEST( JPFSV_E_NO_TRACESESSION == JpfsvDetachContext( KernelCtx, TRUE ) ); DeleteFile( L"__kern.log" ); if ( TracingType != JpfsvTracingTypeWmk ) { TEST( E_INVALIDARG == JpfsvAttachContext( KernelCtx, TracingType, NULL ) ); Hr = JpfsvAttachContext( KernelCtx, TracingType, L"__kern.log" ); } else { TEST( E_INVALIDARG == JpfsvAttachContext( KernelCtx, TracingType, L"__kern.log" ) ); Hr = JpfsvAttachContext( KernelCtx, TracingType, NULL ); } if ( Hr == JPFSV_E_UNSUPPORTED_TRACING_TYPE || Hr == HRESULT_FROM_NT( 0xC0049300L ) ) // STATUS_KFBT_KERNEL_NOT_SUPPORTED { continue; } TEST_OK( Hr ); TEST( S_FALSE == JpfsvAttachContext( KernelCtx, TracingType, NULL ) ); TEST_OK( DetachContextSafe( KernelCtx ) ); TEST( JPFSV_E_NO_TRACESESSION == JpfsvDetachContext( KernelCtx, TRUE ) ); TEST_OK( JpfsvUnloadContext( KernelCtx ) ); TypesTested++; } if ( TypesTested == 0 ) { CFIX_INCONCLUSIVE( L"No TracingTypes supported" ); } }
void EventCheck2() { VCOS_THREAD_T thread1, thread2; // Create two event group. TEST_OK("os_eventgroup_create", os_eventgroup_create ( &eventgroup, "group") ); TEST_OK("os_eventgroup_create", os_eventgroup_create ( &eventgroup2, "group2") ); TEST_OK("os_thread_start", os_thread_start( &thread1, &ThreadTwo, NULL, 1000, "ThreadOne")); TEST_OK("os_thread_start", os_thread_start( &thread2, &ThreadThree, NULL, 1000, "ThreadTwo")); // Wait for threads to start. Should really check a semaphore! TEST_OK("os_delay", os_delay(1000)); for (current_event=1;current_event<=TERM_EVENT;current_event++) { TEST_OK("os_eventgroup_signal", os_eventgroup_signal ( &eventgroup, current_event) ); // for moment same on other thread current_event2 = current_event; TEST_OK("os_eventgroup_signal", os_eventgroup_signal ( &eventgroup2, current_event2) ); TEST_OK("os_delay", os_delay(1000)); } TEST_OK("os_eventgroup_destroy", os_eventgroup_destroy ( &eventgroup ) ); }
static VOID TestAttachDetachNotepad() { PROCESS_INFORMATION pi; JPFSV_HANDLE NpCtx; // // Launch notepad. // LaunchNotepad( &pi ); // // Give notepad some time to start... // Sleep( 1000 ); TEST_OK( JpfsvLoadContext( pi.dwProcessId, NULL, &NpCtx ) ); TEST( JPFSV_E_NO_TRACESESSION == JpfsvDetachContext( NpCtx, TRUE ) ); TEST_OK( JpfsvAttachContext( NpCtx, JpfsvTracingTypeDefault, NULL ) ); TEST( S_FALSE == JpfsvAttachContext( NpCtx, JpfsvTracingTypeDefault, NULL ) ); // // Check that ufag has been loaded. // TEST( HasUfagBeenLoaded( pi.dwProcessId ) ); TEST_OK( DetachContextSafe( NpCtx ) ); TEST( JPFSV_E_NO_TRACESESSION == JpfsvDetachContext( NpCtx, TRUE ) ); TEST_OK( JpfsvUnloadContext( NpCtx ) ); //// //// Attach again and start a trace. //// //TEST_OK( JpfsvLoadContext( pi.dwProcessId, NULL, &NpCtx ) ); //TEST_OK( JpfsvAttachContext( NpCtx ) ); //TEST_OK( JpfsvDetachContext( NpCtx ) ); //TEST_OK( JpfsvUnloadContext( NpCtx ) ); // // Kill notepad. // TEST( TerminateProcess( pi.hProcess, 0 ) ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); // // Wait i.o. not to confuse further tests with dying process. // Sleep( 1000 ); }
int test_multiple_writes(void) { const char *output = "Zorba!\n"; int maxcount = 5; int fd = open(g_testfilepath, O_CREAT|O_RDWR, 0644); int i = 0; int total = 0; int result = 0; int old_errno = errno; TEST_START(); if (fd < 0) { TEST_FAIL(); TEST_COMPLETE_FAIL("Unable to create file %s\n" "Errno %d: %s\n", g_testfilepath, old_errno, strerror(old_errno)); } TEST_OK(); for (i=0; i<maxcount; i++) { total = 0; result = 0; while (total < strlen(output)) { result = write(fd, output + total, strlen(output)); old_errno = errno; if (result < 0) { close(fd); TEST_FAIL(); TEST_COMPLETE_FAIL("Unable to write to file %s\n" "Errno %d: %s\n", g_testfilepath, old_errno, strerror(old_errno)); } total += result; } } TEST_OK(); if (close(fd) < 0) { TEST_FAIL(); TEST_COMPLETE_FAIL("Unable to close %s\nErrno %d: %s\n", g_testfilepath, errno, strerror(errno)); } TEST_OK(); TEST_COMPLETE_OK(); }
int test_single_write(void) { const char *output = "Zorba!\n"; int fd = open(g_testfilepath, O_CREAT|O_RDWR, 0644); int total = 0; int result = 0; int old_errno = errno; TEST_START(); if (fd < 0) { TEST_FAIL(); TEST_COMPLETE_FAIL("Unable to open %s in %s\n" "Errno %d: %s\n", g_testfilepath, __func__, old_errno, strerror(old_errno)); } TEST_OK(); while (total < strlen(output)) { result = write(fd, output + total, strlen(output)); if (result < 0) { old_errno = errno; TEST_FAIL(); TEST_COMPLETE_FAIL("Unable to write to %s in %s\n" "Errno %d: %s\n", g_testfilepath, __func__, old_errno, strerror(old_errno)); // Don't care about this output -- we're going to die soon, anyway. close(fd); } total += result; } TEST_OK(); if (close(fd) < 0) { old_errno = errno; TEST_FAIL(); TEST_COMPLETE_FAIL("Unable to close %s in %s\n" "Errno %d: %s\n", g_testfilepath, __func__, old_errno, strerror(old_errno)); } TEST_OK(); TEST_COMPLETE_OK(); }
static int test_match_1(void) { of_match_v1_t *m_v1; of_match_v2_t *m_v2; of_match_v3_t *m_v3; of_match_v4_t *m_v4; of_match_t match; int value = 1; int idx; uint32_t exp_value; /* Verify default values for ip mask map */ for (idx = 0; idx < 64; idx++) { exp_value = (idx < 32) ? ~((1 << idx) - 1) : 0; TEST_ASSERT(of_ip_index_to_mask(idx) == exp_value); if (idx < 32) { TEST_ASSERT(of_ip_mask_to_index(exp_value) == idx); } } /* Create/populate/convert and delete for version OF_VERSION_1_0 */ m_v1 = of_match_v1_new(OF_VERSION_1_0); TEST_ASSERT(m_v1 != NULL); TEST_ASSERT((value = of_match_populate(&match, OF_VERSION_1_0, value)) > 0); TEST_OK(of_match_to_wire_match_v1(&match, m_v1)); of_match_v1_delete(m_v1); /* Create/populate/convert and delete for version OF_VERSION_1_1 */ m_v2 = of_match_v2_new(OF_VERSION_1_1); TEST_ASSERT(m_v2 != NULL); TEST_ASSERT((value = of_match_populate(&match, OF_VERSION_1_1, value)) > 0); TEST_OK(of_match_to_wire_match_v2(&match, m_v2)); of_match_v2_delete(m_v2); /* Create/populate/convert and delete for version OF_VERSION_1_2 */ m_v3 = of_match_v3_new(OF_VERSION_1_2); TEST_ASSERT(m_v3 != NULL); TEST_ASSERT((value = of_match_populate(&match, OF_VERSION_1_2, value)) > 0); TEST_OK(of_match_to_wire_match_v3(&match, m_v3)); of_match_v3_delete(m_v3); /* Create/populate/convert and delete for version OF_VERSION_1_3 */ m_v4 = of_match_v4_new(OF_VERSION_1_3); TEST_ASSERT(m_v4 != NULL); TEST_ASSERT((value = of_match_populate(&match, OF_VERSION_1_3, value)) > 0); TEST_OK(of_match_to_wire_match_v4(&match, m_v4)); of_match_v4_delete(m_v4); return TEST_PASS; }
void ThreadThree(unsigned int a, void *b) { int32_t event_map = 0; int32_t event = 0; while (event!=TERM_EVENT) { os_eventgroup_retrieve ( &eventgroup2, &event_map ); // Cheap and cheerful 'lookup'...fast though. switch (event_map) { case 0 : case 1 : case 2 : event = event_map -1; break; case 4 : event = 2 ; break; case 8 : event = 3 ; break; case 16 : event = 4; break; case 32 : event = 5; break; default : event = 0; break; }; // printf("\n Got pattern %d, changed to %d, expected %d\n", event_map, event, current_event); TEST_OK("event index correct", !(event == current_event2)); } }
int main() { struct priority_queue *q; q = priority_queue_init(char_cmp); assert(q != NULL); assert(priority_queue_size(q) == 0); priority_queue_add(q, (void *) 'a'); assert(priority_queue_size(q) == 1); assert((char) priority_queue_get(q) == 'a'); priority_queue_add(q, (void *) 'b'); assert(priority_queue_size(q) == 2); assert((char) priority_queue_get(q) == 'a'); priority_queue_add(q, (void *) 'c'); assert(priority_queue_size(q) == 3); assert((char) priority_queue_pop(q) == 'a'); assert(priority_queue_size(q) == 2); assert((char) priority_queue_pop(q) == 'b'); assert((char) priority_queue_pop(q) == 'c'); assert(priority_queue_pop(q) == NULL); priority_queue_destory(q); TEST_OK("priority queue test passed..."); }
void ThreadTwo(unsigned int a, void *b) { int32_t event_map = 0; int32_t event = 0; // We wait on an event in the event group, then cross reference agains th eone we were expect. Do multiple times. while (event!=TERM_EVENT) { //TEST_OK("os_eventgroup_retrieve", os_eventgroup_retrieve ( &eventgroup, &event_map ) ); os_eventgroup_retrieve ( &eventgroup, &event_map ); // convert event to an index rather than a bit pattern // Cheap and cheerful 'lookup'...fast though. switch (event_map) { case 0 : case 1 : case 2 : event = event_map -1; break; case 4 : event = 2 ; break; case 8 : event = 3 ; break; case 16 : event = 4; break; case 32 : event = 5; break; default : event = 0; break; }; // printf("\n Got pattern %d, changed to %d, expected %d\n", event_map, event, current_event); TEST_OK("event index correct", !(event == current_event)); } }
int main(int argc, char *argv[]) { test_read_file(__FILE__); test_write_file(); TEST_OK("IO test passed..."); }
/* Generic routine for parsing an array of values. */ static bool parse_array( const char **string, parser_t parse_type, struct void_array *result, size_t type_size) { /* Start with a sensible upper bound for the number of values and allocate * enough for this; we'll then resize back down when we're done. There * can't be more than one element every two characters as separators are * mandatory in this parser. */ unsigned int initial_count = (unsigned int) (strlen(*string) + 1) / 2; char *data = malloc(type_size * initial_count); unsigned int count = 0; bool ok = true; bool whitespace = true; // Did we see whitespace before this? while (ok && **string != 0) { ok = TEST_OK(count < initial_count) && TEST_OK_(whitespace, "Whitespace separator expected") && parse_type(string, data + type_size * count); whitespace = skip_whitespace(string); count += 1; } if (ok) { result->count = count; result->data = realloc(data, type_size * count); } else free(data); return ok; }
static void TestOpenNtfsFile() { JPTRCRHANDLE Handle; CALLBACK_CONTEXT Ctx; Ctx.Counter = 0; TEST_OK( JptrcrOpenFile( DATA_DIR L"ntfs.jtrc" , &Handle ) ); TEST_OK( JptrcrEnumModules( Handle, ExpectNtfsModuleCallback, &Ctx.Counter ) ); TEST( Ctx.Counter > 0 ); Ctx.Counter = 0; Ctx.Handle = Handle; TEST_OK( JptrcrEnumClients( Handle, ExpectSomeClientsCallback, &Ctx ) ); TEST( Ctx.Counter > 0 ); TEST_OK( JptrcrCloseFile( Handle ) ); }
void canonical () { ADD_TESTS(1 + sizeof(canonical_data)/sizeof(canonical_data[0]) - 1); TEST_OK(path_type().canonical() == path_type()); canonical_data_t * p = & canonical_data[0]; while (!p->path_str.empty()) { std::ostringstream oss; path_type canonical = path_type(p->path_str).canonical(); oss << "'" << canonical.str() << "' is canonical for '" << p->path_str << "'"; bool result = canonical == path_type(p->canonical); if (!result) { oss << "' but expected '" << p->canonical << "'"; } TEST_OK2(result, oss.str().c_str()); ++p; } }
static void ChildCallsCallback( __in PJPTRCR_CALL Call, __in_opt PVOID Context ) { PCALLBACK_CONTEXT Ctx = ( PCALLBACK_CONTEXT ) Context; TEST( Ctx ); if ( ! Ctx ) return; Ctx->Counter++; TEST( ! ( ( Call->EntryType == JptrcrSyntheticEntry ) && ( Call->ExitType == JptrcrSyntheticExit ) ) ); //OutputDebugString( Call->Symbol->Name ); // // Recurse. // if ( Call->EntryType == JptrcrSyntheticEntry ) { TEST( Call->ChildCalls == 0 ); TEST_HR( E_INVALIDARG, JptrcrEnumChildCalls( Ctx->Handle, &Call->CallHandle, ChildCallsCallback, Ctx ) ); } else { TEST_OK( JptrcrEnumChildCalls( Ctx->Handle, &Call->CallHandle, ChildCallsCallback, Ctx ) ); } }
static BOOL AddProcedureSymCallback( __in PSYMBOL_INFO SymInfo, __in ULONG SymbolSize, __in PVOID UserContext ) { PPROC_SET Set = ( PPROC_SET ) UserContext; TEST( Set->Process ); TEST( Set->ContextHandle ); UNREFERENCED_PARAMETER( SymbolSize ); if ( Set->Count < _countof( Set->Procedures ) && ( SymInfo->Tag == 5 /* SymTagFunction */ || SymInfo->Tag == 10 /* SymTagPublicSymbol */ ) ) { BOOL Hotpatchable; UINT PaddingSize; if ( Set->Process == JPFSV_KERNEL_PSEUDO_HANDLE ) { // // Cannot test patchability. // } else { TEST_OK( JpfsvCheckProcedureInstrumentability( Set->ContextHandle, ( DWORD_PTR ) SymInfo->Address, &Hotpatchable, &PaddingSize ) ); if ( ! Hotpatchable || PaddingSize < JPFBT_MIN_PROCEDURE_PADDING_REQUIRED ) { return TRUE; } } //// //// Make sure we do not generate duplicates. //// //for ( Index = 0; Index < Set->Count; Index++ ) //{ // if ( Set->Procedures[ Index ] == ( DWORD_PTR ) SymInfo->Address ) // { // return TRUE; // } //} // // Patchable. // Set->Procedures[ Set->Count++ ] = ( DWORD_PTR ) SymInfo->Address; } return TRUE; }
void test_sign_of_fp () { ADD_TESTS(9); TEST_OK(pfs::sign_of<T>(0) == 0); TEST_OK(pfs::sign_of<T>(-0) == 0); TEST_OK(pfs::sign_of<T>(+0) == 0); TEST_OK(pfs::sign_of<T>(1) == 1); TEST_OK(pfs::sign_of<T>(-1) == -1); TEST_OK(pfs::sign_of<T>(pfs::numeric_limits<T>::min()) == 1); TEST_OK(pfs::sign_of<T>(pfs::numeric_limits<T>::max()) == 1); TEST_OK(pfs::sign_of<T>(-pfs::numeric_limits<T>::min()) == -1); TEST_OK(pfs::sign_of<T>(-pfs::numeric_limits<T>::max()) == -1); }
/* Reads a complete (short) response from the server until end of input, fails * if buffer overflows (or any other reason). */ static bool read_response(FILE *stream, char *buf, size_t buflen) { size_t rx = fread(buf, 1, buflen - 1, stream); buf[rx] = '\0'; return TEST_OK_(rx < buflen, "Read buffer exhausted") && TEST_OK(!ferror(stream)) && TEST_OK_(rx > 0, "No response from server"); }
/* Captures open data stream to configured output file. */ static bool capture_and_save(FILE *stream) { return IF_(!continuous_capture, TEST_OK(READ_ITEM(stream, sample_count))) && IF_ELSE(matlab_format, capture_matlab_data(stream), capture_raw_data(stream)); }
void _test_read_write(char *seq, char mode[2]){ FILE *fh; size_t seq_len = strlen(seq); fh = fopen(TEST_FILE, mode); size_t file_pos = ftell(fh); size_t pos = fencode(fh, (unsigned char *)seq); TEST_OK((seq_len + 1) / 2 == pos - file_pos); fflush(fh); fclose(fh); fh = fopen(TEST_FILE, "rb"); //printf("%i:%i\n", file_pos, pos); char *read_seq = (char *)fdecode(fh, file_pos, pos); //printf("%s, %s\n", seq, read_seq); TEST_OK(!strcmp(seq, read_seq)); free(read_seq); fclose(fh); }
void test_decoder(const char *seq){ char *encoded = (char *)encode((unsigned char *)seq); char *reseq = (char *)decode((unsigned char *)encoded); TEST_OK(!strcmp(seq, reseq)); CONST_FREE(reseq); CONST_FREE(encoded); }
void test_struct(){ FILE *fh; const f4bit *f4; char *seq = "ACC"; size_t seq_len = strlen(seq); fh = fopen(TEST_FILE, "wb"); size_t file_pos = ftell(fh); f4 = fencodes(fh, (unsigned char *)seq); // this tells us the file seek start/end positions // of the added seek in ->fh_start, ->fh_end resepctively. TEST_OK((seq_len + 1) / 2 == f4->fh_end - file_pos); // this tells us how many basepairs were added TEST_OK(seq_len == f4->bp_end - f4->bp_start); fflush(fh); free((void *)f4); fclose(fh); remove(TEST_FILE); }
/* Interrogates server for the nominal sample frequency and the decimation * factors. */ static bool read_archive_parameters(void) { FILE *stream; char buffer[64]; return connect_server(&stream) && FINALLY( TEST_OK(fprintf(stream, "CFdDVKC\n") > 0) && read_response(stream, buffer, sizeof(buffer)), // Finally, whether read_response succeeds TEST_OK(fclose(stream) == 0)) && DO_PARSE("server response", parse_archive_parameters, buffer) && TEST_OK_( major_version > SERVER_MAJOR_VERSION || minor_version >= SERVER_MINOR_VERSION, "Server protocol mismatch, server %d.%d less than expected %d.%d", major_version, minor_version, SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION); }
void test_bad_chars(){ char *seq = "ZZZAACCZZ"; unsigned char *encoded = (unsigned char *)encode((unsigned char *)seq); size_t seq_len = strlen(seq); char *reseq = (char *)decode(encoded); TEST_OK(!strcmp("NNNAACCNN", reseq)); free(reseq); free(encoded); char *seq2 = "ZZ"; encoded = (unsigned char *)encode((unsigned char *)seq2); seq_len = strlen(seq2); reseq = (char *)decode(encoded); TEST_OK(!strcmp("NN", reseq)); free(reseq); free(encoded); }