source: tags/arb-6.0-rc3/TOOLS/arb_probe.cxx

Last change on this file was 11889, checked in by westram, 11 years ago
  • add missing comment to closing #endif of test-sections
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 130.4 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : arb_probe.cxx                                     //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <PT_com.h>
12#include <arbdb.h>
13
14#include <client.h>
15#include <servercntrl.h>
16
17#include <arb_defs.h>
18#include <arb_strbuf.h>
19#include <arb_diff.h>
20#include <RegExpr.hxx>
21
22#include <algorithm>
23#include <string> // need to include before test_unit.h
24#include <unistd.h>
25
26struct apd_sequence {
27    apd_sequence *next;
28    const char *sequence;
29};
30
31struct Params {
32    int         DESIGNCLIPOUTPUT;
33    int         SERVERID;
34    const char *DESIGNNAMES;
35    int         DESIGNPROBELEN;
36    int         DESIGNMAXPROBELEN;
37    const char *DESIGNSEQUENCE;
38
39    int         MINTEMP;
40    int         MAXTEMP;
41    int         MINGC;
42    int         MAXGC;
43    int         MAXBOND;
44    int         MINPOS;
45    int         MAXPOS;
46    int         MISHIT;
47    int         MINTARGETS;
48    const char *SEQUENCE;
49    int         MISMATCHES;
50    int         ACCEPTN;
51    int         LIMITN;
52    int         MAXRESULT;
53    int         COMPLEMENT;
54    int         WEIGHTED;
55
56    apd_sequence *sequence;
57
58    int         ITERATE;
59    int         ITERATE_AMOUNT;
60    int         ITERATE_READABLE;
61    const char *ITERATE_SEPARATOR;
62    const char *ITERATE_TU;
63
64    const char *DUMP;
65};
66
67
68struct gl_struct {
69    aisc_com  *link;
70    T_PT_MAIN  com;
71    T_PT_LOCS  locs;
72    int        pd_design_id;
73
74    gl_struct()
75        : link(0),
76          pd_design_id(0)
77    {
78    }
79
80};
81
82static Params    P;
83static gl_struct pd_gl;
84
85static int init_local_com_struct() {
86    const char *user = GB_getenvUSER();
87
88    if (aisc_create(pd_gl.link, PT_MAIN, pd_gl.com,
89                    MAIN_LOCS, PT_LOCS, pd_gl.locs,
90                    LOCS_USER, user,
91                    NULL)) {
92        return 1;
93    }
94
95    return 0;
96}
97
98static const char *AP_probe_pt_look_for_server(ARB_ERROR& error) {
99    const char *server_tag = GBS_ptserver_tag(P.SERVERID);
100
101    error = arb_look_and_start_server(AISC_MAGIC_NUMBER, server_tag);
102    if (error) return NULL;
103   
104    return GBS_read_arb_tcp(server_tag);
105}
106
107class PTserverConnection {
108    static int count;
109    bool       need_close;
110public:
111    PTserverConnection(ARB_ERROR& error)
112        : need_close(false)
113    {
114        if (count) {
115            error = "Only 1 PTserverConnection allowed";
116        }
117        else {
118            ++count;
119            const char *servername = AP_probe_pt_look_for_server(error);
120            if (servername) {
121                GB_ERROR openerr = NULL;
122                pd_gl.link       = aisc_open(servername, pd_gl.com, AISC_MAGIC_NUMBER, &openerr);
123                if (openerr) {
124                    error = openerr;
125                }
126                else {
127                    if (!pd_gl.link) {
128                        error = "Cannot contact PT_SERVER [1]";
129                    }
130                    else if (init_local_com_struct()) {
131                        error = "Cannot contact PT_SERVER [2]";
132                    }
133                    else {
134                        need_close = true;
135                    }
136                }
137            }
138        }
139    }
140    ~PTserverConnection() {
141        if (need_close) {
142            aisc_close(pd_gl.link, pd_gl.com);
143            pd_gl.link = 0;
144        }
145        --count;
146    }
147};
148int PTserverConnection::count = 0;
149
150static char *AP_dump_index_event(ARB_ERROR& error) {
151    PTserverConnection contact(error);
152
153    char *result = NULL;
154    if (!error) {
155        aisc_put(pd_gl.link, PT_MAIN, pd_gl.com,
156                 MAIN_DUMP_NAME, P.DUMP,
157                 NULL);
158
159        if (aisc_get(pd_gl.link, PT_MAIN, pd_gl.com,
160                     MAIN_DUMP_INDEX, &result,
161                     NULL)) {
162            error = "Connection to PT_SERVER lost (1)";
163        }
164        else {
165            result = strdup("ok");
166        }
167    }
168    return result;
169}
170
171static char *AP_probe_iterate_event(ARB_ERROR& error) {
172    PTserverConnection contact(error);
173
174    char *result = NULL;
175    if (!error) {
176        T_PT_PEP pep;
177        int      length = P.ITERATE;
178
179        if (aisc_create(pd_gl.link, PT_LOCS, pd_gl.locs,
180                        LOCS_PROBE_FIND_CONFIG, PT_PEP, pep,
181                        PEP_PLENGTH,   (long)length,
182                        PEP_RESTART,   (long)1,
183                        PEP_READABLE,  (long)P.ITERATE_READABLE,
184                        PEP_TU,        (long)P.ITERATE_TU[0],
185                        PEP_SEPARATOR, (long)P.ITERATE_SEPARATOR[0],
186                        NULL))
187        {
188            error = "Connection to PT_SERVER lost (1)";
189        }
190
191        if (!error) {
192            int amount          = P.ITERATE_AMOUNT;
193            int amount_per_call = AISC_MAX_STRING_LEN/(length+2);
194
195            GBS_strstruct out(50000);
196            bool          first = true;
197
198            while (amount && !error) {
199                int this_amount = std::min(amount, amount_per_call);
200
201                aisc_put(pd_gl.link, PT_PEP, pep,
202                         PEP_NUMGET,      (long)this_amount,
203                         PEP_FIND_PROBES, 0,
204                         NULL);
205
206                char *pep_result = 0;
207                if (aisc_get(pd_gl.link, PT_PEP, pep,
208                             PEP_RESULT, &pep_result,
209                             NULL)) {
210                    error = "Connection to PT_SERVER lost (2)";
211                }
212
213                if (!error) {
214                    if (pep_result[0]) {
215                        if (first) first = false;
216                        else out.put(P.ITERATE_SEPARATOR[0]);
217
218                        out.cat(pep_result);
219                        amount -= this_amount;
220                    }
221                    else {
222                        amount = 0; // terminate loop
223                    }
224                }
225                free(pep_result);
226            }
227
228            if (!error) {
229                result = out.release();
230            }
231        }
232    }
233
234    if (error) freenull(result);
235    return result;
236}
237
238static char *AP_probe_design_event(ARB_ERROR& error) {
239    PTserverConnection contact(error);
240
241    if (!error) {
242        bytestring bs;
243        bs.data = (char*)(P.DESIGNNAMES);
244        bs.size = strlen(bs.data)+1;
245
246        T_PT_PDC pdc;
247        if (aisc_create(pd_gl.link, PT_LOCS, pd_gl.locs,
248                        LOCS_PROBE_DESIGN_CONFIG, PT_PDC, pdc,
249                        PDC_MIN_PROBELEN, (long)P.DESIGNPROBELEN,
250                        PDC_MAX_PROBELEN, (long)P.DESIGNMAXPROBELEN,
251                        PDC_MINTEMP,      (double)P.MINTEMP,
252                        PDC_MAXTEMP,      (double)P.MAXTEMP,
253                        PDC_MINGC,        P.MINGC/100.0,
254                        PDC_MAXGC,        P.MAXGC/100.0,
255                        PDC_MAXBOND,      (double)P.MAXBOND,
256                        PDC_MIN_ECOLIPOS, (long)P.MINPOS,
257                        PDC_MAX_ECOLIPOS, (long)P.MAXPOS,
258                        PDC_MISHIT,       (long)P.MISHIT,
259                        PDC_MINTARGETS,   P.MINTARGETS/100.0,
260                        PDC_CLIPRESULT,   (long)P.DESIGNCLIPOUTPUT,
261                        NULL))
262        {
263            error = "Connection to PT_SERVER lost (1)";
264        }
265
266        if (!error) {
267            for (apd_sequence *s = P.sequence; s; ) {
268                apd_sequence *next = s->next;
269
270                bytestring    bs_seq;
271                T_PT_SEQUENCE pts;
272
273                bs_seq.data = (char*)s->sequence;
274                bs_seq.size = strlen(bs_seq.data)+1;
275                aisc_create(pd_gl.link, PT_PDC, pdc,
276                            PDC_SEQUENCE, PT_SEQUENCE, pts,
277                            SEQUENCE_SEQUENCE, &bs_seq,
278                            NULL);
279
280                delete s;
281                s = next;
282            }
283
284            aisc_put(pd_gl.link, PT_PDC, pdc,
285                     PDC_NAMES, &bs,
286                     PDC_GO, 0,
287                     NULL);
288
289            {
290                char *locs_error = 0;
291                if (aisc_get(pd_gl.link, PT_LOCS, pd_gl.locs,
292                             LOCS_ERROR, &locs_error,
293                             NULL)) {
294                    error = "Connection to PT_SERVER lost (2)";
295                }
296                else {
297                    if (*locs_error) error = GBS_static_string(locs_error);
298                    free(locs_error);
299                }
300            }
301
302            if (!error) {
303                T_PT_TPROBE tprobe;
304                aisc_get(pd_gl.link, PT_PDC, pdc,
305                         PDC_TPROBE, tprobe.as_result_param(),
306                         NULL);
307
308
309                GBS_strstruct *outstr = GBS_stropen(1000);
310
311                if (tprobe.exists()) {
312                    char *match_info = 0;
313                    aisc_get(pd_gl.link, PT_PDC, pdc,
314                             PDC_INFO_HEADER, &match_info,
315                             NULL);
316                    GBS_strcat(outstr, match_info);
317                    GBS_chrcat(outstr, '\n');
318                    free(match_info);
319                }
320
321
322                while (tprobe.exists()) {
323                    char *match_info = 0;
324                    if (aisc_get(pd_gl.link, PT_TPROBE, tprobe,
325                                 TPROBE_NEXT, tprobe.as_result_param(),
326                                 TPROBE_INFO, &match_info,
327                                 NULL)) break;
328                    GBS_strcat(outstr, match_info);
329                    GBS_chrcat(outstr, '\n');
330                    free(match_info);
331                }
332
333                return GBS_strclose(outstr);
334            }
335        }
336    }
337    return NULL;
338}
339
340static char *AP_probe_match_event(ARB_ERROR& error) {
341    PTserverConnection contact(error);
342
343    if (!error &&
344        aisc_nput(pd_gl.link, PT_LOCS, pd_gl.locs,
345                  LOCS_MATCH_REVERSED,       (long)P.COMPLEMENT,
346                  LOCS_MATCH_SORT_BY,        (long)P.WEIGHTED,
347                  LOCS_MATCH_COMPLEMENT,     0L,
348                  LOCS_MATCH_MAX_MISMATCHES, (long)P.MISMATCHES,
349                  LOCS_MATCH_N_ACCEPT,       (long)P.ACCEPTN,
350                  LOCS_MATCH_N_LIMIT,        (long)P.LIMITN,
351                  LOCS_MATCH_MAX_HITS,       (long)P.MAXRESULT,
352                  LOCS_SEARCHMATCH,          P.SEQUENCE,
353                  NULL)) {
354        error = "Connection to PT_SERVER lost (1)";
355    }
356
357    if (!error) {
358        bytestring bs;
359        bs.data = 0;
360        {
361            char           *locs_error = 0;
362            T_PT_MATCHLIST  match_list;
363            long            match_list_cnt;
364
365            aisc_get(pd_gl.link, PT_LOCS, pd_gl.locs,
366                     LOCS_MATCH_LIST,     match_list.as_result_param(),
367                     LOCS_MATCH_LIST_CNT, &match_list_cnt,
368                     LOCS_MATCH_STRING,   &bs,
369                     LOCS_ERROR,          &locs_error,
370                     NULL);
371            if (*locs_error) error = GBS_static_string(locs_error);
372            free(locs_error);
373        }
374
375        if (!error) return bs.data; // freed by caller
376        free(bs.data);
377    }
378    return NULL;
379}
380
381static int          pargc;
382static const char **pargv = NULL;
383static bool         showhelp;
384
385static int getInt(const char *param, int val, int min, int max, const char *description) {
386    if (showhelp) {
387        printf("    %s=%i [%i .. %i] %s\n", param, val, min, max, description);
388        return 0;
389    }
390    int   i;
391    const char *s = 0;
392
393    arb_assert(pargc >= 1);     // otherwise s stays 0
394
395    for (i=1; i<pargc; i++) {
396        s = pargv[i];
397        if (*s == '-') s++;
398        if (!strncasecmp(s, param, strlen(param))) break;
399    }
400    if (i==pargc) return val;
401    s += strlen(param);
402    if (*s != '=') return val;
403    s++;
404    val = atoi(s);
405    pargc--;        // remove parameter
406    for (; i<pargc; i++) {
407        pargv[i] = pargv[i+1];
408    }
409
410    if (val<min) val = min;
411    if (val>max) val = max;
412    return val;
413}
414
415static const char *getString(const char *param, const char *val, const char *description) {
416    if (showhelp) {
417        if (!val) val = "";
418        printf("    %s=%s   %s\n", param, val, description);
419        return 0;
420    }
421    int   i;
422    const char *s = 0;
423
424    arb_assert(pargc >= 1);     // otherwise s stays 0
425
426    for (i=1; i<pargc; i++) {
427        s = pargv[i];
428        if (*s == '-') s++;
429        if (!strncasecmp(s, param, strlen(param))) break;
430    }
431    if (i==pargc) return val;
432    s += strlen(param);
433    if (*s != '=') return val;
434    s++;
435    pargc--;        // remove parameter
436    for (; i<pargc; i++) {
437        pargv[i] = pargv[i+1];
438    }
439    return s;
440}
441
442static bool parseCommandLine(int argc, const char * const * const argv) {
443    pargc = argc;
444   
445    // copy argv (since parser will remove matched arguments)
446    free(pargv);
447    pargv = (const char **)malloc(sizeof(*pargv)*pargc);
448    for (int i=0; i<pargc; i++) pargv[i] = argv[i];
449
450    showhelp = (pargc <= 1);
451
452#ifdef UNIT_TESTS // UT_DIFF
453    const int minServerID   = TEST_GENESERVER_ID;
454#else // !UNIT_TESTS
455    const int minServerID   = 0;
456#endif
457
458    P.SERVERID = getInt("serverid", 0, minServerID, 100, "Server Id, look into $ARBHOME/lib/arb_tcp.dat");
459#ifdef UNIT_TESTS // UT_DIFF
460    if (P.SERVERID<0) { arb_assert(P.SERVERID == TEST_SERVER_ID || P.SERVERID == TEST_GENESERVER_ID); }
461#endif
462
463    P.DESIGNCLIPOUTPUT = getInt("designmaxhits", 100, 10, 10000, "Maximum Number of Probe Design Suggestions");
464    P.DESIGNNAMES      = getString("designnames", "",            "List of short names separated by '#'");
465
466    P.sequence = 0;
467    while  ((P.DESIGNSEQUENCE = getString("designsequence", 0, "Additional Sequences, will be added to the target group"))) {
468        apd_sequence *= new apd_sequence;
469        s->next          = P.sequence;
470        P.sequence       = s;
471        s->sequence      = P.DESIGNSEQUENCE;
472        P.DESIGNSEQUENCE = 0;
473    }
474    P.DESIGNPROBELEN    = getInt("designprobelength",    18,  2,  100,     "(min.) length of probe");
475    P.DESIGNMAXPROBELEN = getInt("designmaxprobelength", -1,  -1, 100,     "max. length of probe (if specified)");
476    P.MINTEMP           = getInt("designmintemp",        0,   0,  400,     "Minimum melting temperature of probe");
477    P.MAXTEMP           = getInt("designmaxtemp",        400, 0,  400,     "Maximum melting temperature of probe");
478    P.MINGC             = getInt("designmingc",          30,  0,  100,     "Minimum gc content");
479    P.MAXGC             = getInt("designmaxgc",          80,  0,  100,     "Maximum gc content");
480    P.MAXBOND           = getInt("designmaxbond",        0,   0,  10,      "Not implemented");
481    P.MINPOS            = getInt("designminpos",         -1,  -1, INT_MAX, "Minimum ecoli position (-1=none)");
482    P.MAXPOS            = getInt("designmaxpos",         -1,  -1, INT_MAX, "Maximum ecoli position (-1=none)");
483    P.MISHIT            = getInt("designmishit",         0,   0,  10000,   "Number of allowed hits outside the selected group");
484    P.MINTARGETS        = getInt("designmintargets",     50,  0,  100,     "Minimum percentage of hits within the selected species");
485
486    P.SEQUENCE = getString("matchsequence",   "agtagtagt", "The sequence to search for");
487
488    P.MISMATCHES = getInt("matchmismatches", 0,       0, 5,       "Maximum Number of allowed mismatches");
489    P.COMPLEMENT = getInt("matchcomplement", 0,       0, 1,       "Match reversed and complemented probe");
490    P.WEIGHTED   = getInt("matchweighted",   0,       0, 1,       "Use weighted mismatches");
491    P.ACCEPTN    = getInt("matchacceptN",    1,       0, 20,      "Amount of N-matches not counted as mismatch");
492    P.LIMITN     = getInt("matchlimitN",     4,       0, 20,      "Limit for N-matches. If reached N-matches are mismatches");
493    P.MAXRESULT  = getInt("matchmaxresults", 1000000, 0, INT_MAX, "Max. number of matches reported (0=unlimited)");
494
495    P.ITERATE          = getInt("iterate",          0,   1, 20,      "Iterate over probes of given length");
496    P.ITERATE_AMOUNT   = getInt("iterate_amount",   100, 1, INT_MAX, "Number of results per answer");
497    P.ITERATE_READABLE = getInt("iterate_readable", 1,   0, 1,       "readable results");
498
499    P.ITERATE_TU        = getString("iterate_tu",        "T", "use T or U in readable result");
500    P.ITERATE_SEPARATOR = getString("iterate_separator", ";", "Number of results per answer");
501
502    P.DUMP = getString("dump", "", "dump ptserver index to file (may be huge!)");
503
504    if (pargc>1) {
505        printf("Unknown (or duplicate) parameter %s\n", pargv[1]);
506        return false;
507    }
508    return !showhelp;
509}
510
511// --------------------------------------------------------------------------------
512
513#ifdef UNIT_TESTS
514#ifndef TEST_UNIT_H
515#include <test_unit.h>
516#endif
517
518void TEST_BASIC_parseCommandLine() {
519    {
520        const char *args[] = { NULL, "serverid=0"};
521        TEST_EXPECT(parseCommandLine(ARRAY_ELEMS(args), args));
522
523        // test default values here
524        TEST_EXPECT_EQUAL(P.ACCEPTN, 1);
525        TEST_EXPECT_EQUAL(P.LIMITN, 4);
526        TEST_EXPECT_EQUAL(P.MISMATCHES, 0);
527        TEST_EXPECT_EQUAL(P.MAXRESULT, 1000000);
528    }
529
530    {
531        const char *args[] = {NULL, "serverid=4", "matchmismatches=2"};
532        TEST_EXPECT(parseCommandLine(ARRAY_ELEMS(args), args));
533        TEST_EXPECT_EQUAL(P.SERVERID, 4);
534        TEST_EXPECT_EQUAL(P.MISMATCHES, 2);
535        TEST_EXPECT_EQUAL(args[1], "serverid=4"); // check array args was not modified
536    }
537
538    {
539        const char *args[] = { NULL, "matchacceptN=0", "matchlimitN=5"};
540        TEST_EXPECT(parseCommandLine(ARRAY_ELEMS(args), args));
541        TEST_EXPECT_EQUAL(P.ACCEPTN, 0);
542        TEST_EXPECT_EQUAL(P.LIMITN, 5);
543    }
544
545    {
546        const char *args[] = { NULL, "matchmaxresults=100"};
547        TEST_EXPECT(parseCommandLine(ARRAY_ELEMS(args), args));
548        TEST_EXPECT_EQUAL(P.MAXRESULT, 100);
549    }
550}
551
552#endif // UNIT_TESTS
553
554// --------------------------------------------------------------------------------
555
556
557static char *execute(ARB_ERROR& error) {
558    char *answer;
559    if (*P.DESIGNNAMES || P.sequence) {
560        answer = AP_probe_design_event(error);
561    }
562    else if (P.ITERATE>0) {
563        answer = AP_probe_iterate_event(error);
564    }
565    else if (P.DUMP[0]) {
566        answer = AP_dump_index_event(error);
567    }
568    else {
569        answer = AP_probe_match_event(error);
570    }
571    pd_gl.locs.clear();
572    return answer;
573}
574
575int ARB_main(int argc, char *argv[]) {
576    bool ok = parseCommandLine(argc, argv);
577    if (ok) {
578        ARB_ERROR  error;
579        char      *answer = execute(error);
580
581        arb_assert(contradicted(answer, error));
582       
583        if (!answer) {
584            fprintf(stderr,
585                    "arb_probe: Failed to process your request\n"
586                    "           Reason: %s",
587                    error.deliver());
588            ok = false;
589        }
590        else {
591            fputs(answer, stdout);
592            free(answer);
593            error.expect_no_error();
594        }
595    }
596    return ok ? EXIT_SUCCESS : EXIT_FAILURE;
597}
598
599// --------------------------------------------------------------------------------
600
601#ifdef UNIT_TESTS
602#ifndef TEST_UNIT_H
603#include <test_unit.h>
604#endif
605
606static int test_setup(bool use_gene_ptserver) {
607    static bool setup[2] = { false, false };
608    if (!setup[use_gene_ptserver]) {
609        TEST_SETUP_GLOBAL_ENVIRONMENT(use_gene_ptserver ? "ptserver_gene" : "ptserver"); // first call will recreate the test pt-server
610        setup[use_gene_ptserver] = true;
611    }
612    return use_gene_ptserver ? TEST_GENESERVER_ID : TEST_SERVER_ID;
613}
614
615// ----------------------------------
616//      test probe design / match
617
618#define TEST_RUN_ARB_PROBE__INT(fake_argc,fake_argv)                                    \
619    int serverid = test_setup(use_gene_ptserver);                                       \
620    TEST_EXPECT_EQUAL(true, parseCommandLine(fake_argc, fake_argv));                    \
621    TEST_EXPECT((serverid == TEST_SERVER_ID)||(serverid == TEST_GENESERVER_ID));        \
622    P.SERVERID = serverid;                                                              \
623    ARB_ERROR error;                                                                    \
624    char *answer = execute(error)
625
626#define TEST_ARB_PROBE__REPORTS_ERROR(fake_argc,fake_argv,expected_error)       \
627    TEST_RUN_ARB_PROBE__INT(fake_argc,fake_argv);                               \
628    free(answer);                                                               \
629    TEST_EXPECT_ERROR_CONTAINS(error.deliver(), expected_error)
630
631#define TEST_ARB_PROBE__REPORTS_ERROR__BROKEN(fake_argc,fake_argv,expected_error)       \
632    TEST_RUN_ARB_PROBE__INT(fake_argc,fake_argv);                                       \
633    free(answer);                                                                       \
634    TEST_EXPECT_ANY_ERROR(error.preserve());                                            \
635    TEST_EXPECT_ERROR_CONTAINS__BROKEN(error.deliver(), expected_error)
636
637
638#define TEST_RUN_ARB_PROBE(fake_argc,fake_argv)                 \
639    TEST_RUN_ARB_PROBE__INT(fake_argc,fake_argv);               \
640    TEST_EXPECT_NO_ERROR(error.deliver())
641
642#define TEST_ARB_PROBE(fake_argc,fake_argv,expected) do {       \
643        TEST_RUN_ARB_PROBE(fake_argc,fake_argv);                \
644        TEST_EXPECT_EQUAL(answer, expected);                    \
645        free(answer);                                           \
646    } while(0)
647
648#define TEST_ARB_PROBE__BROKEN(fake_argc,fake_argv,expected) do {       \
649        TEST_RUN_ARB_PROBE(fake_argc,fake_argv);                        \
650        TEST_EXPECT_EQUAL__BROKEN(answer, expected);                    \
651        free(answer);                                                   \
652    } while(0)
653
654#define TEST_ARB_PROBE_FILT(fake_argc,fake_argv,filter,expected) do {   \
655        TEST_RUN_ARB_PROBE(fake_argc,fake_argv);                        \
656        char  *filtered   = filter(answer);                             \
657        TEST_EXPECT_EQUAL(filtered, expected);                          \
658        free(filtered);                                                 \
659        free(answer);                                                   \
660    } while(0)
661
662typedef const char *CCP;
663
664void TEST_SLOW_match_geneprobe() {
665    // test here runs versus database ../UNIT_TESTER/run/TEST_gpt_src.arb
666
667    bool use_gene_ptserver = true;
668    {
669        const char *arguments[] = {
670            "prgnamefake",
671            "matchsequence=NNUCNN",
672            "matchacceptN=4",
673            "matchlimitN=5",
674        };
675        CCP expectd = "    organism genename------- mis N_mis wmis pos gpos rev          'NNUCNN'\1"
676            "genome2\1" "  genome2  gene3             0     4  2.6   2    1 0   .........-UU==GG-UUGAUC.\1"
677            "genome2\1" "  genome2  joined1           0     4  2.6   2    1 0   .........-UU==GG-UUGAUCCUG\1"
678            "genome2\1" "  genome2  gene1             0     4  2.6   2    2 0   ........A-UU==GG-U.\1"
679            "genome2\1" "  genome2  intergene_19_65   0     4  2.7  31   12 0   GGUUACUGC-AU==GG-UGUUCGCCU\1"
680            "genome1\1" "  genome1  intergene_17_65   0     4  2.7  31   14 0   GGUUACUGC-UA==GG-UGUUCGCCU\1"
681            "genome2\1" "  genome2  intergene_19_65   0     4  2.7  38   19 0   GCAUUCGGU-GU==GC-CUAAGCACU\1"
682            "genome1\1" "  genome1  intergene_17_65   0     4  2.7  38   21 0   GCUAUCGGU-GU==GC-CUAAGCCAU\1"
683            "genome2\1" "  genome2  gene3             0     4  2.9  10    9 0   .UUUCGGUU-GA==..-\1"
684            "genome2\1" "  genome2  intergene_19_65   0     4  3.1  56   37 0   AGCACUGCG-AG==AU-AUGUA.\1"
685            "genome1\1" "  genome1  intergene_17_65   0     4  3.1  56   39 0   AGCCAUGCG-AG==AU-AUGUA.\1"
686            "genome1\1" "  genome1  gene2             0     4  3.1  10    2 0   ........U-GA==CU-GC.\1"
687            "genome2\1" "  genome2  gene2             0     4  3.1  10    4 0   ......GUU-GA==CU-GCCA.\1"
688            "genome1\1" "  genome1  joined1           0     4  3.1  10    7 0   ...CUGGUU-GA==CU-GC.\1"
689            "genome2\1" "  genome2  joined1           0     4  3.1  10    9 0   .UUUCGGUU-GA==CU-GCCA.\1";
690
691        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd);
692    }
693
694    {
695        const char *arguments[] = {
696            "prgnamefake",
697            "matchsequence=NGGUUN",
698            "matchacceptN=2",
699            "matchlimitN=3",
700        };
701        CCP expectd = "    organism genename------- mis N_mis wmis pos gpos rev          'NGGUUN'\1"
702            "genome1\1" "  genome1  gene3             0     2  1.3   5    2 0   ........C-U====G-A.\1"
703            "genome1\1" "  genome1  joined1           0     2  1.3   5    2 0   ........C-U====G-AUCCUGC.\1"
704            "genome2\1" "  genome2  gene3             0     2  1.4   5    4 0   ......UUU-C====G-AUC.\1"
705            "genome2\1" "  genome2  joined1           0     2  1.4   5    4 0   ......UUU-C====G-AUCCUGCCA\1"
706            "genome2\1" "  genome2  intergene_19_65   0     2  1.8  21    2 0   ........G-A====A-CUGCAUUCG\1"
707            "genome1\1" "  genome1  intergene_17_65   0     2  1.8  21    4 0   ......CAG-A====A-CUGCUAUCG\1";
708
709        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd);
710    }
711
712    {
713        const char *arguments[] = {
714            "prgnamefake",
715            "matchsequence=UGAUCCU", // exists in data
716        };
717        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'UGAUCCU'\1"
718            "genome1\1" "  genome1  gene2      0     0  0.0   9    1 0   .........-=======-GC.\1"
719            "genome2\1" "  genome2  gene2      0     0  0.0   9    3 0   .......GU-=======-GCCA.\1"
720            "genome1\1" "  genome1  joined1    0     0  0.0   9    6 0   ....CUGGU-=======-GC.\1"
721            "genome2\1" "  genome2  joined1    0     0  0.0   9    8 0   ..UUUCGGU-=======-GCCA.\1";
722
723        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // [fixed: now reports hits in  'joined1' (of both genomes)]
724    }
725    {
726        const char *arguments[] = {
727            "prgnamefake",
728            "matchsequence=GAUCCU",
729        };
730        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'GAUCCU'\1"
731            "genome1\1" "  genome1  gene2      0     0  0.0  10    2 0   ........U-======-GC.\1"
732            "genome2\1" "  genome2  gene2      0     0  0.0  10    4 0   ......GUU-======-GCCA.\1"
733            "genome1\1" "  genome1  joined1    0     0  0.0  10    7 0   ...CUGGUU-======-GC.\1"
734            "genome2\1" "  genome2  joined1    0     0  0.0  10    9 0   .UUUCGGUU-======-GCCA.\1";
735
736        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // [fixed: now reports as much hits as previous test; expected cause probe is part of above probe]
737    }
738    {
739        const char *arguments[] = {
740            "prgnamefake",
741            "matchsequence=UUUCGG", // exists only in genome2
742        };
743        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'UUUCGG'\1"
744            "genome2\1" "  genome2  gene3      0     0  0.0   2    1 0   .........-======-UUGAUC.\1"
745            "genome2\1" "  genome2  joined1    0     0  0.0   2    1 0   .........-======-UUGAUCCUG\1"
746            "genome2\1" "  genome2  gene1      0     0  0.0   2    2 0   ........A-======-U.\1";
747
748        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // [fixed: now reports hit in genome2/gene1]
749    }
750    {
751        const char *arguments[] = {
752            "prgnamefake",
753            "matchsequence=AUCCUG", 
754        };
755        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'AUCCUG'\1"
756            "genome1\1" "  genome1  gene2      0     0  0.0  11    3 0   .......UG-======-C.\1"
757            "genome2\1" "  genome2  gene2      0     0  0.0  11    5 0   .....GUUG-======-CCA.\1"
758            "genome1\1" "  genome1  joined1    0     0  0.0  11    8 0   ..CUGGUUG-======-C.\1"
759            "genome2\1" "  genome2  joined1    0     0  0.0  11   10 0   UUUCGGUUG-======-CCA.\1";
760
761        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // [fixed: now reports hits in 'gene2' and 'joined1' of both genomes]
762    }
763    {
764        const char *arguments[] = {
765            "prgnamefake",
766            "matchsequence=UUGAUCCUGC",
767        };
768        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'UUGAUCCUGC'\1"
769            "genome2\1" "  genome2  gene2      0     0  0.0   8    2 0   ........G-==========-CA.\1"
770            "genome1\1" "  genome1  joined1    0     0  0.0   8    5 0   .....CUGG-==========-.\1"
771            "genome2\1" "  genome2  joined1    0     0  0.0   8    7 0   ...UUUCGG-==========-CA.\1";
772
773        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // [fixed: now reports hit in 'genome2/joined1']
774    }
775}
776
777void TEST_SLOW_match_probe() {
778    // test here runs versus database ../UNIT_TESTER/run/TEST_pt_src.arb
779
780    bool use_gene_ptserver = false;
781    {
782        const char *arguments[] = {
783            "prgnamefake",
784            "matchsequence=UAUCGGAGAGUUUGA",
785        };
786        CCP expected = "    name---- fullname mis N_mis wmis pos ecoli rev          'UAUCGGAGAGUUUGA'\1"
787            "BcSSSS00\1" "  BcSSSS00            0     0  0.0   3     2 0   .......UU-===============-UCAAGUCGA\1";
788
789        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
790    }
791
792    // ----------------------------------------------------------------------------
793    //      match with old(=default) N-mismatch-behavior (accepting 1 N-match)
794
795    {
796        const char *arguments[] = {
797            "prgnamefake",
798            "matchsequence=CANCUCCUUUC", // contains 1 N
799            NULL // matchmismatches
800        };
801
802        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
803            "BcSSSS00\1" "  BcSSSS00            0     1  0.9 176   162 0   CGGCUGGAU-==C========-U.\1"; // only N-mismatch accepted
804
805        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
806            "BcSSSS00\1" "  BcSSSS00            0     1  0.9 176   162 0   CGGCUGGAU-==C========-U.\1"
807            "ClfPerfr\1" "  ClfPerfr            1     1  2.0 176   162 0   AGAUUAAUA-=CC========-U.\1"
808            "PbcAcet2\1" "  PbcAcet2            1     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
809            "PbrPropi\1" "  PbrPropi            1     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
810            "Stsssola\1" "  Stsssola            1     2  1.6 176   162 0   CGGCUGGAU-==C=======.-\1"
811            "DcdNodos\1" "  DcdNodos            1     2  1.6 176   162 0   CGGUUGGAU-==C=======.-\1"
812            "VbrFurni\1" "  VbrFurni            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
813            "VblVulni\1" "  VblVulni            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
814            "VbhChole\1" "  VbhChole            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1";
815
816        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
817            "BcSSSS00\1" "  BcSSSS00            0     1  0.9 176   162 0   CGGCUGGAU-==C========-U.\1"
818            "ClfPerfr\1" "  ClfPerfr            1     1  2.0 176   162 0   AGAUUAAUA-=CC========-U.\1"
819            "PbcAcet2\1" "  PbcAcet2            1     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
820            "PbrPropi\1" "  PbrPropi            1     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
821            "Stsssola\1" "  Stsssola            1     2  1.6 176   162 0   CGGCUGGAU-==C=======.-\1"
822            "DcdNodos\1" "  DcdNodos            1     2  1.6 176   162 0   CGGUUGGAU-==C=======.-\1"
823            "VbrFurni\1" "  VbrFurni            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
824            "VblVulni\1" "  VblVulni            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
825            "VbhChole\1" "  VbhChole            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
826            "AclPleur\1" "  AclPleur            2     2  2.7 176   162 0   CGGUUGGAU-==C======A.-\1"
827            "PtVVVulg\1" "  PtVVVulg            2     2  2.7 176   162 0   CGGUUGGAU-==C======A.-\1"
828            "DlcTolu2\1" "  DlcTolu2            2     3  2.3 176   162 0   CGGCUGGAU-==C======NN-N.\1"
829            "FrhhPhil\1" "  FrhhPhil            2     3  2.3 176   162 0   CGGCUGGAU-==C======..-\1"
830            "HllHalod\1" "  HllHalod            2     3  2.3 176   162 0   CGGCUGGAU-==C======..-\1"
831            "CPPParap\1" "  CPPParap            2     3  2.3 177   163 0   CGGNUGGAU-==C======..-\1";
832
833        CCP expectd3 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
834            "BcSSSS00\1" "  BcSSSS00            0     1  0.9 176   162 0   CGGCUGGAU-==C========-U.\1"
835            "ClfPerfr\1" "  ClfPerfr            1     1  2.0 176   162 0   AGAUUAAUA-=CC========-U.\1"
836            "PbcAcet2\1" "  PbcAcet2            1     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
837            "PbrPropi\1" "  PbrPropi            1     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
838            "Stsssola\1" "  Stsssola            1     2  1.6 176   162 0   CGGCUGGAU-==C=======.-\1"
839            "DcdNodos\1" "  DcdNodos            1     2  1.6 176   162 0   CGGUUGGAU-==C=======.-\1"
840            "VbrFurni\1" "  VbrFurni            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
841            "VblVulni\1" "  VblVulni            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
842            "VbhChole\1" "  VbhChole            1     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
843            "AclPleur\1" "  AclPleur            2     2  2.7 176   162 0   CGGUUGGAU-==C======A.-\1"
844            "PtVVVulg\1" "  PtVVVulg            2     2  2.7 176   162 0   CGGUUGGAU-==C======A.-\1"
845            "DlcTolu2\1" "  DlcTolu2            2     3  2.3 176   162 0   CGGCUGGAU-==C======NN-N.\1"
846            "FrhhPhil\1" "  FrhhPhil            2     3  2.3 176   162 0   CGGCUGGAU-==C======..-\1"
847            "HllHalod\1" "  HllHalod            2     3  2.3 176   162 0   CGGCUGGAU-==C======..-\1"
848            "CPPParap\1" "  CPPParap            2     3  2.3 177   163 0   CGGNUGGAU-==C======..-\1"
849            "VblVulni\1" "  VblVulni            3     1  3.6  49    44 0   AGCACAGAG-a=A==uG====-UCGGGUGGC\1";
850
851        arguments[2] = "matchmismatches=0";  TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
852        arguments[2] = "matchmismatches=1";  TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
853        arguments[2] = "matchmismatches=2";  TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
854        arguments[2] = "matchmismatches=3";  TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd3);
855    }
856
857    {
858        const char *arguments[] = {
859            "prgnamefake",
860            "matchsequence=UCACCUCCUUUC", // contains no N
861            NULL // matchmismatches
862        };
863
864        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
865            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
866            "PbcAcet2\1" "  PbcAcet2            0     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
867            "PbrPropi\1" "  PbrPropi            0     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
868            "Stsssola\1" "  Stsssola            0     1  0.7 175   161 0   GCGGCUGGA-===========.-\1"
869            "DcdNodos\1" "  DcdNodos            0     1  0.7 175   161 0   GCGGUUGGA-===========.-\1"
870            "VbrFurni\1" "  VbrFurni            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
871            "VblVulni\1" "  VblVulni            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
872            "VbhChole\1" "  VbhChole            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1";
873
874        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
875            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
876            "PbcAcet2\1" "  PbcAcet2            0     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
877            "PbrPropi\1" "  PbrPropi            0     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
878            "Stsssola\1" "  Stsssola            0     1  0.7 175   161 0   GCGGCUGGA-===========.-\1"
879            "DcdNodos\1" "  DcdNodos            0     1  0.7 175   161 0   GCGGUUGGA-===========.-\1"
880            "VbrFurni\1" "  VbrFurni            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
881            "VblVulni\1" "  VblVulni            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
882            "VbhChole\1" "  VbhChole            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
883            "AclPleur\1" "  AclPleur            1     1  1.8 175   161 0   GCGGUUGGA-==========A.-\1"
884            "PtVVVulg\1" "  PtVVVulg            1     1  1.8 175   161 0   GCGGUUGGA-==========A.-\1"
885            "DlcTolu2\1" "  DlcTolu2            1     2  1.4 175   161 0   GCGGCUGGA-==========NN-N.\1"
886            "FrhhPhil\1" "  FrhhPhil            1     2  1.4 175   161 0   GCGGCUGGA-==========..-\1"
887            "HllHalod\1" "  HllHalod            1     2  1.4 175   161 0   GCGGCUGGA-==========..-\1"
888            "CPPParap\1" "  CPPParap            1     2  1.4 176   162 0   GCGGNUGGA-==========..-\1";
889
890        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
891            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
892            "PbcAcet2\1" "  PbcAcet2            0     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
893            "PbrPropi\1" "  PbrPropi            0     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
894            "Stsssola\1" "  Stsssola            0     1  0.7 175   161 0   GCGGCUGGA-===========.-\1"
895            "DcdNodos\1" "  DcdNodos            0     1  0.7 175   161 0   GCGGUUGGA-===========.-\1"
896            "VbrFurni\1" "  VbrFurni            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
897            "VblVulni\1" "  VblVulni            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
898            "VbhChole\1" "  VbhChole            0     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
899            "AclPleur\1" "  AclPleur            1     1  1.8 175   161 0   GCGGUUGGA-==========A.-\1"
900            "PtVVVulg\1" "  PtVVVulg            1     1  1.8 175   161 0   GCGGUUGGA-==========A.-\1"
901            "DlcTolu2\1" "  DlcTolu2            1     2  1.4 175   161 0   GCGGCUGGA-==========NN-N.\1"
902            "FrhhPhil\1" "  FrhhPhil            1     2  1.4 175   161 0   GCGGCUGGA-==========..-\1"
903            "HllHalod\1" "  HllHalod            1     2  1.4 175   161 0   GCGGCUGGA-==========..-\1"
904            "CPPParap\1" "  CPPParap            1     2  1.4 176   162 0   GCGGNUGGA-==========..-\1"
905            "ClfPerfr\1" "  ClfPerfr            2     0  2.2 175   161 0   AAGAUUAAU-A=C=========-U.\1"
906            "LgtLytic\1" "  LgtLytic            2     3  2.1 175   161 0   GCGGCUGGA-=========N..-\1"
907            "PslFlave\1" "  PslFlave            2     3  2.1 175   161 0   GCGGCUGGA-=========...-\1";
908
909        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
910        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
911        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
912    }
913
914    {
915        const char *arguments[] = {
916            "prgnamefake",
917            "matchsequence=UCACCUCCUUUC", // contains no N
918            NULL,                         // matchmismatches
919            "matchweighted=1",            // use weighted mismatches
920        };
921
922        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
923            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
924            "PbcAcet2\1" "  PbcAcet2            0     1  0.2 175   161 0   GCGGCUGGA-===========N-N.\1"
925            "PbrPropi\1" "  PbrPropi            0     1  0.2 175   161 0   GCGGCUGGA-===========N-N.\1"
926            "Stsssola\1" "  Stsssola            0     1  0.2 175   161 0   GCGGCUGGA-===========.-\1"
927            "DcdNodos\1" "  DcdNodos            0     1  0.2 175   161 0   GCGGUUGGA-===========.-\1"
928            "VbrFurni\1" "  VbrFurni            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
929            "VblVulni\1" "  VblVulni            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
930            "VbhChole\1" "  VbhChole            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1";
931
932        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
933            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
934            "PbcAcet2\1" "  PbcAcet2            0     1  0.2 175   161 0   GCGGCUGGA-===========N-N.\1"
935            "PbrPropi\1" "  PbrPropi            0     1  0.2 175   161 0   GCGGCUGGA-===========N-N.\1"
936            "Stsssola\1" "  Stsssola            0     1  0.2 175   161 0   GCGGCUGGA-===========.-\1"
937            "DcdNodos\1" "  DcdNodos            0     1  0.2 175   161 0   GCGGUUGGA-===========.-\1"
938            "VbrFurni\1" "  VbrFurni            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
939            "VblVulni\1" "  VblVulni            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
940            "VbhChole\1" "  VbhChole            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
941            "DlcTolu2\1" "  DlcTolu2            1     2  0.6 175   161 0   GCGGCUGGA-==========NN-N.\1"
942            "FrhhPhil\1" "  FrhhPhil            1     2  0.6 175   161 0   GCGGCUGGA-==========..-\1"
943            "HllHalod\1" "  HllHalod            1     2  0.6 175   161 0   GCGGCUGGA-==========..-\1"
944            "CPPParap\1" "  CPPParap            1     2  0.6 176   162 0   GCGGNUGGA-==========..-\1"
945            "AclPleur\1" "  AclPleur            1     1  0.9 175   161 0   GCGGUUGGA-==========A.-\1"
946            "PtVVVulg\1" "  PtVVVulg            1     1  0.9 175   161 0   GCGGUUGGA-==========A.-\1"
947            "LgtLytic\1" "  LgtLytic            2     3  1.3 175   161 0   GCGGCUGGA-=========N..-\1"
948            "PslFlave\1" "  PslFlave            2     3  1.3 175   161 0   GCGGCUGGA-=========...-\1"
949            "ClfPerfr\1" "  ClfPerfr            2     0  1.3 175   161 0   AAGAUUAAU-A=C=========-U.\1";
950
951        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
952            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
953            "PbcAcet2\1" "  PbcAcet2            0     1  0.2 175   161 0   GCGGCUGGA-===========N-N.\1"
954            "PbrPropi\1" "  PbrPropi            0     1  0.2 175   161 0   GCGGCUGGA-===========N-N.\1"
955            "Stsssola\1" "  Stsssola            0     1  0.2 175   161 0   GCGGCUGGA-===========.-\1"
956            "DcdNodos\1" "  DcdNodos            0     1  0.2 175   161 0   GCGGUUGGA-===========.-\1"
957            "VbrFurni\1" "  VbrFurni            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
958            "VblVulni\1" "  VblVulni            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
959            "VbhChole\1" "  VbhChole            0     1  0.2 175   161 0   GGCGCUGGA-===========.-\1"
960            "DlcTolu2\1" "  DlcTolu2            1     2  0.6 175   161 0   GCGGCUGGA-==========NN-N.\1"
961            "FrhhPhil\1" "  FrhhPhil            1     2  0.6 175   161 0   GCGGCUGGA-==========..-\1"
962            "HllHalod\1" "  HllHalod            1     2  0.6 175   161 0   GCGGCUGGA-==========..-\1"
963            "CPPParap\1" "  CPPParap            1     2  0.6 176   162 0   GCGGNUGGA-==========..-\1"
964            "AclPleur\1" "  AclPleur            1     1  0.9 175   161 0   GCGGUUGGA-==========A.-\1"
965            "PtVVVulg\1" "  PtVVVulg            1     1  0.9 175   161 0   GCGGUUGGA-==========A.-\1"
966            "LgtLytic\1" "  LgtLytic            2     3  1.3 175   161 0   GCGGCUGGA-=========N..-\1"
967            "PslFlave\1" "  PslFlave            2     3  1.3 175   161 0   GCGGCUGGA-=========...-\1"
968            "ClfPerfr\1" "  ClfPerfr            2     0  1.3 175   161 0   AAGAUUAAU-A=C=========-U.\1"
969            "AclPleur\1" "  AclPleur            5     0  2.4  50    45 0   GAAGGGAGC-=ug=u=u====G-CCGACGAGU\1"
970            "PtVVVulg\1" "  PtVVVulg            5     0  2.4  50    45 0   GGAGAAAGC-=ug=u=u===g=-UGACGAGCG\1";
971
972        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
973        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
974        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
975    }
976
977    // ----------------------------------------------
978    //      do not accept any N-matches as match
979
980    {
981        const char *arguments[] = {
982            "prgnamefake",
983            "matchsequence=CANCUCCUUUC", // contains 1 N
984            NULL, // matchmismatches
985            "matchacceptN=0",
986        };
987
988        CCP expectd0 = ""; // nothing matches
989
990        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
991            "BcSSSS00\1" "  BcSSSS00            1     1  0.9 176   162 0   CGGCUGGAU-==C========-U.\1";
992 
993        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
994            "BcSSSS00\1" "  BcSSSS00            1     1  0.9 176   162 0   CGGCUGGAU-==C========-U.\1"
995            "ClfPerfr\1" "  ClfPerfr            2     1  2.0 176   162 0   AGAUUAAUA-=CC========-U.\1"
996            "PbcAcet2\1" "  PbcAcet2            2     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
997            "PbrPropi\1" "  PbrPropi            2     2  1.6 176   162 0   CGGCUGGAU-==C=======N-N.\1"
998            "Stsssola\1" "  Stsssola            2     2  1.6 176   162 0   CGGCUGGAU-==C=======.-\1"
999            "DcdNodos\1" "  DcdNodos            2     2  1.6 176   162 0   CGGUUGGAU-==C=======.-\1"
1000            "VbrFurni\1" "  VbrFurni            2     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
1001            "VblVulni\1" "  VblVulni            2     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1"
1002            "VbhChole\1" "  VbhChole            2     2  1.6 176   162 0   GCGCUGGAU-==C=======.-\1";
1003
1004        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1005        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
1006        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1007    }
1008    {
1009        const char *arguments[] = {
1010            "prgnamefake",
1011            "matchsequence=UUUCUUU", // contains no N
1012            NULL, // matchmismatches
1013            "matchacceptN=0",
1014        };
1015
1016        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UUUCUUU'\1"
1017            "AclPleur\1" "  AclPleur            0     0  0.0  54    49 0   GGAGCUUGC-=======-GCCGACGAG\1";
1018
1019        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UUUCUUU'\1"
1020            "AclPleur\1" "  AclPleur            0     0  0.0  54    49 0   GGAGCUUGC-=======-GCCGACGAG\1"
1021            "AclPleur\1" "  AclPleur            1     0  0.6  50    45 0   GAAGGGAGC-==g====-CUUUGCCGA\1"
1022            "PtVVVulg\1" "  PtVVVulg            1     0  0.6  50    45 0   GGAGAAAGC-==g====-CUUGCUGAC\1"
1023            "PtVVVulg\1" "  PtVVVulg            1     0  0.6  54    49 0   AAAGCUUGC-======g-CUGACGAGC\1"
1024            "ClfPerfr\1" "  ClfPerfr            1     0  1.1  49    44 0   GCGAUGAAG-====C==-CGGGAAACG\1";
1025
1026        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UUUCUUU'\1"
1027            "AclPleur\1" "  AclPleur            0     0  0.0  54    49 0   GGAGCUUGC-=======-GCCGACGAG\1"
1028            "AclPleur\1" "  AclPleur            1     0  0.6  50    45 0   GAAGGGAGC-==g====-CUUUGCCGA\1"
1029            "PtVVVulg\1" "  PtVVVulg            1     0  0.6  50    45 0   GGAGAAAGC-==g====-CUUGCUGAC\1"
1030            "PtVVVulg\1" "  PtVVVulg            1     0  0.6  54    49 0   AAAGCUUGC-======g-CUGACGAGC\1"
1031            "ClfPerfr\1" "  ClfPerfr            1     0  1.1  49    44 0   GCGAUGAAG-====C==-CGGGAAACG\1"
1032            "DlcTolu2\1" "  DlcTolu2            2     0  1.2  47    42 0   AGAAAGGGA-==g===g-CAAUCCUGA\1"
1033            "ClnCorin\1" "  ClnCorin            2     0  1.7  48    43 0   AGCGAUGAA-g===C==-CGGGAAUGG\1"
1034            "CPPParap\1" "  CPPParap            2     0  1.7  48    43 0   AGCGAUGAA-g===C==-CGGGAACGG\1"
1035            "HllHalod\1" "  HllHalod            2     0  1.7  49    44 0   GAUGGAAGC-==g===C-CAGGCGUCG\1"
1036            "DcdNodos\1" "  DcdNodos            2     0  1.7  50    45 0   UUAUGUAGC-==g==A=-GUAACCUAG\1"
1037            "VbhChole\1" "  VbhChole            2     0  1.7  55    50 0   GAGGAACUU-g===C==-GGGUGGCGA\1"
1038            "VbrFurni\1" "  VbrFurni            2     0  1.7  62    57 0   UUCGGGGGA-===G==g-GGCGGCGAG\1"
1039            "VblVulni\1" "  VblVulni            2     0  1.7  62    57 0   AGAAACUUG-=====Cg-GGUGGCGAG\1"
1040            "VbhChole\1" "  VbhChole            2     0  1.7  62    57 0   AGGAACUUG-==C===g-GGUGGCGAG\1"
1041            "ClnCorin\1" "  ClnCorin            2     0  2.2  49    44 0   GCGAUGAAG-==C===C-GGGAAUGGA\1"
1042            "CltBotul\1" "  CltBotul            2     0  2.2  49    44 0   GCGAUGAAG-C=====C-GGAAGUGGA\1"
1043            "CPPParap\1" "  CPPParap            2     0  2.2  49    44 0   GCGAUGAAG-==C===C-GGGAACGGA\1"
1044            "ClfPerfr\1" "  ClfPerfr            2     0  2.2  50    45 0   CGAUGAAGU-==C===C-GGGAAACGG\1"
1045            "VblVulni\1" "  VblVulni            2     0  2.2  52    47 0   ACAGAGAAA-C==G===-CUCGGGUGG\1"
1046            "BcSSSS00\1" "  BcSSSS00            2     0  2.2 179   165 0   CUGGAUCAC-C=C====-CU.\1"
1047            "ClfPerfr\1" "  ClfPerfr            2     0  2.2 179   165 0   UUAAUACCC-C=C====-CU.\1"
1048            "PbcAcet2\1" "  PbcAcet2            2     0  2.2 179   165 0   CUGGAUCAC-C=C====-NN.\1"
1049            "PbrPropi\1" "  PbrPropi            2     0  2.2 179   165 0   CUGGAUCAC-C=C====-NN.\1"
1050            "Stsssola\1" "  Stsssola            2     0  2.2 179   165 0   CUGGAUCAC-C=C====-.\1"
1051            "DcdNodos\1" "  DcdNodos            2     0  2.2 179   165 0   UUGGAUCAC-C=C====-.\1"
1052            "VbrFurni\1" "  VbrFurni            2     0  2.2 179   165 0   CUGGAUCAC-C=C====-.\1"
1053            "VblVulni\1" "  VblVulni            2     0  2.2 179   165 0   CUGGAUCAC-C=C====-.\1"
1054            "VbhChole\1" "  VbhChole            2     0  2.2 179   165 0   CUGGAUCAC-C=C====-.\1"
1055            "BcSSSS00\1" "  BcSSSS00            2     2  1.4 183   169 0   AUCACCUCC-=====..-\1"
1056            "ClfPerfr\1" "  ClfPerfr            2     2  1.4 183   169 0   UACCCCUCC-=====..-\1";
1057
1058        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1059        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
1060        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1061    }
1062    {
1063        const char *arguments[] = {
1064            "prgnamefake",
1065            "matchsequence=UCACCUCCUUUC", // contains no N
1066            NULL, // matchmismatches
1067            "matchacceptN=0",
1068        };
1069
1070        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
1071            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1" "";
1072
1073        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
1074            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
1075            "PbcAcet2\1" "  PbcAcet2            1     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
1076            "PbrPropi\1" "  PbrPropi            1     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
1077            "Stsssola\1" "  Stsssola            1     1  0.7 175   161 0   GCGGCUGGA-===========.-\1"
1078            "DcdNodos\1" "  DcdNodos            1     1  0.7 175   161 0   GCGGUUGGA-===========.-\1"
1079            "VbrFurni\1" "  VbrFurni            1     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
1080            "VblVulni\1" "  VblVulni            1     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
1081            "VbhChole\1" "  VbhChole            1     1  0.7 175   161 0   GGCGCUGGA-===========.-\1";
1082
1083        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
1084            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U.\1"
1085            "PbcAcet2\1" "  PbcAcet2            1     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
1086            "PbrPropi\1" "  PbrPropi            1     1  0.7 175   161 0   GCGGCUGGA-===========N-N.\1"
1087            "Stsssola\1" "  Stsssola            1     1  0.7 175   161 0   GCGGCUGGA-===========.-\1"
1088            "DcdNodos\1" "  DcdNodos            1     1  0.7 175   161 0   GCGGUUGGA-===========.-\1"
1089            "VbrFurni\1" "  VbrFurni            1     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
1090            "VblVulni\1" "  VblVulni            1     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
1091            "VbhChole\1" "  VbhChole            1     1  0.7 175   161 0   GGCGCUGGA-===========.-\1"
1092            "ClfPerfr\1" "  ClfPerfr            2     0  2.2 175   161 0   AAGAUUAAU-A=C=========-U.\1"
1093            "AclPleur\1" "  AclPleur            2     1  1.8 175   161 0   GCGGUUGGA-==========A.-\1"
1094            "PtVVVulg\1" "  PtVVVulg            2     1  1.8 175   161 0   GCGGUUGGA-==========A.-\1"
1095            "DlcTolu2\1" "  DlcTolu2            2     2  1.4 175   161 0   GCGGCUGGA-==========NN-N.\1"
1096            "FrhhPhil\1" "  FrhhPhil            2     2  1.4 175   161 0   GCGGCUGGA-==========..-\1"
1097            "HllHalod\1" "  HllHalod            2     2  1.4 175   161 0   GCGGCUGGA-==========..-\1"
1098            "CPPParap\1" "  CPPParap            2     2  1.4 176   162 0   GCGGNUGGA-==========..-\1";
1099       
1100        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1101        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
1102        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1103    }
1104    {
1105        const char *arguments[] = {
1106            "prgnamefake",
1107            "matchsequence=UCACCUCCUUUCU", // contains no N
1108            NULL, // matchmismatches
1109            "matchacceptN=0",
1110        };
1111
1112        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUCU'\1"
1113            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-=============-.\1";
1114
1115        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUCU'\1"
1116            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-=============-.\1"
1117            "ClfPerfr\1" "  ClfPerfr            2     0  2.2 175   161 0   AAGAUUAAU-A=C==========-.\1"
1118            "PbcAcet2\1" "  PbcAcet2            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1119            "PbrPropi\1" "  PbrPropi            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1120            "Stsssola\1" "  Stsssola            2     2  1.4 175   161 0   GCGGCUGGA-===========..-\1"
1121            "DcdNodos\1" "  DcdNodos            2     2  1.4 175   161 0   GCGGUUGGA-===========..-\1"
1122            "VbrFurni\1" "  VbrFurni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1123            "VblVulni\1" "  VblVulni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1124            "VbhChole\1" "  VbhChole            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1";
1125
1126        CCP expectd3 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUCU'\1"
1127            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-=============-.\1"
1128            "ClfPerfr\1" "  ClfPerfr            2     0  2.2 175   161 0   AAGAUUAAU-A=C==========-.\1"
1129            "PbcAcet2\1" "  PbcAcet2            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1130            "PbrPropi\1" "  PbrPropi            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1131            "Stsssola\1" "  Stsssola            2     2  1.4 175   161 0   GCGGCUGGA-===========..-\1"
1132            "DcdNodos\1" "  DcdNodos            2     2  1.4 175   161 0   GCGGUUGGA-===========..-\1"
1133            "VbrFurni\1" "  VbrFurni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1134            "VblVulni\1" "  VblVulni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1135            "VbhChole\1" "  VbhChole            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1136            "AclPleur\1" "  AclPleur            3     2  2.5 175   161 0   GCGGUUGGA-==========A..-\1"
1137            "PtVVVulg\1" "  PtVVVulg            3     2  2.5 175   161 0   GCGGUUGGA-==========A..-\1"
1138            "DlcTolu2\1" "  DlcTolu2            3     3  2.1 175   161 0   GCGGCUGGA-==========NNN-.\1"
1139            "FrhhPhil\1" "  FrhhPhil            3     3  2.1 175   161 0   GCGGCUGGA-==========...-\1"
1140            "HllHalod\1" "  HllHalod            3     3  2.1 175   161 0   GCGGCUGGA-==========...-\1"
1141            "CPPParap\1" "  CPPParap            3     3  2.1 176   162 0   GCGGNUGGA-==========...-\1";
1142
1143        CCP expectd4 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUCU'\1"
1144            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-=============-.\1"
1145            "ClfPerfr\1" "  ClfPerfr            2     0  2.2 175   161 0   AAGAUUAAU-A=C==========-.\1"
1146            "PbcAcet2\1" "  PbcAcet2            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1147            "PbrPropi\1" "  PbrPropi            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1148            "Stsssola\1" "  Stsssola            2     2  1.4 175   161 0   GCGGCUGGA-===========..-\1"
1149            "DcdNodos\1" "  DcdNodos            2     2  1.4 175   161 0   GCGGUUGGA-===========..-\1"
1150            "VbrFurni\1" "  VbrFurni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1151            "VblVulni\1" "  VblVulni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1152            "VbhChole\1" "  VbhChole            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1153            "AclPleur\1" "  AclPleur            3     2  2.5 175   161 0   GCGGUUGGA-==========A..-\1"
1154            "PtVVVulg\1" "  PtVVVulg            3     2  2.5 175   161 0   GCGGUUGGA-==========A..-\1"
1155            "DlcTolu2\1" "  DlcTolu2            3     3  2.1 175   161 0   GCGGCUGGA-==========NNN-.\1"
1156            "FrhhPhil\1" "  FrhhPhil            3     3  2.1 175   161 0   GCGGCUGGA-==========...-\1"
1157            "HllHalod\1" "  HllHalod            3     3  2.1 175   161 0   GCGGCUGGA-==========...-\1"
1158            "CPPParap\1" "  CPPParap            3     3  2.1 176   162 0   GCGGNUGGA-==========...-\1"
1159            "LgtLytic\1" "  LgtLytic            4     4  2.8 175   161 0   GCGGCUGGA-=========N...-\1"
1160            "PslFlave\1" "  PslFlave            4     4  2.8 175   161 0   GCGGCUGGA-=========....-\1";
1161
1162        CCP expectd5 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUCU'\1"
1163            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-=============-.\1"
1164            "ClfPerfr\1" "  ClfPerfr            2     0  2.2 175   161 0   AAGAUUAAU-A=C==========-.\1"
1165            "PbcAcet2\1" "  PbcAcet2            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1166            "PbrPropi\1" "  PbrPropi            2     2  1.4 175   161 0   GCGGCUGGA-===========NN-.\1"
1167            "Stsssola\1" "  Stsssola            2     2  1.4 175   161 0   GCGGCUGGA-===========..-\1"
1168            "DcdNodos\1" "  DcdNodos            2     2  1.4 175   161 0   GCGGUUGGA-===========..-\1"
1169            "VbrFurni\1" "  VbrFurni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1170            "VblVulni\1" "  VblVulni            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1171            "VbhChole\1" "  VbhChole            2     2  1.4 175   161 0   GGCGCUGGA-===========..-\1"
1172            "AclPleur\1" "  AclPleur            3     2  2.5 175   161 0   GCGGUUGGA-==========A..-\1"
1173            "PtVVVulg\1" "  PtVVVulg            3     2  2.5 175   161 0   GCGGUUGGA-==========A..-\1"
1174            "DlcTolu2\1" "  DlcTolu2            3     3  2.1 175   161 0   GCGGCUGGA-==========NNN-.\1"
1175            "FrhhPhil\1" "  FrhhPhil            3     3  2.1 175   161 0   GCGGCUGGA-==========...-\1"
1176            "HllHalod\1" "  HllHalod            3     3  2.1 175   161 0   GCGGCUGGA-==========...-\1"
1177            "CPPParap\1" "  CPPParap            3     3  2.1 176   162 0   GCGGNUGGA-==========...-\1"
1178            "LgtLytic\1" "  LgtLytic            4     4  2.8 175   161 0   GCGGCUGGA-=========N...-\1"
1179            "PslFlave\1" "  PslFlave            4     4  2.8 175   161 0   GCGGCUGGA-=========....-\1"
1180            "PtVVVulg\1" "  PtVVVulg            5     0  2.6  50    45 0   GGAGAAAGC-=ug=u=u===g==-GACGAGCGG\1"
1181            "AclPleur\1" "  AclPleur            5     0  3.5  46    41 0   ACGGGAAGG-gag=u=G======-UUGCCGACG\1"
1182            "PtVVVulg\1" "  PtVVVulg            5     0  4.0  45    40 0   ...AGGAGA-Aag=u=G======-UGCUGACGA\1"
1183            "VblVulni\1" "  VblVulni            5     0  4.3  48    43 0   CAGCACAGA-ga=a==uG=====-CGGGUGGCG\1";
1184
1185        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
1186        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1187        arguments[2] = "matchmismatches=3"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd3);
1188        arguments[2] = "matchmismatches=4"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd4);
1189        arguments[2] = "matchmismatches=5"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd5);
1190    }
1191
1192    // ----------------------------------
1193    //      accept several N-matches
1194
1195    {
1196        const char *arguments[] = {
1197            "prgnamefake",
1198            "matchsequence=CANCUCCUUNC", // contains 2 N
1199            NULL, // matchmismatches
1200            "matchacceptN=2",
1201            "matchlimitN=4",
1202        };
1203
1204        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUNC'\1"
1205            "BcSSSS00\1" "  BcSSSS00            0     2  1.7 176   162 0   CGGCUGGAU-==C======U=-U.\1";
1206
1207        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUNC'\1"
1208            "BcSSSS00\1" "  BcSSSS00            0     2  1.7 176   162 0   CGGCUGGAU-==C======U=-U.\1"
1209            "ClfPerfr\1" "  ClfPerfr            1     2  2.8 176   162 0   AGAUUAAUA-=CC======U=-U.\1"
1210            "DlcTolu2\1" "  DlcTolu2            1     3  2.4 176   162 0   CGGCUGGAU-==C=======N-N.\1"
1211            "FrhhPhil\1" "  FrhhPhil            1     3  2.4 176   162 0   CGGCUGGAU-==C======..-\1"
1212            "HllHalod\1" "  HllHalod            1     3  2.4 176   162 0   CGGCUGGAU-==C======..-\1"
1213            "CPPParap\1" "  CPPParap            1     3  2.4 177   163 0   CGGNUGGAU-==C======..-\1"
1214            "PbcAcet2\1" "  PbcAcet2            1     3  2.4 176   162 0   CGGCUGGAU-==C======UN-N.\1"
1215            "PbrPropi\1" "  PbrPropi            1     3  2.4 176   162 0   CGGCUGGAU-==C======UN-N.\1"
1216            "Stsssola\1" "  Stsssola            1     3  2.4 176   162 0   CGGCUGGAU-==C======U.-\1"
1217            "DcdNodos\1" "  DcdNodos            1     3  2.4 176   162 0   CGGUUGGAU-==C======U.-\1"
1218            "VbrFurni\1" "  VbrFurni            1     3  2.4 176   162 0   GCGCUGGAU-==C======U.-\1"
1219            "VblVulni\1" "  VblVulni            1     3  2.4 176   162 0   GCGCUGGAU-==C======U.-\1"
1220            "VbhChole\1" "  VbhChole            1     3  2.4 176   162 0   GCGCUGGAU-==C======U.-\1"
1221            "AclPleur\1" "  AclPleur            1     3  2.5 176   162 0   CGGUUGGAU-==C======A.-\1"
1222            "PtVVVulg\1" "  PtVVVulg            1     3  2.5 176   162 0   CGGUUGGAU-==C======A.-\1";
1223       
1224        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUNC'\1"
1225            "BcSSSS00\1" "  BcSSSS00            0     2  1.7 176   162 0   CGGCUGGAU-==C======U=-U.\1"
1226            "ClfPerfr\1" "  ClfPerfr            1     2  2.8 176   162 0   AGAUUAAUA-=CC======U=-U.\1"
1227            "DlcTolu2\1" "  DlcTolu2            1     3  2.4 176   162 0   CGGCUGGAU-==C=======N-N.\1"
1228            "FrhhPhil\1" "  FrhhPhil            1     3  2.4 176   162 0   CGGCUGGAU-==C======..-\1"
1229            "HllHalod\1" "  HllHalod            1     3  2.4 176   162 0   CGGCUGGAU-==C======..-\1"
1230            "CPPParap\1" "  CPPParap            1     3  2.4 177   163 0   CGGNUGGAU-==C======..-\1"
1231            "PbcAcet2\1" "  PbcAcet2            1     3  2.4 176   162 0   CGGCUGGAU-==C======UN-N.\1"
1232            "PbrPropi\1" "  PbrPropi            1     3  2.4 176   162 0   CGGCUGGAU-==C======UN-N.\1"
1233            "Stsssola\1" "  Stsssola            1     3  2.4 176   162 0   CGGCUGGAU-==C======U.-\1"
1234            "DcdNodos\1" "  DcdNodos            1     3  2.4 176   162 0   CGGUUGGAU-==C======U.-\1"
1235            "VbrFurni\1" "  VbrFurni            1     3  2.4 176   162 0   GCGCUGGAU-==C======U.-\1"
1236            "VblVulni\1" "  VblVulni            1     3  2.4 176   162 0   GCGCUGGAU-==C======U.-\1"
1237            "VbhChole\1" "  VbhChole            1     3  2.4 176   162 0   GCGCUGGAU-==C======U.-\1"
1238            "AclPleur\1" "  AclPleur            1     3  2.5 176   162 0   CGGUUGGAU-==C======A.-\1"
1239            "PtVVVulg\1" "  PtVVVulg            1     3  2.5 176   162 0   CGGUUGGAU-==C======A.-\1";
1240       
1241        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1242        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
1243        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1244    }
1245
1246    {
1247        const char *arguments[] = {
1248            "prgnamefake",
1249            "matchsequence=GAGCGGUCAG", // similar to a region where dots occur in seqdata
1250            NULL, // matchmismatches
1251            "matchacceptN=0",
1252            "matchlimitN=4",
1253        };
1254
1255        CCP expectd0 = "";
1256
1257        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'GAGCGGUCAG'\1"
1258            "BcSSSS00\1" "  BcSSSS00            1     0  1.1  25    21 0   GAUCAAGUC-======A===-AUGGGAGCU\1";
1259
1260        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'GAGCGGUCAG'\1"
1261            "BcSSSS00\1" "  BcSSSS00            1     0  1.1  25    21 0   GAUCAAGUC-======A===-AUGGGAGCU\1"
1262            "Bl0LLL00\1" "  Bl0LLL00            2     0  2.2  25    21 0   GAUCAAGUC-======A=C=-ACGGGAGCU\1";
1263
1264        CCP expectd3 = "    name---- fullname mis N_mis wmis pos ecoli rev          'GAGCGGUCAG'\1"
1265            "BcSSSS00\1" "  BcSSSS00            1     0  1.1  25    21 0   GAUCAAGUC-======A===-AUGGGAGCU\1"
1266            "Bl0LLL00\1" "  Bl0LLL00            2     0  2.2  25    21 0   GAUCAAGUC-======A=C=-ACGGGAGCU\1"
1267            "VbrFurni\1" "  VbrFurni            3     0  2.4  68    60 0   GGAUUUGUU-=g====CG==-CGGCGGACG\1"
1268            "FrhhPhil\1" "  FrhhPhil            3     0  2.8  82    70 0   ACGAGUGGC-=gA===C===-UUGGAAACG\1"
1269            "ClfPerfr\1" "  ClfPerfr            3     0  3.2  86    74 0   CGGCGGGAC-=g==CU====-AACCUGCGG\1"
1270            "HllHalod\1" "  HllHalod            3     0  3.6  25    21 0   GAUCAAGUC-======Aa=C-GAUGGAAGC\1"
1271            "DlcTolu2\1" "  DlcTolu2            3     0  3.6  95    83 0   GGACUGCCC-==Aa==A===-CUAAUACCG\1"
1272            "FrhhPhil\1" "  FrhhPhil            3     0  4.0  25    21 0   GAUCAAGUC-==A====a=C-AGGUCUUCG\1"
1273            "AclPleur\1" "  AclPleur            3     0  4.0  29    24 0   GAUCAAGUC-==A====a=C-GGGAAGGGA\1"
1274            "ClnCorin\1" "  ClnCorin            3     0  4.1  25    21 0   GAUCAAGUC-=====A=G=A-GUUCCUUCG\1"
1275            "CltBotul\1" "  CltBotul            3     0  4.1  25    21 0   .AUCAAGUC-=====A=G=A-GCUUCUUCG\1"
1276            "CPPParap\1" "  CPPParap            3     0  4.1  25    21 0   GAUCAAGUC-=====A=G=A-GUUCCUUCG\1"
1277            "ClfPerfr\1" "  ClfPerfr            3     0  4.1  25    21 0   GAUCAAGUC-=====A=G=A-GUUUCCUUC\1"
1278            "DlcTolu2\1" "  DlcTolu2            3     0  4.1 157   143 0   GUAGCCGUU-===GAA====-CGGCUGGAU\1"
1279            "PslFlave\1" "  PslFlave            3     3  2.4  25    21 0   GAUCAAGUC-=======...-<more>\1"
1280            "PtVVVulg\1" "  PtVVVulg            3     3  2.4  29    24 0   GAUCAAGUC-=======...-<more>\1";
1281
1282        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1283        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
1284        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1285        arguments[2] = "matchmismatches=3"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd3);
1286    }
1287
1288    {
1289        const char *arguments[] = {
1290            "prgnamefake",
1291            "matchsequence=GAGCGGUCAGGAG", // as above, but continues behind '...'
1292            NULL, // matchmismatches
1293            "matchweighted=1",            // use weighted mismatches
1294        };
1295
1296        CCP expectd2 = "";
1297        CCP expectd3 = "    name---- fullname mis N_mis wmis pos ecoli rev          'GAGCGGUCAGGAG'\1"
1298            "ClnCorin\1" "  ClnCorin            6     0  3.4  77    66 0   AUGGAUUAG-Cg====A=g==CC-UUUCGAAAG\1"
1299            "CltBotul\1" "  CltBotul            6     0  3.4  77    66 0   GUGGAUUAG-Cg====A=g==CC-UUUCGAAAG\1"
1300            "CPPParap\1" "  CPPParap            6     0  3.4  77    66 0   ACGGAUUAG-Cg====A=g==CC-UUCCGAAAG\1"
1301            "BcSSSS00\1" "  BcSSSS00            3     0  3.4  25    21 0   GAUCAAGUC-======A===AU=-GGAGCUUGC\1";
1302
1303        CCP expectd4 = "    name---- fullname mis N_mis wmis pos ecoli rev          'GAGCGGUCAGGAG'\1"
1304            "ClnCorin\1" "  ClnCorin            6     0  3.4  77    66 0   AUGGAUUAG-Cg====A=g==CC-UUUCGAAAG\1"
1305            "CltBotul\1" "  CltBotul            6     0  3.4  77    66 0   GUGGAUUAG-Cg====A=g==CC-UUUCGAAAG\1"
1306            "CPPParap\1" "  CPPParap            6     0  3.4  77    66 0   ACGGAUUAG-Cg====A=g==CC-UUCCGAAAG\1"
1307            "BcSSSS00\1" "  BcSSSS00            3     0  3.4  25    21 0   GAUCAAGUC-======A===AU=-GGAGCUUGC\1"
1308            "ClfPerfr\1" "  ClfPerfr            6     0  3.9 121   108 0   AUCAUAAUG-C====A=ug==gU-GAAGUCGUA\1"
1309            "ClnCorin\1" "  ClnCorin            6     0  3.9 122   109 0   CGCAUAAGA-C====A=ug==gU-GAAGUCGUA\1"
1310            "CltBotul\1" "  CltBotul            6     0  3.9 122   109 0   CUCAUAAGA-C====A=ug==gU-GAAGUCGUA\1"
1311            "CPPParap\1" "  CPPParap            6     0  3.9 122   109 0   GCAUAAGAU-C====A=ug==gU-AAGUCGUAA\1"
1312            "DcdNodos\1" "  DcdNodos            6     0  4.2  77    66 0   GUAACCUAG-Ug====A=g=AC=-UAUGGAAAC\1"
1313            "PsAAAA00\1" "  PsAAAA00            6     0  4.2  77    66 0   UGGAUUCAG-Cg====A=g=AC=-UCCGGAAAC\1"
1314            "PslFlave\1" "  PslFlave            6     0  4.2  77    66 0   CUGAUUCAG-Cg====A=g=AC=-UUUCGAAAG\1"
1315            "FrhhPhil\1" "  FrhhPhil            5     0  4.2 149   135 0   UAACAAUGG-U===C==ag===A-CCUGCGGCU\1"
1316            "AclPleur\1" "  AclPleur            4     0  4.3  29    24 0   GAUCAAGUC-==A====a=C=g=-AAGGGAGCU\1"
1317            "PbcAcet2\1" "  PbcAcet2            6     0  4.3 149   135 0   GUAACAAGG-U===C==ag==gA-ACCUGCGGC\1"
1318            "PbrPropi\1" "  PbrPropi            6     0  4.3 149   135 0   GUAACAAGG-U===C==ag==gA-ACCUGCGGC\1"
1319            "Stsssola\1" "  Stsssola            6     0  4.3 149   135 0   GUAACAAGG-U===C==ag==gA-ACCUGCGGC\1"
1320            "LgtLytic\1" "  LgtLytic            6     0  4.3 149   135 0   GUAACAAGG-U===C==ag==gA-ACCUGCGGC\1"
1321            "PslFlave\1" "  PslFlave            6     0  4.3 149   135 0   GUAACAAGG-U===C==ag==gA-ACCUGCGGC\1"
1322            "HllHalod\1" "  HllHalod            6     0  4.3 149   135 0   GUAACAAGG-U===C==ag==gA-ACCUGCGGC\1"
1323            "VbrFurni\1" "  VbrFurni            5     0  4.4  68    60 0   GGAUUUGUU-=g====CG==Cg=-CGGACGGAC\1"
1324            "AclPleur\1" "  AclPleur            6     0  4.4  35    30 0   GUCGAACGG-U=A===ga===gA-GCUUGCUUU\1"
1325            "PslFlave\1" "  PslFlave            6     6  4.4  25    21 0   GAUCAAGUC-=======......-<more>\1"
1326            "PtVVVulg\1" "  PtVVVulg            6     6  4.4  29    24 0   GAUCAAGUC-=======......-<more>\1"
1327            "VbrFurni\1" "  VbrFurni            6     0  4.4 149   135 0   GUAACAAGG-U====C=ag==gA-ACCUGGCGC\1"
1328            "VblVulni\1" "  VblVulni            6     0  4.4 149   135 0   GUAACAAGG-U====C=ag==gA-ACCUGGCGC\1"
1329            "VbhChole\1" "  VbhChole            6     0  4.4 149   135 0   GUAACAAGG-U====C=ag==gA-ACCUGGCGC\1";
1330
1331        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1332        arguments[2] = "matchmismatches=3"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd3);
1333        arguments[2] = "matchmismatches=4"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd4);
1334    }
1335
1336    // --------------------------
1337    //      truncate results
1338
1339    {
1340        const char *arguments[] = {
1341            "prgnamefake",
1342            "matchsequence=CANCNCNNUNC", // contains 5N
1343            NULL, // matchmismatches
1344            "matchacceptN=5",
1345            "matchlimitN=7",
1346            "matchmaxresults=5",
1347        };
1348
1349        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCNCNNUNC'\1"
1350            "BcSSSS00\1" "  BcSSSS00            0     5  4.2 176   162 0   CGGCUGGAU-==C=U=CU=U=-U.\1";
1351
1352        // many hits are truncated here:
1353        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCNCNNUNC'\1"
1354            "DlcTolu2\1" "  DlcTolu2            1     6  4.9 176   162 0   CGGCUGGAU-==C=U=CU==N-N.\1"
1355            "FrhhPhil\1" "  FrhhPhil            1     6  4.9 176   162 0   CGGCUGGAU-==C=U=CU=..-\1"
1356            "HllHalod\1" "  HllHalod            1     6  4.9 176   162 0   CGGCUGGAU-==C=U=CU=..-\1"
1357            "CPPParap\1" "  CPPParap            1     6  4.9 177   163 0   CGGNUGGAU-==C=U=CU=..-\1"
1358            "AclPleur\1" "  AclPleur            1     6  5.0 176   162 0   CGGUUGGAU-==C=U=CU=A.-\1";
1359
1360        // many hits are truncated here:
1361        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCNCNNUNC'\1"
1362            "HllHalod\1" "  HllHalod            2     5  5.1  45    40 0   AAACGAUGG-a=G=UuGC=U=-CAGGCGUCG\1"
1363            "VblVulni\1" "  VblVulni            2     5  5.4  49    44 0   AGCACAGAG-a=A=UuGU=U=-UCGGGUGGC\1"
1364            "VbrFurni\1" "  VbrFurni            2     5  5.7  40    35 0   CGGCAGCGA-==A=AuUGAA=-CUUCGGGGG\1"
1365            "LgtLytic\1" "  LgtLytic            2     5  6.2 101    89 0   GGGGAAACU-==AGCuAA=A=-CGCAUAAUC\1"
1366            "ClfPerfr\1" "  ClfPerfr            2     5  6.5 172   158 0   AGGAAGAUU-a=UaC=CC=C=-UUUCU.\1";
1367
1368        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1369        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
1370        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
1371    }
1372
1373    // -------------------------------------------------------------
1374    //      tests related to http://bugs.arb-home.de/ticket/410
1375    {
1376        const char *arguments[] = {
1377            "prgnamefake",
1378            "matchsequence=ACGGACUCCGGGAAACCGGGGCUAAUACC", // length=29
1379            NULL, // matchmismatches
1380            "matchacceptN=5",
1381            "matchlimitN=7",
1382            "matchmaxresults=10",
1383        };
1384
1385        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'ACGGACUCCGGGAAACCGGGGCUAAUACC'\1"
1386            "BcSSSS00\1" "  BcSSSS00            0     0  0.0  84    72 0   UAGCGGCGG-=============================-GGAUGGUGA\1"
1387            "Bl0LLL00\1" "  Bl0LLL00            0     0  0.0  84    72 0   CAGCGGCGG-=============================-GGAUGCUGA\1"
1388            "AclPleur\1" "  AclPleur            4     0  4.6  84    72 0   GAGUGGCGG-=======a========u=UA=========-GCGUAAUCA\1"
1389            "PtVVVulg\1" "  PtVVVulg            4     0  5.1  84    72 0   GAGCGGCGG-=======a=U======G=U==========-GCAUGACCA\1"
1390            "DsssDesu\1" "  DsssDesu            5     0  5.3  84    72 0   GAGUGGCGC-========u=C====Gu==A=========-GGAUACAGA\1"
1391            "PsAAAA00\1" "  PsAAAA00            5     0  5.3  84    72 0   CAGCGGCGG-======gu=C======G==C=========-GCAUACGCA\1";
1392
1393        arguments[2] = "matchmismatches=5"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1394    }
1395    {
1396        const char *arguments[] = {
1397            "prgnamefake",
1398            "matchsequence=ACGGACUCCGGGAAACCGGGGCUAAUACCGGAUGGUGA", // length=38
1399            NULL, // matchmismatches
1400            "matchacceptN=5",
1401            "matchlimitN=7",
1402            "matchmaxresults=10",
1403        };
1404
1405        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'ACGGACUCCGGGAAACCGGGGCUAAUACCGGAUGGUGA'\1"
1406            "BcSSSS00\1" "  BcSSSS00            0     0  0.0  84    72 0   UAGCGGCGG-======================================-UGAUUGGGG\1"
1407            "Bl0LLL00\1" "  Bl0LLL00            1     0  1.5  84    72 0   CAGCGGCGG-==================================C===-UGAUUGGGG\1";
1408
1409        arguments[2] = "matchmismatches=18"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
1410    }
1411}
1412
1413static char *extract_locations(const char *probe_design_result) {
1414    const char *Target = strstr(probe_design_result, "\nTarget");
1415    if (Target) {
1416        const char *designed = strchr(Target+7, '\n');
1417        if (designed) {
1418            ++designed;
1419
1420            GBS_strstruct result(300);
1421            RegExpr reg_designed("^[A-Z]+"
1422                                 "[[:space:]]+[0-9]+"
1423                                 "[[:space:]]+([A-Z][=+-])" // subexpr #1 (loc+-=)
1424                                 "[[:space:]]*([0-9]+)",    // subexpr #2 (abs or locrel)
1425                                 true);
1426
1427
1428            while (designed) {
1429                const char     *eol   = strchr(designed, '\n');
1430                const RegMatch *match = reg_designed.match(designed); if (!match) break;
1431
1432                match           = reg_designed.subexpr_match(1); if (!match) break;
1433                std::string loc = match->extract(designed);
1434
1435                match           = reg_designed.subexpr_match(2); if (!match) break;
1436                std::string pos = match->extract(designed);
1437
1438                result.cat(loc.c_str());
1439                result.cat(pos.c_str());
1440
1441                designed = eol ? eol+1 : NULL;
1442            }
1443
1444            return result.release();
1445        }
1446    }
1447    return strdup("can't extract");
1448}
1449
1450inline const char *next_line(const char *this_line) {
1451    const char *lf = strchr(this_line, '\n');
1452    return (lf && lf[1] && strchr("ACGTU", lf[1])) ? lf+1 : NULL;
1453}
1454inline int count_hits(const char *design_result) {
1455    const char *target = strstr(design_result, "\nTarget");
1456    if (target) {
1457        const char *hit  = next_line(target+1);
1458        int         hits = 0;
1459
1460        while (hit) {
1461            ++hits;
1462            hit = next_line(hit);
1463        }
1464        return hits;
1465    }
1466    return -1;
1467}
1468
1469void TEST_SLOW_design_probe() {
1470    // test here runs versus database ../UNIT_TESTER/run/TEST_pt_src.arb
1471
1472    bool use_gene_ptserver = false;
1473    {
1474        int hits_len_18;
1475        {
1476            const char *arguments[] = {
1477                "prgnamefake",
1478                "designnames=ClnCorin#CltBotul#CPPParap#ClfPerfr",
1479                "designmintargets=100",
1480            };
1481            const char *expected =
1482                "Probe design parameters:\n"
1483                "Length of probe    18\n"
1484                "Temperature        [ 0.0 -400.0]\n"
1485                "GC-content         [30.0 - 80.0]\n"
1486                "E.Coli position    [any]\n"
1487                "Max. nongroup hits 0\n"
1488                "Min. group hits    100% (max. rejected coverage: 75%)\n"
1489                "Target             le apos ecol qual grps   G+C temp     Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1490                "CGAAAGGAAGAUUAAUAC 18 A=94   82   77    4  33.3 48.0 GUAUUAAUCUUCCUUUCG | - - - - - - - - - - - - - - - - - - - -\n"
1491                "GAAAGGAAGAUUAAUACC 18 A+ 1   83   77    4  33.3 48.0 GGUAUUAAUCUUCCUUUC | - - - - - - - - - - - - - - - - - - - -\n"
1492                "UCAAGUCGAGCGAUGAAG 18 B=18   17   61    4  50.0 54.0 CUUCAUCGCUCGACUUGA | - - - - - - - - - - - - - - - 2 2 2 2 2\n"
1493                "AUCAAGUCGAGCGAUGAA 18 B- 1   16   45    4  44.4 52.0 UUCAUCGCUCGACUUGAU | - - - - - - - - - - - 2 2 2 2 2 2 2 2 2\n";
1494
1495            TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1496            hits_len_18 = count_hits(expected);
1497            TEST_EXPECT_EQUAL(hits_len_18, 4);
1498
1499            // test extraction of positions:
1500            {
1501                char *positions = extract_locations(expected);
1502                TEST_EXPECT_EQUAL(positions, "A=94A+1B=18B-1");
1503                free(positions);
1504            }
1505        }
1506        // same as above with probelength 17
1507        int hits_len_17;
1508        {
1509            const char *arguments[] = {
1510                "prgnamefake",
1511                "designnames=ClnCorin#CltBotul#CPPParap#ClfPerfr",
1512                "designmintargets=100",
1513                "designprobelength=17",
1514            };
1515            const char *expected =
1516                "Probe design parameters:\n"
1517                "Length of probe    17\n"
1518                "Temperature        [ 0.0 -400.0]\n"
1519                "GC-content         [30.0 - 80.0]\n"
1520                "E.Coli position    [any]\n"
1521                "Max. nongroup hits 0\n"
1522                "Min. group hits    100% (max. rejected coverage: 75%)\n"
1523                "Target            le apos ecol qual grps   G+C temp    Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1524                "CAAGUCGAGCGAUGAAG 17 A=19   18   65    4  52.9 52.0 CUUCAUCGCUCGACUUG | - - - - - - - - - - - - - - - - 2 2 2 2\n"
1525                "UCAAGUCGAGCGAUGAA 17 A- 1   17   49    4  47.1 50.0 UUCAUCGCUCGACUUGA | - - - - - - - - - - - - 2 2 2 2 2 2 2 2\n"
1526                "AUCAAGUCGAGCGAUGA 17 A- 2   16   33    4  47.1 50.0 UCAUCGCUCGACUUGAU | - - - - - - - - 2 2 2 2 2 2 2 2 2 2 2 4\n";
1527
1528            TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1529            hits_len_17 = count_hits(expected);
1530            TEST_EXPECT_EQUAL(hits_len_17, 3);
1531        }
1532        // same as above with probelength 16
1533        int hits_len_16;
1534        {
1535            const char *arguments[] = {
1536                "prgnamefake",
1537                "designnames=ClnCorin#CltBotul#CPPParap#ClfPerfr",
1538                "designmintargets=100",
1539                "designprobelength=16",
1540            };
1541            const char *expected =
1542                "Probe design parameters:\n"
1543                "Length of probe    16\n"
1544                "Temperature        [ 0.0 -400.0]\n"
1545                "GC-content         [30.0 - 80.0]\n"
1546                "E.Coli position    [any]\n"
1547                "Max. nongroup hits 0\n"
1548                "Min. group hits    100% (max. rejected coverage: 75%)\n"
1549                "Target           le apos ecol qual grps   G+C temp   Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1550                "CGAAAGGAAGAUUAAU 16 A=94   82   77    4  31.2 42.0 AUUAAUCUUCCUUUCG | - - - - - - - - - - - - - - - - - - - -\n"
1551                "AAGGAAGAUUAAUACC 16 A+ 3   85   77    4  31.2 42.0 GGUAUUAAUCUUCCUU | - - - - - - - - - - - - - - - - - - - -\n"
1552                "AAGUCGAGCGAUGAAG 16 B=20   19   69    4  50.0 48.0 CUUCAUCGCUCGACUU | - - - - - - - - - - - - - - - - - 2 2 2\n"
1553                "CAAGUCGAGCGAUGAA 16 B- 1   18   49    4  50.0 48.0 UUCAUCGCUCGACUUG | - - - - - - - - - - - - 2 2 2 2 2 2 2 2\n"
1554                "UCAAGUCGAGCGAUGA 16 B- 2   17   37    4  50.0 48.0 UCAUCGCUCGACUUGA | - - - - - - - - - 2 2 2 2 2 2 2 2 2 2 2\n"
1555                "AUCAAGUCGAGCGAUG 16 B- 3   16   21    4  50.0 48.0 CAUCGCUCGACUUGAU | - - - - - 2 2 2 2 2 2 2 2 2 2 2 2 9 9 9\n";
1556
1557            TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1558            hits_len_16 = count_hits(expected);
1559            TEST_EXPECT_EQUAL(hits_len_16, 6);
1560        }
1561        // combine the 3 preceeding designs
1562        int combined_hits;
1563        {
1564            const char *arguments[] = {
1565                "prgnamefake",
1566                "designnames=ClnCorin#CltBotul#CPPParap#ClfPerfr",
1567                "designmintargets=100",
1568                "designprobelength=16",
1569                "designmaxprobelength=18",
1570            };
1571            const char *expected =
1572                "Probe design parameters:\n"
1573                "Length of probe    16-18\n"
1574                "Temperature        [ 0.0 -400.0]\n"
1575                "GC-content         [30.0 - 80.0]\n"
1576                "E.Coli position    [any]\n"
1577                "Max. nongroup hits 0\n"
1578                "Min. group hits    100% (max. rejected coverage: 75%)\n"
1579                "Target             le apos ecol qual grps   G+C temp     Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1580                "CGAAAGGAAGAUUAAU   16 A=94   82   77    4  31.2 42.0   AUUAAUCUUCCUUUCG | - - - - - - - - - - - - - - - - - - - -\n"
1581                "CGAAAGGAAGAUUAAUAC 18 A+ 0   82   77    4  33.3 48.0 GUAUUAAUCUUCCUUUCG | - - - - - - - - - - - - - - - - - - - -\n"
1582                "GAAAGGAAGAUUAAUACC 18 A+ 1   83   77    4  33.3 48.0 GGUAUUAAUCUUCCUUUC | - - - - - - - - - - - - - - - - - - - -\n"
1583                "AAGGAAGAUUAAUACC   16 A+ 3   85   77    4  31.2 42.0   GGUAUUAAUCUUCCUU | - - - - - - - - - - - - - - - - - - - -\n"
1584                "AAGUCGAGCGAUGAAG   16 B=20   19   69    4  50.0 48.0   CUUCAUCGCUCGACUU | - - - - - - - - - - - - - - - - - 2 2 2\n"
1585                "CAAGUCGAGCGAUGAAG  17 B- 1   18   65    4  52.9 52.0  CUUCAUCGCUCGACUUG | - - - - - - - - - - - - - - - - 2 2 2 2\n"
1586                "UCAAGUCGAGCGAUGAAG 18 B- 2   17   61    4  50.0 54.0 CUUCAUCGCUCGACUUGA | - - - - - - - - - - - - - - - 2 2 2 2 2\n"
1587                "UCAAGUCGAGCGAUGAA  17 B- 2   17   49    4  47.1 50.0  UUCAUCGCUCGACUUGA | - - - - - - - - - - - - 2 2 2 2 2 2 2 2\n"
1588                "CAAGUCGAGCGAUGAA   16 B- 1   18   49    4  50.0 48.0   UUCAUCGCUCGACUUG | - - - - - - - - - - - - 2 2 2 2 2 2 2 2\n"
1589                "AUCAAGUCGAGCGAUGAA 18 B- 3   16   45    4  44.4 52.0 UUCAUCGCUCGACUUGAU | - - - - - - - - - - - 2 2 2 2 2 2 2 2 2\n"
1590                "UCAAGUCGAGCGAUGA   16 B- 2   17   37    4  50.0 48.0   UCAUCGCUCGACUUGA | - - - - - - - - - 2 2 2 2 2 2 2 2 2 2 2\n"
1591                "AUCAAGUCGAGCGAUGA  17 B- 3   16   33    4  47.1 50.0  UCAUCGCUCGACUUGAU | - - - - - - - - 2 2 2 2 2 2 2 2 2 2 2 4\n"
1592                "AUCAAGUCGAGCGAUG   16 B- 3   16   21    4  50.0 48.0   CAUCGCUCGACUUGAU | - - - - - 2 2 2 2 2 2 2 2 2 2 2 2 9 9 9\n";
1593
1594            TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1595            combined_hits = count_hits(expected);
1596        }
1597
1598        // check that combined design reports all probes reported by single designs:
1599        TEST_EXPECT_EQUAL(combined_hits, hits_len_16+hits_len_17+hits_len_18);
1600    }
1601    // test vs bug (fails with [8988] .. [9175])
1602    {
1603        const char *arguments[] = {
1604            "prgnamefake",
1605            "designnames=VbhChole#VblVulni",
1606            "designmintargets=50", // hit at least 1 of the 2 targets
1607            "designmingc=60", "designmaxgc=75", // specific GC range
1608        };
1609
1610        const char *expected =
1611            "Probe design parameters:\n"
1612            "Length of probe    18\n"
1613            "Temperature        [ 0.0 -400.0]\n"
1614            "GC-content         [60.0 - 75.0]\n"
1615            "E.Coli position    [any]\n"
1616            "Max. nongroup hits 0 (lowest rejected nongroup hits: 1)\n"
1617            "Min. group hits    50%\n"
1618            "Target             le apos ecol qual grps   G+C temp     Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1619            "AGUCGAGCGGCAGCACAG 18 A=21   20   39    2  66.7 60.0 CUGUGCUGCCGCUCGACU | - - - - - - - - - - - - - - - - - - - -\n"
1620            "GUCGAGCGGCAGCACAGA 18 A+ 1   21   39    2  66.7 60.0 UCUGUGCUGCCGCUCGAC | - - - - - - - - - - - - - - - - - - - -\n"
1621            "UCGAGCGGCAGCACAGAG 18 A+ 2   21   39    2  66.7 60.0 CUCUGUGCUGCCGCUCGA | - - - - - - - - - - - - - - - - - - - -\n"
1622            "AAGUCGAGCGGCAGCACA 18 A- 1   19   25    2  61.1 58.0 UGUGCUGCCGCUCGACUU | - - - - - - - - - - - - 1 1 1 1 1 1 1 1\n"
1623            "CGAGCGGCAGCACAGAGA 18 A+ 3   21   20    1  66.7 60.0 UCUCUGUGCUGCCGCUCG | - - - - - - - - - - - - - - - - - - - -\n"
1624            "CGAGCGGCAGCACAGAGG 18 A+ 3   21   20    1  72.2 62.0 CCUCUGUGCUGCCGCUCG | - - - - - - - - - - - - - - - - - - - -\n"
1625            "GAGCGGCAGCACAGAGAA 18 A+ 4   21   20    1  61.1 58.0 UUCUCUGUGCUGCCGCUC | - - - - - - - - - - - - - - - - - - - -\n"
1626            "GAGCGGCAGCACAGAGGA 18 A+ 4   21   20    1  66.7 60.0 UCCUCUGUGCUGCCGCUC | - - - - - - - - - - - - - - - - - - - -\n"
1627            "AGCGGCAGCACAGAGGAA 18 A+ 5   21   20    1  61.1 58.0 UUCCUCUGUGCUGCCGCU | - - - - - - - - - - - - - - - - - - - -\n"
1628            "GCGGCAGCACAGAGAAAC 18 A+ 6   22   20    1  61.1 58.0 GUUUCUCUGUGCUGCCGC | - - - - - - - - - - - - - - - - - - - -\n"
1629            "GCGGCAGCACAGAGGAAC 18 A+ 6   22   20    1  66.7 60.0 GUUCCUCUGUGCUGCCGC | - - - - - - - - - - - - - - - - - - - -\n"
1630            "CGGCAGCACAGAGGAACU 18 A+ 7   23   20    1  61.1 58.0 AGUUCCUCUGUGCUGCCG | - - - - - - - - - - - - - - - - - - - -\n"
1631            "CUUGUUCCUUGGGUGGCG 18 B=52   47   20    1  61.1 58.0 CGCCACCCAAGGAACAAG | - - - - - - - - - - - - - - - - - - - -\n"
1632            "CUUGUUUCUCGGGUGGCG 18 B+ 0   47   20    1  61.1 58.0 CGCCACCCGAGAAACAAG | - - - - - - - - - - - - - - - - - - - -\n"
1633            "UGUUCCUUGGGUGGCGAG 18 B+ 2   49   20    1  61.1 58.0 CUCGCCACCCAAGGAACA | - - - - - - - - - - - - - - - - - - - -\n"
1634            "UGUUUCUCGGGUGGCGAG 18 B+ 2   49   20    1  61.1 58.0 CUCGCCACCCGAGAAACA | - - - - - - - - - - - - - - - - - - - -\n"
1635            "GUUCCUUGGGUGGCGAGC 18 B+ 3   50   20    1  66.7 60.0 GCUCGCCACCCAAGGAAC | - - - - - - - - - - - - - - - - - - - -\n"
1636            "GUUUCUCGGGUGGCGAGC 18 B+ 3   50   20    1  66.7 60.0 GCUCGCCACCCGAGAAAC | - - - - - - - - - - - - - - - - - - - -\n"
1637            "UUCCUUGGGUGGCGAGCG 18 B+10   57   20    1  66.7 60.0 CGCUCGCCACCCAAGGAA | - - - - - - - - - - - - - - - - - - - -\n"
1638            "UUUCUCGGGUGGCGAGCG 18 B+10   57   20    1  66.7 60.0 CGCUCGCCACCCGAGAAA | - - - - - - - - - - - - - - - - - - - -\n"
1639            "UCCUUGGGUGGCGAGCGG 18 B+11   58   20    1  72.2 62.0 CCGCUCGCCACCCAAGGA | - - - - - - - - - - - - - - - - - - - -\n"
1640            "UUCUCGGGUGGCGAGCGG 18 B+11   58   20    1  72.2 62.0 CCGCUCGCCACCCGAGAA | - - - - - - - - - - - - - - - - - - - -\n"
1641            "CAAGUCGAGCGGCAGCAC 18 A- 2   18   13    2  66.7 60.0 GUGCUGCCGCUCGACUUG | - - - - - - 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n"
1642            "UCAAGUCGAGCGGCAGCA 18 A- 3   17    3    2  61.1 58.0 UGCUGCCGCUCGACUUGA | - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3\n";
1643
1644        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1645    }
1646
1647    // design MANY probes to test location specifier
1648    {
1649        const char *arguments_loc[] = {
1650            "prgnamefake",
1651            // "designnames=Stsssola#Stsssola", // @@@ crashes the ptserver
1652            "designnames=CPPParap#PsAAAA00",
1653            "designmintargets=50", // hit at least 1 of the 2 targets
1654            "designmingc=0", "designmaxgc=100", // allow all GCs
1655            "designmintemp=30", "designmaxtemp=100", // allow all temp above 30 deg
1656            "designmishit=7",  // allow enough outgroup hits
1657            "designprobelength=9",
1658        };
1659
1660        const char *expected_loc =
1661            "A=29B=51B+1C=99A+8D=112E=80E+2E+3E+4B-1A-5B-6B-5F=124F+1B-2E-7B+0C-5E+2E-1D-1E+6E+7E+8G=89C-2A-1H=61A-6C-1C-3E+3B+3B+4B+5E+5C+1E+4E+6E+7E+8C-7C-6E+5H+1H+2E-6C-4I=152I+1A-7";
1662
1663        TEST_ARB_PROBE_FILT(ARRAY_ELEMS(arguments_loc), arguments_loc, extract_locations, expected_loc);
1664    }
1665
1666    // same as above
1667    {
1668        const char *arguments[] = {
1669            "prgnamefake",
1670            "designnames=CPPParap#PsAAAA00",
1671            "designmintargets=50", // hit at least 1 of the 2 targets
1672            "designmingc=0", "designmaxgc=100", // allow all GCs
1673            "designmintemp=30", "designmaxtemp=100", // allow all temp above 30 deg
1674            "designmishit=7",  // allow enough outgroup hits
1675            "designprobelength=9",
1676        };
1677
1678        const char *expected =
1679            "Probe design parameters:\n"
1680            "Length of probe    9\n"
1681            "Temperature        [30.0 -100.0]\n"
1682            "GC-content         [ 0.0 -100.0]\n"
1683            "E.Coli position    [any]\n"
1684            "Max. nongroup hits 7 (lowest rejected nongroup hits: 9)\n"
1685            "Min. group hits    50%\n"
1686            "Target    le  apos ecol qual grps   G+C temp     Probe | Decrease T by n*.3C -> probe matches n non group species\n"
1687            "GAGCGGAUG  9 A= 29   24   20    1  66.7 30.0 CAUCCGCUC | - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n"
1688            "UGCUCCUGG  9 B= 51   46   20    1  66.7 30.0 CCAGGAGCA | - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n"
1689            "GCUCCUGGA  9 B+  1   47   20    1  66.7 30.0 UCCAGGAGC | - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n"
1690            "CGGGCGCUA  9 C= 99   87   20    1  77.8 32.0 UAGCGCCCG | - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n"
1691            "GAAGGGAGC  9 A+  8   32   20    1  66.7 30.0 GCUCCCUUC | 1 1  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  2  2\n"
1692            "CGCAUACGC  9 D=112  100   20    1  66.7 30.0 GCGUAUGCG | 2 2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2\n"
1693            "CGGACGGGC  9 E= 80   69   20    1  88.9 34.0 GCCCGUCCG | 2 2  2  2  2  2  2  2  2  2  2  2  2  2  3  3  3  3  3  3\n"
1694            "GGACGGGCC  9 E+  2   70   20    1  88.9 34.0 GGCCCGUCC | 3 3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3\n"
1695            "GACGGGCCU  9 E+  3   71   20    1  77.8 32.0 AGGCCCGUC | 3 3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3\n"
1696            "ACGGGCCUU  9 E+  4   72   20    1  66.7 30.0 AAGGCCCGU | 3 3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3\n"
1697            "UCCUUCGGG  9 B-  1   45   20    1  66.7 30.0 CCCGAAGGA | 2 2  2  2  2  2  2  2  2  2  2  2  3  4  4  4  4  4  4  4\n"
1698            "CGAGCGAUG  9 A-  5   21   20    1  66.7 30.0 CAUCGCUCG | 3 3  3  3  3  3  3  3  3  3  5  5  5  5  5  5  5  5  5  5\n"
1699            "GGGAGCUUG  9 B-  6   40   20    1  66.7 30.0 CAAGCUCCC | 4 4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  5  5\n"
1700            "GGAGCUUGC  9 B-  5   41   20    1  66.7 30.0 GCAAGCUCC | 4 4  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5\n"
1701            "GCGAUUGGG  9 F=124  111   20    1  66.7 30.0 CCCAAUCGC | 3 3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  6  6\n"
1702            "CGAUUGGGG  9 F+  1  112   20    1  66.7 30.0 CCCCAAUCG | 3 3  3  3  3  3  6  6  6  6  6  6  6  6  6  6  6  6  6  6\n"
1703            "GCUUGCUCC  9 B-  2   44   20    1  66.7 30.0 GGAGCAAGC | 4 4  4  4  4  4  5  5  5  5  5  5  5  7  7  7  7  8  8  8\n"
1704            "UUAGCGGCG  9 E-  7   62   19    1  66.7 30.0 CGCCGCUAA | 4 4  4  4  4  4  4  4  5  5  5  5  5  5  5  6  6  6 11 11\n"
1705            "CCUUCGGGA  9 B+  0   46   18    1  66.7 30.0 UCCCGAAGG | 2 2  3  3  3  3  4  4  4  4  4  4  4  4  4  4  4  5  5 13\n"
1706            "GGAAACGGG  9 C-  5   82   17    1  66.7 30.0 CCCGUUUCC | - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  3  3  3  3\n"
1707            "GGACGGACG  9 E+  2   70   17    1  77.8 32.0 CGUCCGUCC | 2 2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 10 10 14 14\n"
1708            "GCGGACGGG  9 E-  1   68   17    1  88.9 34.0 CCCGUCCGC | 2 2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 13 13 13 13\n"
1709            "CCGCAUACG  9 D-  1   99   16    1  66.7 30.0 CGUAUGCGG | 2 2  2  2  2  2  2  2  2  2  2  4  4  4  4  5  5  5  5  5\n"
1710            "GGACGUCCG  9 E+  6   74   14    1  77.8 32.0 CGGACGUCC | - -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  3  3  3\n"
1711            "GACGUCCGG  9 E+  7   75   14    1  77.8 32.0 CCGGACGUC | - -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  2  2 14\n"
1712            "ACGUCCGGA  9 E+  8   76   14    1  66.7 30.0 UCCGGACGU | - -  -  -  -  -  -  -  -  -  -  -  -  1  1 11 11 12 12 17\n"
1713            "CGUCCGGAA  9 G= 89   77   14    1  66.7 30.0 UUCCGGACG | - -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  2  2  2\n"
1714            "AACGGGCGC  9 C-  2   85   14    1  77.8 32.0 GCGCCCGUU | - -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  1  1  2\n"
1715            "CGAGCGGAU  9 A-  1   23   13    1  66.7 30.0 AUCCGCUCG | - -  -  -  -  -  -  -  -  -  -  -  3  3  3  3  3  3  3  3\n"
1716            "UUCAGCGGC  9 H= 61   56   13    1  66.7 30.0 GCCGCUGAA | 1 1  1  1  1  1  2  2  2  2  2  2  3  4  4  4  4  4  7  7\n"
1717            "UCGAGCGGA  9 A-  6   21   13    1  66.7 30.0 UCCGCUCGA | 3 3  3  3  3  3  3  3  3  3  3  3  8  8  8  8  8  8  8  8\n"
1718            "ACGGGCGCU  9 C-  1   86   12    1  77.8 32.0 AGCGCCCGU | - -  -  -  -  -  -  -  -  -  -  1  1  1  1  1  1  2  2  2\n"
1719            "AAACGGGCG  9 C-  3   84    9    1  66.7 30.0 CGCCCGUUU | - -  -  -  -  -  -  -  1  1  1  1  1  1  1  1  1  1  1  1\n"
1720            "GACGGACGU  9 E+  3   71    9    1  66.7 30.0 ACGUCCGUC | 2 2  2  2  2  2  2  2 13 13 13 13 13 13 13 14 14 14 14 14\n"
1721            "UCGGGAACG  9 B+  3   49    7    1  66.7 30.0 CGUUCCCGA | - -  -  -  -  -  1  1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1722            "CGGGAACGG  9 B+  4   50    7    1  77.8 32.0 CCGUUCCCG | - -  -  -  -  -  1  1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1723            "GGGAACGGA  9 B+  5   51    7    1  66.7 30.0 UCCGUUCCC | - -  -  -  -  -  1  1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1724            "CGGACGUCC  9 E+  5   73    7    1  77.8 32.0 GGACGUCCG | - -  -  -  -  -  1  1  1  1  1  1  1  3  3  3  3 12 12 12\n"
1725            "GGGCGCUAA  9 C+  1   88    7    1  66.7 30.0 UUAGCGCCC | - -  -  -  -  -  1  1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1726            "ACGGACGUC  9 E+  4   72    7    1  66.7 30.0 GACGUCCGU | - -  -  -  -  -  2  2  3  3  3  4  4  4  4  5  5  5  5 13\n"
1727            "GGGCCUUCC  9 E+  6   74    7    1  77.8 32.0 GGAAGGCCC | - -  -  -  -  -  2  2  2  2  2  3  3  3  3  3  3  3  3  4\n"
1728            "GGCCUUCCG  9 E+  7   75    7    1  77.8 32.0 CGGAAGGCC | - -  -  -  -  -  2  2  2  2  2  3  3  3  3  3  3  3  3  3\n"
1729            "GCCUUCCGA  9 E+  8   76    7    1  66.7 30.0 UCGGAAGGC | - -  -  -  -  -  2  2  2  2  2  3  3  3  3  3  3  3  3  3\n"
1730            "CCGGAAACG  9 C-  7   80    7    1  66.7 30.0 CGUUUCCGG | - -  -  -  -  -  2  2  2  2  2  2  2  6  7  9  9 10 10 10\n"
1731            "CGGAAACGG  9 C-  6   81    7    1  66.7 30.0 CCGUUUCCG | - -  -  -  -  -  2  2  4  4  4  4  4  4  5  5  6  6  6  6\n"
1732            "CGGGCCUUC  9 E+  5   73    7    1  77.8 32.0 GAAGGCCCG | 1 1  1  1  1  1  3  3  3  3  3  3  3  3  3  3  3  3  3  3\n"
1733            "UCAGCGGCG  9 H+  1   57    7    1  77.8 32.0 CGCCGCUGA | 2 2  2  2  2  2  6  6  6  6  6  6  6  6  6  6  7  7  7  7\n"
1734            "CAGCGGCGG  9 H+  2   58    7    1  88.9 34.0 CCGCCGCUG | 2 2  2  2  2  2  6  6  6  6  6  6  6  7 12 12 12 12 12 12\n"
1735            "UAGCGGCGG  9 E-  6   63    7    1  77.8 32.0 CCGCCGCUA | 4 4  4  4  4  4 10 10 10 10 10 10 12 14 14 14 14 14 14 14\n"
1736            "GAAACGGGC  9 C-  4   83    5    1  66.7 30.0 GCCCGUUUC | - -  -  -  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1737            "GCCGUAGGA  9 I=152  138    3    1  66.7 30.0 UCCUACGGC | 1 1  8  8  8  8  8  8  8  8  8  8  9  9  9  9  9  9 12 12\n"
1738            "CCGUAGGAG  9 I+  1  139    3    1  66.7 30.0 CUCCUACGG | 1 1 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11\n"
1739            "GUCGAGCGA  9 A-  7   21    3    1  66.7 30.0 UCGCUCGAC | 3 3 11 11 11 11 11 11 11 11 11 11 11 11 11 12 12 12 12 14\n";
1740
1741        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1742    }
1743
1744    // same as above (with probelen == 8)
1745    {
1746        const char *arguments[] = {
1747            "prgnamefake",
1748            "designnames=CPPParap#PsAAAA00",
1749            "designmintargets=50", // hit at least 1 of the 2 targets
1750            "designmingc=0", "designmaxgc=100", // allow all GCs
1751            "designmintemp=30", "designmaxtemp=100", // allow all temp above 30 deg
1752            // "designmishit=7",
1753            "designmishit=15", // @@@ reports more results than with 7 mishits, but no mishits reported below!
1754            "designprobelength=8",
1755        };
1756
1757        const char *expected =
1758            "Probe design parameters:\n"
1759            "Length of probe    8\n"
1760            "Temperature        [30.0 -100.0]\n"
1761            "GC-content         [ 0.0 -100.0]\n"
1762            "E.Coli position    [any]\n"
1763            "Max. nongroup hits 15\n"
1764            "Min. group hits    50%\n"
1765            "Target   le apos ecol qual grps   G+C temp    Probe | Decrease T by n*.3C -> probe matches n non group species\n"
1766            "GGCGGACG  8 A=78   67   39    2  87.5 30.0 CGUCCGCC | 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13\n"
1767            "GCGGACGG  8 A+ 1   68   39    2  87.5 30.0 CCGUCCGC | 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13\n"
1768            "AGCGGCGG  8 A- 3   64   39    2  87.5 30.0 CCGCCGCU | 11 11 11 11 11 11 11 14 14 14 14 14 14 14 14 14 14 14 14 14\n"
1769            "GCGGCGGA  8 A- 2   65   39    2  87.5 30.0 UCCGCCGC | 10 10 11 11 11 11 11 14 14 14 14 14 14 14 14 14 14 14 14 14\n"
1770            "CGGCGGAC  8 A- 1   66   39    2  87.5 30.0 GUCCGCCG | 10 10 10 10 10 10 10 13 13 13 13 13 13 13 14 14 14 14 14 14\n"
1771            "CGGACGGG  8 A+ 2   69   20    1  87.5 30.0 CCCGUCCG |  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2\n"
1772            "GGACGGGC  8 A+ 4   70   20    1  87.5 30.0 GCCCGUCC |  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3\n"
1773            "GACGGGCC  8 A+ 5   71   20    1  87.5 30.0 GGCCCGUC |  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3\n"
1774#if defined(ARB_64)
1775            "ACGGGCGC  8 B=98   86   13    1  87.5 30.0 GCGCCCGU |  -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  1  1  1  1\n"
1776            "CGGGCGCU  8 B+ 1   87   13    1  87.5 30.0 AGCGCCCG |  -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  1  1  1  1\n"
1777            "CAGCGGCG  8 C=63   58    8    1  87.5 30.0 CGCCGCUG |  2  2  2  2  2  2  2  6  6  6  6  6  6  6  8  8  8  8  8  8\n";
1778#else // !defined(ARB_64)
1779        // @@@ 32bit version differs (possibly numeric issues?)
1780            "ACGGGCGC  8 B=98   86   13    1  87.5 30.0 GCGCCCGU |  -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  1  1  1  2\n"
1781            "CGGGCGCU  8 B+ 1   87   13    1  87.5 30.0 AGCGCCCG |  -  -  -  -  -  -  -  -  -  -  -  -  1  1  1  1  1  1  1  2\n"
1782            "CAGCGGCG  8 C=63   58    8    1  87.5 30.0 CGCCGCUG |  2  2  2  2  2  2  2  6  6  6  6  6  6  6  8  8  8  8  8 10\n";
1783#endif
1784
1785        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1786    }
1787
1788    // same as above (but restricting ecoli-range)
1789    {
1790        const char *arguments[] = {
1791            "prgnamefake",
1792            "designnames=CPPParap#PsAAAA00",
1793            "designmintargets=50", // hit at least 1 of the 2 targets
1794            "designmingc=0", "designmaxgc=100", // allow all GCs
1795            "designmintemp=30", "designmaxtemp=100", // allow all temp above 30 deg
1796            "designmishit=15",
1797            "designprobelength=8",
1798            "designminpos=65", "designmaxpos=69", // restrict ecoli-range
1799        };
1800
1801        const char *expected =
1802            "Probe design parameters:\n"
1803            "Length of probe    8\n"
1804            "Temperature        [30.0 -100.0]\n"
1805            "GC-content         [ 0.0 -100.0]\n"
1806            "E.Coli position    [  65 -   69]\n"
1807            "Max. nongroup hits 15\n"
1808            "Min. group hits    50%\n"
1809            "Target   le apos ecol qual grps   G+C temp    Probe | Decrease T by n*.3C -> probe matches n non group species\n"
1810            "GGCGGACG  8 A=78   67   39    2  87.5 30.0 CGUCCGCC | 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13\n"
1811            "GCGGACGG  8 A+ 1   68   39    2  87.5 30.0 CCGUCCGC | 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13\n"
1812            "GCGGCGGA  8 A- 2   65   39    2  87.5 30.0 UCCGCCGC | 10 10 11 11 11 11 11 14 14 14 14 14 14 14 14 14 14 14 14 14\n"
1813            "CGGCGGAC  8 A- 1   66   39    2  87.5 30.0 GUCCGCCG | 10 10 10 10 10 10 10 13 13 13 13 13 13 13 14 14 14 14 14 14\n"
1814            "CGGACGGG  8 A+ 2   69   20    1  87.5 30.0 CCCGUCCG |  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2\n";
1815
1816        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1817    }
1818
1819    {
1820        const char *arguments[] = {
1821            "prgnamefake",
1822            "designnames=ClnCorin#CPPParap#ClfPerfr",
1823            "designprobelength=16",
1824            "designmintargets=100",
1825            "designmishit=2",
1826        };
1827        const char *expected =
1828            "Probe design parameters:\n"
1829            "Length of probe    16\n"
1830            "Temperature        [ 0.0 -400.0]\n"
1831            "GC-content         [30.0 - 80.0]\n"
1832            "E.Coli position    [any]\n"
1833            "Max. nongroup hits 2 (lowest rejected nongroup hits: 6)\n"
1834            "Min. group hits    100% (max. rejected coverage: 67%)\n"
1835            "Target           le apos ecol qual grps   G+C temp   Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1836            "CGAAAGGAAGAUUAAU 16 A=94   82   58    3  31.2 42.0 AUUAAUCUUCCUUUCG | 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1837            "AAGGAAGAUUAAUACC 16 A+ 3   85   58    3  31.2 42.0 GGUAUUAAUCUUCCUU | 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1838            "AAGUCGAGCGAUGAAG 16 B=20   19   52    3  50.0 48.0 CUUCAUCGCUCGACUU | 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  3  3  3\n"
1839            "CAAGUCGAGCGAUGAA 16 B- 1   18   37    3  50.0 48.0 UUCAUCGCUCGACUUG | 1 1 1 1 1 1 1 1  1  1  1  1  3  3  3  3  3  3  3  3\n"
1840            "GUCGAGCGAUGAAGUU 16 B+ 2   21   31    3  50.0 48.0 AACUUCAUCGCUCGAC | - - - - - - - -  -  -  1  1  1  1  1  1  1  1  1  1\n"
1841            "UCAAGUCGAGCGAUGA 16 B- 2   17   28    3  50.0 48.0 UCAUCGCUCGACUUGA | 1 1 1 1 1 1 1 1  1  3  3  3  3  3  3  3  3  3  3  3\n"
1842            "AGUCGAGCGAUGAAGU 16 B+ 1   20   19    3  50.0 48.0 ACUUCAUCGCUCGACU | - - - - - - 1 1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1843            "AUCAAGUCGAGCGAUG 16 B- 3   16   16    3  50.0 48.0 CAUCGCUCGACUUGAU | 1 1 1 1 1 3 3 3  3  3  3  3  3  3  3  3  3 10 10 10\n"
1844            "GAUCAAGUCGAGCGAU 16 B- 4   15    4    3  50.0 48.0 AUCGCUCGACUUGAUC | - 2 2 2 3 3 3 3 10 10 10 10 10 10 10 10 10 10 10 10\n"
1845            "UGAUCAAGUCGAGCGA 16 B- 5   14    4    3  50.0 48.0 UCGCUCGACUUGAUCA | - 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10\n";
1846
1847        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1848    }
1849    // test same design as above, but add 2 "unknown species" each of which is missing one of the previously designed probes
1850    {
1851        const char *arguments[] = {
1852            "prgnamefake",
1853            "designnames=ClnCorin#Unknown1#CPPParap#ClfPerfr#Unknown2",
1854            "designprobelength=16",
1855            "designmintargets=100",
1856            "designmishit=2",
1857            // pass sequences for the unknown species
1858            "designsequence=---CGAAAGGAAGAUUAAU------------------AAGUCGAGCGAUGAAG-CAAGUCGAGCGAUGAA-GUCGAGCGAUGAAGUU-UCAAGUCGAGCGAUGA-AGUCGAGCGAUGAAGU-AUCAAGUCGAGCGAUG-GAUCAAGUCGAGCGAU-UGAUCAAGUCGAGCGA",
1859            "designsequence=---CGAAAGGAAGAUUAAU-AAGGAAGAUUAAUACC-AAGUCGAGCGAUGAAG-CAAGUCGAGCGAUGAA-GUCGAGCGAUGAAGUU-UCAAGUCGAGCGAUGA-AGUCGAGCGAUGAAGU-AUCAAGUCGAGCGAUG------------------UGAUCAAGUCGAGCGA",
1860        };
1861        const char *expected =
1862            "Probe design parameters:\n"
1863            "Length of probe    16\n"
1864            "Temperature        [ 0.0 -400.0]\n"
1865            "GC-content         [30.0 - 80.0]\n"
1866            "E.Coli position    [any]\n"
1867            "Max. nongroup hits 2\n"
1868            "Min. group hits    100% (max. rejected coverage: 80%)\n"
1869            "Target           le apos ecol qual grps   G+C temp   Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1870            "CGAAAGGAAGAUUAAU 16 A=94   82   96    5  31.2 42.0 AUUAAUCUUCCUUUCG | 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1871            // AAGGAAGAUUAAUACC is not designed here
1872            "AAGUCGAGCGAUGAAG 16 B=20   19   86    5  50.0 48.0 CUUCAUCGCUCGACUU | 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  3  3  3\n"
1873            "CAAGUCGAGCGAUGAA 16 B- 1   18   61    5  50.0 48.0 UUCAUCGCUCGACUUG | 1 1 1 1 1 1 1 1  1  1  1  1  3  3  3  3  3  3  3  3\n"
1874            "GUCGAGCGAUGAAGUU 16 B+ 2   21   51    5  50.0 48.0 AACUUCAUCGCUCGAC | - - - - - - - -  -  -  1  1  1  1  1  1  1  1  1  1\n"
1875            "UCAAGUCGAGCGAUGA 16 B- 2   17   46    5  50.0 48.0 UCAUCGCUCGACUUGA | 1 1 1 1 1 1 1 1  1  3  3  3  3  3  3  3  3  3  3  3\n"
1876            "AGUCGAGCGAUGAAGU 16 B+ 1   20   31    5  50.0 48.0 ACUUCAUCGCUCGACU | - - - - - - 1 1  1  1  1  1  1  1  1  1  1  1  1  1\n"
1877            "AUCAAGUCGAGCGAUG 16 B- 3   16   26    5  50.0 48.0 CAUCGCUCGACUUGAU | 1 1 1 1 1 3 3 3  3  3  3  3  3  3  3  3  3 10 10 10\n"
1878            // GAUCAAGUCGAGCGAU is not designed here
1879            "UGAUCAAGUCGAGCGA 16 B- 5   14    6    5  50.0 48.0 UCGCUCGACUUGAUCA | - 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10\n";
1880
1881        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1882    }
1883    {
1884        const char *arguments[] = {
1885            "prgnamefake",
1886            "designnames=VbrFurni",
1887            "designprobelength=8",
1888            "designmingc=80",
1889            "designmaxgc=100",
1890        };
1891        const char *expected =
1892            "Probe design parameters:\n"
1893            "Length of probe    8\n"
1894            "Temperature        [ 0.0 -400.0]\n"
1895            "GC-content         [80.0 -100.0]\n"
1896            "E.Coli position    [any]\n"
1897            "Max. nongroup hits 0 (lowest rejected nongroup hits: 2)\n"
1898            "Min. group hits    50%\n"
1899            "Target   le apos ecol qual grps   G+C temp    Probe | Decrease T by n*.3C -> probe matches n non group species\n"
1900#if defined(ARB_64)
1901            "CGGCAGCG  8 A=28   23   20    1  87.5 30.0 CGCUGCCG | - - - - - - - - - - - - - - - - - - - -\n"
1902#else // !defined(ARB_64)
1903            "CGGCAGCG  8 A=28   23   20    1  87.5 30.0 CGCUGCCG | - - - - - - - - - - - - - - - - - - - 3\n"
1904#endif
1905            "UGGGCGGC  8 B=67   60    8    1  87.5 30.0 GCCGCCCA | - - - - - - - 1 1 1 1 1 1 1 1 1 1 1 1 1\n"
1906#if defined(ARB_64)
1907            "CGGCGAGC  8 B+ 4   60    8    1  87.5 30.0 GCUCGCCG | - - - - - - - 2 2 2 2 2 2 2 4 4 4 4 4 4\n"
1908#else // !defined(ARB_64)
1909            "CGGCGAGC  8 B+ 4   60    8    1  87.5 30.0 GCUCGCCG | - - - - - - - 2 2 2 2 2 2 2 4 4 4 4 4 5\n"
1910#endif
1911            "GGGCGGCG  8 B+ 1   60    8    1 100.0 32.0 CGCCGCCC | - - - - - - - 3 3 3 3 3 3 3 3 3 3 3 3 3\n"
1912            "GGCGGCGA  8 B+ 2   60    8    1  87.5 30.0 UCGCCGCC | - - - - - - - 3 3 3 3 3 3 3 3 3 3 3 3 3\n"
1913            "GCGGCGAG  8 B+ 3   60    3    1  87.5 30.0 CUCGCCGC | - - 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4\n";
1914
1915        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1916    }
1917    {
1918        const char *arguments[] = {
1919            "prgnamefake",
1920            "designnames=HllHalod#VbhChole#VblVulni#VbrFurni#PtVVVulg",
1921            "designprobelength=14",
1922            "designmintargets=100",
1923            "designmishit=4",
1924            "designmingc=70",
1925            "designmaxgc=100",
1926        };
1927        const char *expected =
1928            "Probe design parameters:\n"
1929            "Length of probe    14\n"
1930            "Temperature        [ 0.0 -400.0]\n"
1931            "GC-content         [70.0 -100.0]\n"
1932            "E.Coli position    [any]\n"
1933            "Max. nongroup hits 4\n"
1934            "Min. group hits    100% (max. rejected coverage: 80%)\n"
1935            "Target         le apos ecol qual grps   G+C temp Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n"
1936            "GAGCGGCGGACGGA 14 A=75   64   21    5  78.6 50.0 UCCGUCCGCCGCUC | - - - - 1 1 1 1 1 1 5 5 9 9 10 10 10 10 10 10\n"
1937            "CGAGCGGCGGACGG 14 A- 1   63   21    5  85.7 52.0 CCGUCCGCCGCUCG | - - - - 2 2 2 2 2 2 2 2 2 2  2  2  2  2  9  9\n"
1938            "AGCGGCGGACGGAC 14 A+ 0   64   21    5  78.6 50.0 GUCCGUCCGCCGCU | 4 7 7 7 9 9 9 9 9 9 9 9 9 9  9  9  9 10 10 10\n";
1939
1940        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1941    }
1942    {
1943        const char *arguments[] = {
1944            "prgnamefake",
1945            "designnames=HllHalod#VbhChole#VblVulni#VbrFurni#PtVVVulg",
1946            "designprobelength=14",
1947            "designmintargets=100",
1948            "designmishit=0",
1949            "designmingc=51",
1950            "designmaxgc=60",
1951        };
1952        const char *expected = ""; // no probes found!
1953
1954        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
1955    }
1956
1957}
1958
1959void TEST_SLOW_probe_design_errors() {
1960    // test here runs versus database ../UNIT_TESTER/run/TEST_pt_src.arb
1961
1962    bool use_gene_ptserver = false;
1963    {
1964        const char *arguments[] = {
1965            "prgnamefake",
1966            "designnames=CPPParap#PsAAAA00",
1967            "designprobelength=3",
1968        };
1969        const char *expected_error = "Specified min. probe length 3 is below the min. allowed probe length of 8";
1970
1971        TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
1972    }
1973    {
1974        const char *arguments[] = {
1975            "prgnamefake",
1976            "designnames=CPPParap#PsAAAA00",
1977            "designprobelength=15",
1978            "designmaxprobelength=12",
1979        };
1980        const char *expected_error = "Max. probe length 12 is below the specified min. probe length of 15";
1981
1982        TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
1983    }
1984    {
1985        const char *expected_error = "Sequence contains only 0 bp. Impossible design request for one of the added sequences";
1986        {
1987            const char *arguments[] = {
1988                "prgnamefake",
1989                "designsequence=", // pass an empty sequence
1990                "designprobelength=16",
1991            };
1992            TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
1993        }
1994        {
1995            const char *arguments[] = {
1996                "prgnamefake",
1997                "designsequence=-------------", // pass a gap-only sequence
1998                "designprobelength=16",
1999            };
2000            TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
2001        }
2002    }
2003    {
2004        const char *arguments[] = {
2005            "prgnamefake",
2006            "designsequence=ACGTACGTACGTACGT", // pass a long enough (unexpected) sequence
2007            "designprobelength=16",
2008        };
2009        const char *expected_error = "Got 0 unknown marked species, but 1 custom sequence was added (has to match)";
2010        TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
2011    }
2012    {
2013        const char *arguments[] = {
2014            "prgnamefake",
2015            "designnames=Unknown", // one unknown species
2016            "designprobelength=16",
2017        };
2018        const char *expected_error = "No species marked - no probes designed";
2019        TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
2020    }
2021    {
2022        const char *arguments[] = {
2023            "prgnamefake",
2024            "designnames=Unknown#CPPParap", // one unknown species, one known species
2025            "designprobelength=16",
2026        };
2027        const char *expected_error = "Got 1 unknown marked species, but 0 custom sequences were added (has to match)";
2028        TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
2029    }
2030    {
2031        const char *expected_error = "Sequence contains only 0 bp. Impossible design request for one of the added sequences";
2032        {
2033            const char *arguments[] = {
2034                "prgnamefake",
2035                "designnames=Unknown", // one unknown species
2036                "designsequence=", // pass an empty sequence
2037                "designprobelength=16",
2038            };
2039            TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
2040        }
2041        {
2042            const char *arguments[] = {
2043                "prgnamefake",
2044                "designnames=Unknown", // one unknown species
2045                "designsequence=-------------", // pass a gap-only sequence
2046                "designprobelength=16",
2047            };
2048            TEST_ARB_PROBE__REPORTS_ERROR(ARRAY_ELEMS(arguments), arguments, expected_error);
2049        }
2050    }
2051}
2052
2053void TEST_SLOW_match_designed_probe() {
2054    // test here runs versus database ../UNIT_TESTER/run/TEST_pt_src.arb
2055
2056    bool use_gene_ptserver = false;
2057    const char *arguments[] = {
2058        "prgnamefake",
2059        "matchsequence=UCAAGUCGAGCGAUGAAG",
2060    };
2061    CCP expected = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCAAGUCGAGCGAUGAAG'\1"
2062        "ClnCorin\1" "  ClnCorin            0     0  0.0  18    17 0   .GAGUUUGA-==================-UUCCUUCGG\1"
2063        "CltBotul\1" "  CltBotul            0     0  0.0  18    17 0   ........A-==================-CUUCUUCGG\1"
2064        "CPPParap\1" "  CPPParap            0     0  0.0  18    17 0   AGAGUUUGA-==================-UUCCUUCGG\1"
2065        "ClfPerfr\1" "  ClfPerfr            0     0  0.0  18    17 0   AGAGUUUGA-==================-UUUCCUUCG\1";
2066
2067    TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
2068}
2069
2070void TEST_SLOW_get_existing_probes() {
2071    // test here runs versus database ../UNIT_TESTER/run/TEST_pt_src.arb
2072
2073    bool use_gene_ptserver = false;
2074    {
2075        const char *arguments[] = {
2076            "prgnamefake",
2077            "iterate=20",
2078            "iterate_amount=10",
2079        };
2080        CCP expected =
2081            "AAACCGGGGCTAATACCGGA;AAACGACTGTTAATACCGCA;AAACGATGGAAGCTTGCTTC;AAACGATGGCTAATACCGCA;AAACGGATTAGCGGCGGGAC;"
2082            "AAACGGGCGCTAATACCGCA;AAACGGTCGCTAATACCGGA;AAACGGTGGCTAATACCGCA;AAACGTACGCTAATACCGCA;AAACTCAAGCTAATACCGCA";
2083
2084        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
2085    }
2086    {
2087        const char *arguments[] = {
2088            "prgnamefake",
2089            "iterate=15",
2090            "iterate_amount=20",
2091            "iterate_separator=:",
2092        };
2093        CCP expected =
2094            "AAACCGGGGCTAATA:AAACGACTGTTAATA:AAACGATGGAAGCTT:AAACGATGGCTAATA:AAACGGATTAGCGGC:AAACGGGCGCTAATA:AAACGGTCGCTAATA:"
2095            "AAACGGTGGCTAATA:AAACGTACGCTAATA:AAACTCAAGCTAATA:AAACTCAGGCTAATA:AAACTGGAGAGTTTG:AAACTGTAGCTAATA:AAACTTGTTTCTCGG:"
2096            "AAAGAGGTGCTAATA:AAAGCTTGCTTTCTT:AAAGGAACGCTAATA:AAAGGAAGATTAATA:AAAGGACAGCTAATA:AAAGGGACTTCGGTC";
2097
2098        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
2099    }
2100    {
2101        const char *arguments[] = {
2102            "prgnamefake",
2103            "iterate=10",
2104            "iterate_amount=5",
2105            "iterate_readable=0",
2106        };
2107        CCP expected =
2108            "\2\2\2\3\3\4\4\4\4\3;\2\2\2\3\4\2\3\5\4\5;\2\2\2\3\4\2\5\4\4\2;\2\2\2\3\4\2\5\4\4\3;\2\2\2\3\4\4\2\5\5\2";
2109
2110        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
2111    }
2112    {
2113        const char *arguments[] = {
2114            "prgnamefake",
2115            "iterate=3",
2116            "iterate_amount=70",
2117            "iterate_tu=U",
2118        };
2119        CCP expected =
2120            "AAA;AAC;AAG;AAU;ACA;ACC;ACG;ACU;AGA;AGC;AGG;AGU;AUA;AUC;AUG;AUU;"
2121            "CAA;CAC;CAG;CAU;CCA;CCC;CCG;CCU;CGA;CGC;CGG;CGU;CUA;CUC;CUG;CUU;"
2122            "GAA;GAC;GAG;GAU;GCA;GCC;GCG;GCU;GGA;GGC;GGG;GGU;GUA;GUC;GUG;GUU;"
2123            "UAA;UAC;UAG;UAU;UCA;UCC;UCG;UCU;UGA;UGC;UGG;UGU;UUA;UUC;UUG;UUU";
2124
2125        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
2126    }
2127    {
2128        const char *arguments[] = {
2129            "prgnamefake",
2130            "iterate=2",
2131            "iterate_amount=20",
2132        };
2133        CCP expected =
2134            "AA;AC;AG;AT;"
2135            "CA;CC;CG;CT;"
2136            "GA;GC;GG;GT;"
2137            "TA;TC;TG;TT";
2138
2139        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
2140    }
2141}
2142
2143// #define TEST_AUTO_UPDATE // uncomment to auto-update expected index dumps
2144
2145void TEST_SLOW_index_dump() {
2146    for (int use_gene_ptserver = 0; use_gene_ptserver <= 1; use_gene_ptserver++) {
2147        const char *dumpfile     = use_gene_ptserver ? "index_gpt.dump" : "index_pt.dump";
2148        char       *dumpfile_exp = GBS_global_string_copy("%s.expected", dumpfile);
2149
2150        const char *arguments[] = {
2151            "prgnamefake",
2152            GBS_global_string_copy("dump=%s", dumpfile),
2153        };
2154        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, "ok");
2155
2156#if defined(TEST_AUTO_UPDATE)
2157        TEST_COPY_FILE(dumpfile, dumpfile_exp);
2158#else // !defined(TEST_AUTO_UPDATE)
2159        TEST_EXPECT_TEXTFILES_EQUAL(dumpfile_exp, dumpfile);
2160#endif
2161        TEST_EXPECT_ZERO_OR_SHOW_ERRNO(unlink(dumpfile));
2162
2163        free((char*)arguments[1]);
2164        free(dumpfile_exp);
2165    }
2166}
2167
2168#undef TEST_AUTO_UPDATE
2169
2170// --------------------------------------------------------------------------------
2171
2172#include <arb_strarray.h>
2173#include <set>
2174#include <iterator>
2175
2176using namespace std;
2177
2178typedef set<string> Matches;
2179
2180inline void parseMatches(char*& answer, Matches& matches) {
2181    ConstStrArray match_results;
2182
2183    GBT_splitNdestroy_string(match_results, answer, "\1", false);
2184
2185    for (size_t i = 1; i<match_results.size(); i += 2) {
2186        if (match_results[i][0]) {
2187            matches.insert(match_results[i]);
2188        }
2189    }
2190}
2191
2192inline void getMatches(const char *probe, Matches& matches) {
2193    bool  use_gene_ptserver = false;
2194    char *matchseq          = GBS_global_string_copy("matchsequence=%s", probe);
2195    const char *arguments[] = {
2196        "prgnamefake",
2197        matchseq,
2198    };
2199    TEST_RUN_ARB_PROBE(ARRAY_ELEMS(arguments), arguments);
2200    parseMatches(answer, matches);
2201    free(matchseq);
2202}
2203
2204inline string matches2hitlist(const Matches& matches) {
2205    string hitlist;
2206    if (!matches.empty()) {
2207        for (Matches::const_iterator m = matches.begin(); m != matches.end(); ++m) {
2208            hitlist = hitlist + ',' + *m;
2209        }
2210        hitlist = hitlist.substr(1);
2211    }
2212    return hitlist;
2213}
2214
2215inline void extract_first_but_not_second(const Matches& first, const Matches& second, Matches& result) {
2216    set_difference(first.begin(), first.end(),
2217                   second.begin(), second.end(),
2218                   inserter(result, result.begin()));
2219}
2220
2221// --------------------------------------------------------------------------------
2222
2223// #define TEST_INDEX_COMPLETENESS // only uncomment temporarily (slow as hell)
2224
2225#if defined(TEST_INDEX_COMPLETENESS)
2226
2227void TEST_SLOW_find_unmatched_probes() {
2228    bool use_gene_ptserver = false;
2229
2230    // get all 20mers indexed in ptserver:
2231    ConstStrArray fullProbes;
2232    {
2233        const char *arguments[] = {
2234            "prgnamefake",
2235            "iterate=20",
2236            "iterate_amount=1000000",
2237            "iterate_tu=U",
2238        };
2239        TEST_RUN_ARB_PROBE(ARRAY_ELEMS(arguments), arguments);
2240
2241        GBT_splitNdestroy_string(fullProbes, answer, ";", false);
2242        TEST_EXPECT_EQUAL(fullProbes.size(), 2040);
2243    }
2244
2245    for (size_t lp = 0; lp<fullProbes.size(); ++lp) { // with all 20mers existing in ptserver
2246        const char *fullProbe = fullProbes[lp];
2247
2248        size_t fullLen = strlen(fullProbe);
2249        TEST_EXPECT_EQUAL(fullLen, 20);
2250
2251        Matches fullHits;
2252        getMatches(fullProbe, fullHits);
2253        TEST_EXPECT(fullHits.size()>0);
2254
2255        bool fewerHitsSeen = false;
2256
2257        for (size_t subLen = fullLen-1; !fewerHitsSeen && subLen >= 10; --subLen) { // for each partial sub-probe of 20mer
2258            char subProbe[20];
2259            subProbe[subLen] = 0;
2260
2261            for (size_t pos = 0; pos+subLen <= fullLen; ++pos) {
2262                Matches subHits, onlyFull;
2263
2264                memcpy(subProbe, fullProbe+pos, subLen);
2265                getMatches(subProbe, subHits);
2266                extract_first_but_not_second(fullHits, subHits, onlyFull);
2267
2268                if (!onlyFull.empty()) {
2269                    fprintf(stderr, "TEST_PARTIAL_COVERS_FULL_PROBE__BROKEN(\"%s\", \"%s\");\n", subProbe, fullProbe);
2270                    fewerHitsSeen = true; // only list first wrong hit for each fullProbe
2271                }
2272            }
2273        }
2274    }
2275}
2276
2277#endif
2278// --------------------------------------------------------------------------------
2279
2280static arb_test::match_expectation partial_covers_full_probe(const char *part, const char *full) {
2281    using namespace arb_test;
2282    using namespace std;
2283   
2284    expectation_group expected;
2285    expected.add(that(strstr(full, part)).does_differ_from_NULL());
2286    expected.add(that(strlen(part)).is_less_than(strlen(full)));
2287
2288    {
2289        Matches matchFull, matchPart;
2290        getMatches(full,  matchFull);
2291        getMatches(part, matchPart);
2292
2293        expected.add(that(matchFull.empty()).is_equal_to(false));
2294
2295        Matches onlyFirst;
2296        extract_first_but_not_second(matchFull, matchPart, onlyFirst);
2297
2298        string only_hit_by_full = matches2hitlist(onlyFirst);
2299        expected.add(that(only_hit_by_full).is_equal_to(""));
2300    }
2301
2302
2303    return all().ofgroup(expected);
2304}
2305
2306#define TEST_PARTIAL_COVERS_FULL_PROBE(part,full)         TEST_EXPECTATION(partial_covers_full_probe(part, full))
2307#define TEST_PARTIAL_COVERS_FULL_PROBE__BROKEN(part,full) TEST_EXPECTATION__BROKEN(partial_covers_full_probe(part, full))
2308
2309void TEST_SLOW_unmatched_probes() {
2310    TEST_PARTIAL_COVERS_FULL_PROBE("CCUCCUUUCU",          "GAUUAAUACCCCUCCUUUCU");
2311
2312    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUC",          "GGGGAACCUGCGGUUGGAUC");
2313    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCA",         "GGGAACCUGCGGUUGGAUCA");
2314    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCAC",        "GGAACCUGCGGUUGGAUCAC");
2315    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCACC",       "GAACCUGCGGUUGGAUCACC");
2316    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCACCU",      "AACCUGCGGUUGGAUCACCU");
2317    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCACCUC",     "ACCUGCGGUUGGAUCACCUC");
2318    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCACCUCC",    "CCUGCGGUUGGAUCACCUCC");
2319    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCACCUCCU",   "CUGCGGUUGGAUCACCUCCU");
2320    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCACCUCCUU",  "UGCGGUUGGAUCACCUCCUU");
2321    TEST_PARTIAL_COVERS_FULL_PROBE("CGGUUGGAUCACCUCCUUA", "GCGGUUGGAUCACCUCCUUA");
2322
2323    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUC",          "GGGGAACCUGGCGCUGGAUC");
2324    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCA",         "GGGAACCUGGCGCUGGAUCA");
2325    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCAC",        "GGAACCUGGCGCUGGAUCAC");
2326    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCACC",       "GAACCUGGCGCUGGAUCACC");
2327    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCACCU",      "AACCUGGCGCUGGAUCACCU");
2328    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCACCUC",     "ACCUGGCGCUGGAUCACCUC");
2329    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCACCUCC",    "CCUGGCGCUGGAUCACCUCC");
2330    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCACCUCCU",   "CUGGCGCUGGAUCACCUCCU");
2331    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCACCUCCUU",  "UGGCGCUGGAUCACCUCCUU");
2332    TEST_PARTIAL_COVERS_FULL_PROBE("GCGCUGGAUCACCUCCUUU", "GGCGCUGGAUCACCUCCUUU");
2333
2334    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCAC",         "GGAACCUGCGGCUGGAUCAC");
2335    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACC",        "GAACCUGCGGCUGGAUCACC");
2336    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACCU",       "AACCUGCGGCUGGAUCACCU");
2337    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACCUC",      "ACCUGCGGCUGGAUCACCUC");
2338    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACCUCC",     "CCUGCGGCUGGAUCACCUCC");
2339    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACCUCCU",    "CUGCGGCUGGAUCACCUCCU");
2340    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACCUCCUU",   "UGCGGCUGGAUCACCUCCUU");
2341    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACCUCCUUU",  "GCGGCUGGAUCACCUCCUUU");
2342    TEST_PARTIAL_COVERS_FULL_PROBE("GCUGGAUCACCUCCUUUC", "CGGCUGGAUCACCUCCUUUC");
2343
2344    // the data of the following tests is located right in front of the dots inserted in [8962]
2345    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAG",          "AAUUGAAGAGUUUGAUCAAG");
2346    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGU",         "AUUGAAGAGUUUGAUCAAGU");
2347    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUC",        "UUGAAGAGUUUGAUCAAGUC");
2348    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUCG",       "UGAAGAGUUUGAUCAAGUCG");
2349    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUCGA",      "GAAGAGUUUGAUCAAGUCGA");
2350    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUCGAG",     "AAGAGUUUGAUCAAGUCGAG");
2351    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUCGAGC",    "AGAGUUUGAUCAAGUCGAGC");
2352    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUCGAGCG",   "GAGUUUGAUCAAGUCGAGCG");
2353    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUCGAGCGG",  "AGUUUGAUCAAGUCGAGCGG");
2354    TEST_PARTIAL_COVERS_FULL_PROBE("UUUGAUCAAGUCGAGCGGU", "GUUUGAUCAAGUCGAGCGGU");
2355}
2356
2357void TEST_SLOW_variable_defaults_in_server() {
2358    test_setup(false);
2359
2360    const char *server_tag = GBS_ptserver_tag(TEST_SERVER_ID);
2361    TEST_EXPECT_NO_ERROR(arb_look_and_start_server(AISC_MAGIC_NUMBER, server_tag));
2362
2363    const char *servername = GBS_read_arb_tcp(server_tag);
2364    {
2365        char *socketname = GBS_global_string_copy(":%s", GB_path_in_ARBHOME("UNIT_TESTER/sockets/pt.socket"));
2366        TEST_EXPECT_EQUAL(servername, socketname); // as defined in ../lib/arb_tcp.dat@ARB_TEST_PT_SERVER
2367        free(socketname);
2368    }
2369
2370    T_PT_MAIN  com;
2371    T_PT_LOCS  locs;
2372    GB_ERROR   error = NULL;
2373    aisc_com  *link  = aisc_open(servername, com, AISC_MAGIC_NUMBER, &error);
2374    TEST_EXPECT_NO_ERROR(error);
2375    TEST_REJECT_NULL(link);
2376
2377    TEST_EXPECT_ZERO(aisc_create(link, PT_MAIN, com,
2378                                 MAIN_LOCS, PT_LOCS, locs,
2379                                 NULL));
2380
2381    {
2382#define LOCAL(rvar) (prev_read_##rvar)
2383
2384       
2385#define FREE_LOCAL_long(rvar)
2386#define FREE_LOCAL_charp(rvar) free(LOCAL(rvar))
2387#define FREE_LOCAL(type,rvar) FREE_LOCAL_##type(rvar)
2388
2389#define TEST__READ(type,rvar,expected)                                  \
2390        do {                                                            \
2391            TEST_EXPECT_ZERO(aisc_get(link, PT_LOCS, locs, rvar, &(LOCAL(rvar)), NULL)); \
2392            TEST_EXPECT_EQUAL(LOCAL(rvar), expected);                   \
2393            FREE_LOCAL(type,rvar);                                      \
2394        } while(0)
2395#define TEST_WRITE(type,rvar,val)                                       \
2396        TEST_EXPECT_ZERO(aisc_put(link, PT_LOCS, locs, rvar, (type)val, NULL))
2397#define TEST_CHANGE(type,rvar,val)              \
2398        do {                                    \
2399            TEST_WRITE(type, rvar, val);        \
2400            TEST__READ(type, rvar, val);        \
2401        } while(0)
2402#define TEST_DEFAULT_CHANGE(ctype,type,remote_variable,default_value,other_value) \
2403        do {                                                            \
2404            ctype DEFAULT_VALUE = default_value;                   \
2405            ctype OTHER_VALUE   = other_value;                     \
2406            type LOCAL(remote_variable);                                \
2407            TEST__READ(type, remote_variable, DEFAULT_VALUE);           \
2408            TEST_CHANGE(type, remote_variable, OTHER_VALUE);            \
2409            TEST_CHANGE(type, remote_variable, DEFAULT_VALUE);          \
2410        } while(0)
2411
2412        TEST_DEFAULT_CHANGE(const long, long, LOCS_MATCH_REVERSED, 1, 67);
2413        typedef char *charp;
2414        typedef const char *ccharp;
2415        TEST_DEFAULT_CHANGE(ccharp, charp, LOCS_LOGINTIME, "notime", "sometime");
2416    }
2417
2418    TEST_EXPECT_ZERO(aisc_close(link, com));
2419    link = 0;
2420}
2421
2422#endif // UNIT_TESTS
Note: See TracBrowser for help on using the repository browser.