_ZN8PfxEntryC2EP8AffixMgr:
   90|      8|    : pmyMgr(pmgr)
   91|      8|    , next(nullptr)
   92|      8|    , nexteq(nullptr)
   93|      8|    , nextne(nullptr)
   94|      8|    , flgnxt(nullptr) {}
_ZN8PfxEntry3addEPKcm:
   97|      3|std::string PfxEntry::add(const char* word, size_t len) {
   98|      3|  std::string result;
   99|      3|  if ((len > strip.size() || (len == 0 && pmyMgr->get_fullstrip())) &&
  ------------------
  |  Branch (99:7): [True: 3, False: 0]
  |  Branch (99:8): [True: 3, False: 0]
  |  Branch (99:31): [True: 0, False: 0]
  |  Branch (99:43): [True: 0, False: 0]
  ------------------
  100|      3|      (len >= numconds) && test_condition(word) &&
  ------------------
  |  Branch (100:7): [True: 3, False: 0]
  |  Branch (100:28): [True: 3, False: 0]
  ------------------
  101|      3|      (strip.empty() ||
  ------------------
  |  Branch (101:8): [True: 3, False: 0]
  ------------------
  102|      3|      (len >= strip.size() && strncmp(word, strip.c_str(), strip.size()) == 0))) {
  ------------------
  |  Branch (102:8): [True: 0, False: 0]
  |  Branch (102:31): [True: 0, False: 0]
  ------------------
  103|       |    /* we have a match so add prefix */
  104|      3|    result.assign(appnd);
  105|      3|    result.append(word + strip.size());
  106|      3|  }
  107|      3|  return result;
  108|      3|}
_ZN8PfxEntry9checkwordERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiictR12AffixScratch:
  213|  1.20M|                                   AffixScratch& scratch) {
  214|  1.20M|  struct hentry* he;  // hash entry of root word or NULL
  215|       |
  216|       |  // on entry prefix is 0 length or already matches the beginning of the word.
  217|       |  // So if the remaining root word has positive length
  218|       |  // and if there are enough chars in root word and added back strip chars
  219|       |  // to meet the number of characters conditions, then test it
  220|       |
  221|  1.20M|  int tmpl = len - appnd.size(); // length of tmpword
  222|       |
  223|  1.20M|  if (tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) {
  ------------------
  |  Branch (223:7): [True: 1.19M, False: 2.75k]
  |  Branch (223:20): [True: 2.75k, False: 0]
  |  Branch (223:33): [True: 0, False: 2.75k]
  ------------------
  224|       |    // generate new root word by removing prefix and adding
  225|       |    // back any characters that would have been stripped
  226|       |
  227|  1.19M|    std::string& tmpword = scratch.pfx_check_word;
  228|  1.19M|    tmpword.assign(strip);
  229|  1.19M|    tmpword.append(word, start + appnd.size(), tmpl);
  230|       |
  231|       |    // now make sure all of the conditions on characters
  232|       |    // are met.  Please see the appendix at the end of
  233|       |    // this file for more info on exactly what is being
  234|       |    // tested
  235|       |
  236|       |    // if all conditions are met then check if resulting
  237|       |    // root word in the dictionary
  238|       |
  239|  1.19M|    if (test_condition(tmpword)) {
  ------------------
  |  Branch (239:9): [True: 15.6k, False: 1.18M]
  ------------------
  240|  15.6k|      tmpl += strip.size();
  241|  15.6k|      if ((he = pmyMgr->lookup(tmpword.c_str(), tmpword.size())) != nullptr) {
  ------------------
  |  Branch (241:11): [True: 2, False: 15.6k]
  ------------------
  242|      2|        do {
  243|      2|          if (TESTAFF(he->astr, aflag, he->alen) &&
  ------------------
  |  |   99|      4|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 2]
  |  |  ------------------
  ------------------
  |  Branch (243:15): [True: 0, False: 2]
  ------------------
  244|       |              // forbid single prefixes with needaffix flag
  245|      0|              !TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
  ------------------
  |  |   99|      2|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (245:15): [True: 0, False: 0]
  ------------------
  246|       |              // needflag
  247|      0|              ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (247:16): [True: 0, False: 0]
  ------------------
  248|      0|               (contclass && TESTAFF(contclass, needflag, contclasslen))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (248:17): [True: 0, False: 0]
  ------------------
  249|      0|            return he;
  250|      2|          he = he->next_homonym;  // check homonyms
  251|      2|        } while (he);
  ------------------
  |  Branch (251:18): [True: 0, False: 2]
  ------------------
  252|      2|      }
  253|       |
  254|       |      // prefix matched but no root word was found
  255|       |      // if aeXPRODUCT is allowed, try again but now
  256|       |      // ross checked combined with a suffix
  257|       |
  258|       |      // if ((opts & aeXPRODUCT) && in_compound) {
  259|  15.6k|      if ((opts & aeXPRODUCT)) {
  ------------------
  |  |   65|  15.6k|#define aeXPRODUCT (1 << 0)
  ------------------
  |  Branch (259:11): [True: 15.6k, False: 0]
  ------------------
  260|  15.6k|        he = pmyMgr->suffix_check(tmpword, 0, tmpl, aeXPRODUCT, this,
  ------------------
  |  |   65|  15.6k|#define aeXPRODUCT (1 << 0)
  ------------------
  261|  15.6k|                                  scratch, FLAG_NULL, needflag, in_compound);
  ------------------
  |  |   96|  15.6k|#define FLAG_NULL 0x00
  ------------------
  262|  15.6k|        if (he)
  ------------------
  |  Branch (262:13): [True: 0, False: 15.6k]
  ------------------
  263|      0|          return he;
  264|  15.6k|      }
  265|  15.6k|    }
  266|  1.19M|  }
  267|  1.20M|  return nullptr;
  268|  1.20M|}
_ZN8PfxEntry12check_twosfxERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiictR12AffixScratch:
  276|  1.19M|                                      AffixScratch& scratch) {
  277|       |  // on entry prefix is 0 length or already matches the beginning of the word.
  278|       |  // So if the remaining root word has positive length
  279|       |  // and if there are enough chars in root word and added back strip chars
  280|       |  // to meet the number of characters conditions, then test it
  281|       |
  282|  1.19M|  int tmpl = len - appnd.size(); // length of tmpword
  283|       |
  284|  1.19M|  if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
  ------------------
  |  Branch (284:8): [True: 1.19M, False: 2.71k]
  |  Branch (284:21): [True: 2.71k, False: 0]
  |  Branch (284:34): [True: 0, False: 2.71k]
  ------------------
  285|  1.19M|      (tmpl + strip.size() >= numconds)) {
  ------------------
  |  Branch (285:7): [True: 1.16M, False: 32.2k]
  ------------------
  286|       |    // generate new root word by removing prefix and adding
  287|       |    // back any characters that would have been stripped
  288|       |
  289|  1.16M|    std::string& tmpword = scratch.pfx_check_twosfx;
  290|  1.16M|    tmpword.assign(strip);
  291|  1.16M|    tmpword.append(word, start + appnd.size(), tmpl);
  292|       |
  293|       |    // now make sure all of the conditions on characters
  294|       |    // are met.  Please see the appendix at the end of
  295|       |    // this file for more info on exactly what is being
  296|       |    // tested
  297|       |
  298|       |    // if all conditions are met then check if resulting
  299|       |    // root word in the dictionary
  300|       |
  301|  1.16M|    if (test_condition(tmpword)) {
  ------------------
  |  Branch (301:9): [True: 11.6k, False: 1.15M]
  ------------------
  302|  11.6k|      tmpl += strip.size();
  303|       |
  304|       |      // prefix matched but no root word was found
  305|       |      // if aeXPRODUCT is allowed, try again but now
  306|       |      // cross checked combined with a suffix
  307|       |
  308|  11.6k|      if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
  ------------------
  |  |   65|  11.6k|#define aeXPRODUCT (1 << 0)
  ------------------
                    if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
  ------------------
  |  |   73|  11.6k|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (308:11): [True: 11.6k, False: 0]
  |  Branch (308:34): [True: 11.6k, False: 0]
  ------------------
  309|       |        // hash entry of root word or NULL
  310|  11.6k|        struct hentry* he = pmyMgr->suffix_check_twosfx(tmpword, 0, tmpl, aeXPRODUCT, this,
  ------------------
  |  |   65|  11.6k|#define aeXPRODUCT (1 << 0)
  ------------------
  311|  11.6k|                                                        scratch, needflag);
  312|  11.6k|        if (he)
  ------------------
  |  Branch (312:13): [True: 0, False: 11.6k]
  ------------------
  313|      0|          return he;
  314|  11.6k|      }
  315|  11.6k|    }
  316|  1.16M|  }
  317|  1.19M|  return nullptr;
  318|  1.19M|}
_ZN8PfxEntry18check_twosfx_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiictR12AffixScratch:
  326|    564|                                         AffixScratch& scratch) {
  327|    564|  std::string result;
  328|       |  // on entry prefix is 0 length or already matches the beginning of the word.
  329|       |  // So if the remaining root word has positive length
  330|       |  // and if there are enough chars in root word and added back strip chars
  331|       |  // to meet the number of characters conditions, then test it
  332|    564|  int tmpl = len - appnd.size(); // length of tmpword
  333|       |
  334|    564|  if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
  ------------------
  |  Branch (334:8): [True: 564, False: 0]
  |  Branch (334:21): [True: 0, False: 0]
  |  Branch (334:34): [True: 0, False: 0]
  ------------------
  335|    564|      (tmpl + strip.size() >= numconds)) {
  ------------------
  |  Branch (335:7): [True: 485, False: 79]
  ------------------
  336|       |    // generate new root word by removing prefix and adding
  337|       |    // back any characters that would have been stripped
  338|       |
  339|    485|    std::string& tmpword = scratch.pfx_check_twosfx;
  340|    485|    tmpword.assign(strip);
  341|    485|    tmpword.append(word, start + appnd.size(), tmpl);
  342|       |
  343|       |    // now make sure all of the conditions on characters
  344|       |    // are met.  Please see the appendix at the end of
  345|       |    // this file for more info on exactly what is being
  346|       |    // tested
  347|       |
  348|       |    // if all conditions are met then check if resulting
  349|       |    // root word in the dictionary
  350|       |
  351|    485|    if (test_condition(tmpword)) {
  ------------------
  |  Branch (351:9): [True: 0, False: 485]
  ------------------
  352|      0|      tmpl += strip.size();
  353|       |
  354|       |      // prefix matched but no root word was found
  355|       |      // if aeXPRODUCT is allowed, try again but now
  356|       |      // ross checked combined with a suffix
  357|       |
  358|      0|      if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
  ------------------
  |  |   65|      0|#define aeXPRODUCT (1 << 0)
  ------------------
                    if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (358:11): [True: 0, False: 0]
  |  Branch (358:34): [True: 0, False: 0]
  ------------------
  359|      0|        result = pmyMgr->suffix_check_twosfx_morph(tmpword, 0, tmpl,
  360|      0|                                                   aeXPRODUCT,
  ------------------
  |  |   65|      0|#define aeXPRODUCT (1 << 0)
  ------------------
  361|      0|                                                   this, scratch, needflag);
  362|      0|      }
  363|      0|    }
  364|    485|  }
  365|    564|  return result;
  366|    564|}
_ZN8PfxEntry11check_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiictR12AffixScratch:
  374|    564|                                  AffixScratch& scratch) {
  375|    564|  std::string result;
  376|       |
  377|       |  // on entry prefix is 0 length or already matches the beginning of the word.
  378|       |  // So if the remaining root word has positive length
  379|       |  // and if there are enough chars in root word and added back strip chars
  380|       |  // to meet the number of characters conditions, then test it
  381|       |
  382|    564|  int tmpl = len - appnd.size(); // length of tmpword
  383|       |
  384|    564|  if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
  ------------------
  |  Branch (384:8): [True: 564, False: 0]
  |  Branch (384:21): [True: 0, False: 0]
  |  Branch (384:34): [True: 0, False: 0]
  ------------------
  385|    564|      (tmpl + strip.size() >= numconds)) {
  ------------------
  |  Branch (385:7): [True: 485, False: 79]
  ------------------
  386|       |    // generate new root word by removing prefix and adding
  387|       |    // back any characters that would have been stripped
  388|       |
  389|    485|    std::string& tmpword = scratch.pfx_check_word;
  390|    485|    tmpword.assign(strip);
  391|    485|    tmpword.append(word, start + appnd.size(), tmpl);
  392|       |
  393|       |    // now make sure all of the conditions on characters
  394|       |    // are met.  Please see the appendix at the end of
  395|       |    // this file for more info on exactly what is being
  396|       |    // tested
  397|       |
  398|       |    // if all conditions are met then check if resulting
  399|       |    // root word in the dictionary
  400|       |
  401|    485|    if (test_condition(tmpword)) {
  ------------------
  |  Branch (401:9): [True: 0, False: 485]
  ------------------
  402|      0|      tmpl += strip.size();
  403|      0|      struct hentry* he;  // hash entry of root word or NULL
  404|      0|      if ((he = pmyMgr->lookup(tmpword.c_str(), tmpword.size())) != nullptr) {
  ------------------
  |  Branch (404:11): [True: 0, False: 0]
  ------------------
  405|      0|        do {
  406|      0|          if (TESTAFF(he->astr, aflag, he->alen) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (406:15): [True: 0, False: 0]
  ------------------
  407|       |              // forbid single prefixes with needaffix flag
  408|      0|              !TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (408:15): [True: 0, False: 0]
  ------------------
  409|       |              // needflag
  410|      0|              ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (410:16): [True: 0, False: 0]
  ------------------
  411|      0|               (contclass && TESTAFF(contclass, needflag, contclasslen)))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (411:17): [True: 0, False: 0]
  ------------------
  412|      0|            if (morphcode) {
  ------------------
  |  Branch (412:17): [True: 0, False: 0]
  ------------------
  413|      0|              result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
  414|      0|              result.append(morphcode);
  415|      0|            } else
  416|      0|              result.append(getKey());
  417|      0|            if (!HENTRY_FIND(he, MORPH_STEM)) {
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
  |  Branch (417:17): [True: 0, False: 0]
  ------------------
  418|      0|              result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
  419|      0|              result.append(MORPH_STEM);
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
  420|      0|              result.append(HENTRY_WORD(he));
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
  421|      0|            }
  422|       |            // store the pointer of the hash entry
  423|      0|            if (HENTRY_DATA(he)) {
  ------------------
  |  Branch (423:17): [True: 0, False: 0]
  ------------------
  424|      0|              result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
  425|      0|              result.append(HENTRY_DATA2(he));
  426|      0|            } else {
  427|       |              // return with debug information
  428|      0|              std::string flag = pmyMgr->encode_flag(getFlag());
  429|      0|              result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
  430|      0|              result.append(MORPH_FLAG);
  ------------------
  |  |  117|      0|#define MORPH_FLAG "fl:"
  ------------------
  431|      0|              result.append(flag);
  432|      0|            }
  433|      0|            result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
  434|      0|          }
  435|      0|          he = he->next_homonym;
  436|      0|        } while (he);
  ------------------
  |  Branch (436:18): [True: 0, False: 0]
  ------------------
  437|      0|      }
  438|       |
  439|       |      // prefix matched but no root word was found
  440|       |      // if aeXPRODUCT is allowed, try again but now
  441|       |      // ross checked combined with a suffix
  442|       |
  443|      0|      if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
  ------------------
  |  |   65|      0|#define aeXPRODUCT (1 << 0)
  ------------------
                    if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (443:11): [True: 0, False: 0]
  |  Branch (443:34): [True: 0, False: 0]
  ------------------
  444|      0|        std::string st = pmyMgr->suffix_check_morph(tmpword, 0, tmpl, aeXPRODUCT, this,
  ------------------
  |  |   65|      0|#define aeXPRODUCT (1 << 0)
  ------------------
  445|      0|                                                    scratch, FLAG_NULL, needflag);
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
  446|      0|        if (!st.empty()) {
  ------------------
  |  Branch (446:13): [True: 0, False: 0]
  ------------------
  447|      0|          result.append(st);
  448|      0|        }
  449|      0|      }
  450|      0|    }
  451|    485|  }
  452|       |
  453|    564|  return result;
  454|    564|}
_ZN8SfxEntryC2EP8AffixMgr:
  457|     34|    : pmyMgr(pmgr)  // register affix manager
  458|     34|    , next(nullptr)
  459|     34|    , nexteq(nullptr)
  460|     34|    , nextne(nullptr)
  461|     34|    , flgnxt(nullptr)
  462|     34|    , l_morph(nullptr)
  463|     34|    , r_morph(nullptr)
  464|     34|    , eq_morph(nullptr) {}
_ZN8SfxEntry3addEPKcm:
  467|     35|std::string SfxEntry::add(const char* word, size_t len) {
  468|     35|  std::string result;
  469|       |  /* make sure all conditions match */
  470|     35|  if ((len > strip.size() || (len == 0 && pmyMgr->get_fullstrip())) &&
  ------------------
  |  Branch (470:8): [True: 35, False: 0]
  |  Branch (470:31): [True: 0, False: 0]
  |  Branch (470:43): [True: 0, False: 0]
  ------------------
  471|     35|      (len >= numconds) && test_condition(word + len, word) &&
  ------------------
  |  Branch (471:7): [True: 35, False: 0]
  |  Branch (471:28): [True: 35, False: 0]
  ------------------
  472|     35|      (strip.empty() ||
  ------------------
  |  Branch (472:8): [True: 35, False: 0]
  ------------------
  473|     35|       (len >= strip.size() && strcmp(word + len - strip.size(), strip.c_str()) == 0))) {
  ------------------
  |  Branch (473:9): [True: 0, False: 0]
  |  Branch (473:32): [True: 0, False: 0]
  ------------------
  474|     35|    result.assign(word, len);
  475|       |    /* we have a match so add suffix */
  476|     35|    result.replace(len - strip.size(), std::string::npos, appnd);
  477|     35|  }
  478|     35|  return result;
  479|     35|}
_ZN8SfxEntry9checkwordERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiiP8PfxEntrytttR12AffixScratch:
  627|  64.9k|                                   AffixScratch& scratch) {
  628|  64.9k|  struct hentry* he;  // hash entry pointer
  629|  64.9k|  PfxEntry* ep = ppfx;
  630|       |
  631|       |  // if this suffix is being cross checked with a prefix
  632|       |  // but it does not support cross products skip it
  633|       |
  634|  64.9k|  if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0))
  ------------------
  |  |   65|  64.9k|#define aeXPRODUCT (1 << 0)
  ------------------
                if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0))
  ------------------
  |  |   65|      0|#define aeXPRODUCT (1 << 0)
  ------------------
  |  Branch (634:7): [True: 0, False: 64.9k]
  |  Branch (634:41): [True: 0, False: 0]
  ------------------
  635|      0|    return nullptr;
  636|       |
  637|       |  // upon entry suffix is 0 length or already matches the end of the word.
  638|       |  // So if the remaining root word has positive length
  639|       |  // and if there are enough chars in root word and added back strip chars
  640|       |  // to meet the number of characters conditions, then test it
  641|       |
  642|  64.9k|  int tmpl = len - appnd.size(); // length of tmpword
  643|       |  // the second condition is not enough for UTF-8 strings
  644|       |  // it checked in test_condition()
  645|       |
  646|  64.9k|  if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
  ------------------
  |  Branch (646:8): [True: 64.2k, False: 698]
  |  Branch (646:21): [True: 698, False: 0]
  |  Branch (646:34): [True: 0, False: 698]
  ------------------
  647|  64.2k|      (tmpl + strip.size() >= numconds)) {
  ------------------
  |  Branch (647:7): [True: 64.2k, False: 0]
  ------------------
  648|       |    // generate new root word by removing suffix and adding
  649|       |    // back any characters that would have been stripped or
  650|       |    // or null terminating the shorter string
  651|       |
  652|  64.2k|    std::string& tmpword = scratch.sfx_check_word;
  653|  64.2k|    tmpword.assign(word, start, tmpl);
  654|  64.2k|    if (!strip.empty()) {
  ------------------
  |  Branch (654:9): [True: 0, False: 64.2k]
  ------------------
  655|      0|      tmpword.append(strip);
  656|      0|    }
  657|       |
  658|  64.2k|    const char* beg = tmpword.c_str();
  659|  64.2k|    const char* end = beg + tmpword.size();
  660|       |
  661|       |    // now make sure all of the conditions on characters
  662|       |    // are met.  Please see the appendix at the end of
  663|       |    // this file for more info on exactly what is being
  664|       |    // tested
  665|       |
  666|       |    // if all conditions are met then check if resulting
  667|       |    // root word in the dictionary
  668|       |
  669|  64.2k|    if (test_condition(end, beg)) {
  ------------------
  |  Branch (669:9): [True: 64.2k, False: 2]
  ------------------
  670|       |#ifdef SZOSZABLYA_POSSIBLE_ROOTS
  671|       |      fprintf(stdout, "%s %s %c\n", word.c_str() + start, beg, aflag);
  672|       |#endif
  673|  64.2k|      if ((he = pmyMgr->lookup(tmpword.c_str(), tmpword.size())) != nullptr) {
  ------------------
  |  Branch (673:11): [True: 39, False: 64.1k]
  ------------------
  674|     39|        do {
  675|       |          // check conditional suffix (enabled by prefix)
  676|     39|          if ((TESTAFF(he->astr, aflag, he->alen) ||
  ------------------
  |  |   99|     78|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 4, False: 35]
  |  |  ------------------
  ------------------
  |  Branch (676:15): [True: 4, False: 35]
  ------------------
  677|     35|               (ep && ep->getCont() &&
  ------------------
  |  Branch (677:17): [True: 0, False: 35]
  |  Branch (677:23): [True: 0, False: 0]
  ------------------
  678|      0|                TESTAFF(ep->getCont(), aflag, ep->getContLen()))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  679|      4|              (((optflags & aeXPRODUCT) == 0) ||
  ------------------
  |  |   65|      4|#define aeXPRODUCT (1 << 0)
  ------------------
  |  Branch (679:16): [True: 4, False: 0]
  ------------------
  680|      0|               (ep && TESTAFF(he->astr, ep->getFlag(), he->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (680:17): [True: 0, False: 0]
  ------------------
  681|       |               // enabled by prefix
  682|      0|               ((contclass) &&
  ------------------
  |  Branch (682:17): [True: 0, False: 0]
  ------------------
  683|      0|                (ep && TESTAFF(contclass, ep->getFlag(), contclasslen)))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (683:18): [True: 0, False: 0]
  ------------------
  684|       |              // handle cont. class
  685|      4|              ((!cclass) ||
  ------------------
  |  Branch (685:16): [True: 4, False: 0]
  ------------------
  686|      0|               ((contclass) && TESTAFF(contclass, cclass, contclasslen))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (686:17): [True: 0, False: 0]
  ------------------
  687|       |              // check only in compound homonyms (bad flags)
  688|      4|              (!badflag || !TESTAFF(he->astr, badflag, he->alen)) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (688:16): [True: 4, False: 0]
  |  Branch (688:28): [True: 0, False: 0]
  ------------------
  689|       |              // handle required flag
  690|      4|              ((!needflag) ||
  ------------------
  |  Branch (690:16): [True: 4, False: 0]
  ------------------
  691|      0|               (TESTAFF(he->astr, needflag, he->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  692|      0|                ((contclass) && TESTAFF(contclass, needflag, contclasslen)))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (692:18): [True: 0, False: 0]
  ------------------
  693|      4|            return he;
  694|     35|          he = he->next_homonym;  // check homonyms
  695|     35|        } while (he);
  ------------------
  |  Branch (695:18): [True: 0, False: 35]
  ------------------
  696|     39|      }
  697|  64.2k|    }
  698|  64.2k|  }
  699|  64.8k|  return nullptr;
  700|  64.9k|}
_ZN8SfxEntry12check_twosfxERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiiP8PfxEntrytR12AffixScratch:
  709|  36.6k|                                      AffixScratch& scratch) {
  710|  36.6k|  PfxEntry* ep = ppfx;
  711|       |
  712|       |  // if this suffix is being cross checked with a prefix
  713|       |  // but it does not support cross products skip it
  714|       |
  715|  36.6k|  if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0)
  ------------------
  |  |   65|  36.6k|#define aeXPRODUCT (1 << 0)
  ------------------
                if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0)
  ------------------
  |  |   65|      0|#define aeXPRODUCT (1 << 0)
  ------------------
  |  Branch (715:7): [True: 0, False: 36.6k]
  |  Branch (715:39): [True: 0, False: 0]
  ------------------
  716|      0|    return nullptr;
  717|       |
  718|       |  // upon entry suffix is 0 length or already matches the end of the word.
  719|       |  // So if the remaining root word has positive length
  720|       |  // and if there are enough chars in root word and added back strip chars
  721|       |  // to meet the number of characters conditions, then test it
  722|       |
  723|  36.6k|  int tmpl = len - appnd.size(); // length of tmpword
  724|       |
  725|  36.6k|  if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
  ------------------
  |  Branch (725:8): [True: 36.5k, False: 75]
  |  Branch (725:21): [True: 75, False: 0]
  |  Branch (725:34): [True: 0, False: 75]
  ------------------
  726|  36.5k|      (tmpl + strip.size() >= numconds)) {
  ------------------
  |  Branch (726:7): [True: 36.5k, False: 0]
  ------------------
  727|       |    // generate new root word by removing suffix and adding
  728|       |    // back any characters that would have been stripped or
  729|       |    // or null terminating the shorter string
  730|       |
  731|  36.5k|    std::string& tmpword = scratch.sfx_check_twosfx;
  732|  36.5k|    tmpword.assign(word, start);
  733|  36.5k|    tmpword.resize(tmpl);
  734|  36.5k|    tmpword.append(strip);
  735|  36.5k|    tmpl += strip.size();
  736|       |
  737|  36.5k|    const char* beg = tmpword.c_str();
  738|  36.5k|    const char* end = beg + tmpl;
  739|       |
  740|       |    // now make sure all of the conditions on characters
  741|       |    // are met.  Please see the appendix at the end of
  742|       |    // this file for more info on exactly what is being
  743|       |    // tested
  744|       |
  745|       |    // if all conditions are met then recall suffix_check
  746|       |
  747|  36.5k|    if (test_condition(end, beg)) {
  ------------------
  |  Branch (747:9): [True: 36.5k, False: 0]
  ------------------
  748|  36.5k|      struct hentry* he;  // hash entry pointer
  749|  36.5k|      if (ppfx) {
  ------------------
  |  Branch (749:11): [True: 0, False: 36.5k]
  ------------------
  750|       |        // handle conditional suffix
  751|      0|        if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (751:13): [True: 0, False: 0]
  |  Branch (751:13): [True: 0, False: 0]
  ------------------
  752|      0|          he = pmyMgr->suffix_check(tmpword, 0, tmpl, 0, nullptr, scratch, (FLAG)aflag, needflag, IN_CPD_NOT);
  ------------------
  |  |   72|      0|#define IN_CPD_NOT 0
  ------------------
  753|      0|        else
  754|      0|          he = pmyMgr->suffix_check(tmpword, 0, tmpl, optflags, ppfx,
  755|      0|                                    scratch, (FLAG)aflag, needflag, IN_CPD_NOT);
  ------------------
  |  |   72|      0|#define IN_CPD_NOT 0
  ------------------
  756|  36.5k|      } else {
  757|  36.5k|        he = pmyMgr->suffix_check(tmpword, 0, tmpl, 0, nullptr, scratch, (FLAG)aflag, needflag, IN_CPD_NOT);
  ------------------
  |  |   72|  36.5k|#define IN_CPD_NOT 0
  ------------------
  758|  36.5k|      }
  759|  36.5k|      if (he)
  ------------------
  |  Branch (759:11): [True: 0, False: 36.5k]
  ------------------
  760|      0|        return he;
  761|  36.5k|    }
  762|  36.5k|  }
  763|  36.6k|  return nullptr;
  764|  36.6k|}
_ZN8SfxEntry15initReverseWordEv:
  875|     34|void SfxEntry::initReverseWord() {
  876|     34|  rappnd = appnd;
  877|     34|  reverseword(rappnd);
  878|     34|}
_ZN8PfxEntry14test_conditionERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  125|  2.36M|inline int PfxEntry::test_condition(const std::string& s) {
  126|  2.36M|  size_t st = 0;
  127|  2.36M|  size_t pos = std::string::npos;  // group with pos input position
  128|  2.36M|  bool neg = false;        // complementer
  129|  2.36M|  bool ingroup = false;    // character in the group
  130|  2.36M|  if (numconds == 0)
  ------------------
  |  Branch (130:7): [True: 4.04k, False: 2.35M]
  ------------------
  131|  4.04k|    return 1;
  132|  2.35M|  char* p = c.conds;
  133|  2.47M|  while (true) {
  ------------------
  |  Branch (133:10): [True: 2.47M, Folded]
  ------------------
  134|  2.47M|    switch (*p) {
  135|      0|      case '\0':
  ------------------
  |  Branch (135:7): [True: 0, False: 2.47M]
  ------------------
  136|      0|        return 1;
  137|  23.2k|      case '[': {
  ------------------
  |  Branch (137:7): [True: 23.2k, False: 2.45M]
  ------------------
  138|  23.2k|        neg = false;
  139|  23.2k|        ingroup = false;
  140|  23.2k|        p = nextchar(p);
  141|  23.2k|        pos = st;
  142|  23.2k|        break;
  143|      0|      }
  144|  23.2k|      case '^': {
  ------------------
  |  Branch (144:7): [True: 23.2k, False: 2.45M]
  ------------------
  145|  23.2k|        p = nextchar(p);
  146|  23.2k|        neg = true;
  147|  23.2k|        break;
  148|      0|      }
  149|  23.2k|      case ']': {
  ------------------
  |  Branch (149:7): [True: 23.2k, False: 2.45M]
  ------------------
  150|  23.2k|        if (bool(neg) == bool(ingroup))
  ------------------
  |  Branch (150:13): [True: 0, False: 23.2k]
  ------------------
  151|      0|          return 0;
  152|  23.2k|        pos = std::string::npos;
  153|  23.2k|        p = nextchar(p);
  154|       |        // skip the next character
  155|  23.2k|        if (!ingroup && st < s.size())
  ------------------
  |  Branch (155:13): [True: 23.2k, False: 0]
  |  Branch (155:25): [True: 22.0k, False: 1.16k]
  ------------------
  156|  22.0k|          st = (opts & aeUTF8) ? utf8_next(s, st) : st + 1;
  ------------------
  |  |   66|  22.0k|#define aeUTF8 (1 << 1)
  ------------------
  |  Branch (156:16): [True: 22.0k, False: 0]
  ------------------
  157|  23.2k|        if (st == s.size() && p)
  ------------------
  |  Branch (157:13): [True: 3.25k, False: 19.9k]
  |  Branch (157:31): [True: 0, False: 3.25k]
  ------------------
  158|      0|          return 0;  // word <= condition
  159|  23.2k|        break;
  160|  23.2k|      }
  161|  23.2k|      case '.':
  ------------------
  |  Branch (161:7): [True: 0, False: 2.47M]
  ------------------
  162|      0|        if (pos == std::string::npos) {  // dots are not metacharacters in groups: [.]
  ------------------
  |  Branch (162:13): [True: 0, False: 0]
  ------------------
  163|      0|          if (st == s.size())
  ------------------
  |  Branch (163:15): [True: 0, False: 0]
  ------------------
  164|      0|            return 0;  // dot has no character to match
  165|      0|          p = nextchar(p);
  166|       |          // skip the next character
  167|      0|          st = (opts & aeUTF8) ? utf8_next(s, st) : st + 1;
  ------------------
  |  |   66|      0|#define aeUTF8 (1 << 1)
  ------------------
  |  Branch (167:16): [True: 0, False: 0]
  ------------------
  168|      0|          break;
  169|      0|        }
  170|       |      /* FALLTHROUGH */
  171|  2.40M|      default: {
  ------------------
  |  Branch (171:7): [True: 2.40M, False: 69.6k]
  ------------------
  172|  2.40M|        if (st < s.size() && s[st] == *p) {
  ------------------
  |  Branch (172:13): [True: 2.40M, False: 2.33k]
  |  Branch (172:30): [True: 23.3k, False: 2.37M]
  ------------------
  173|  23.3k|          ++st;
  174|  23.3k|          p = nextchar(p);
  175|  23.3k|          if ((opts & aeUTF8) && (s[st - 1] & 0x80)) {  // multibyte
  ------------------
  |  |   66|  23.3k|#define aeUTF8 (1 << 1)
  ------------------
  |  Branch (175:15): [True: 23.3k, False: 0]
  |  Branch (175:34): [True: 23.3k, False: 0]
  ------------------
  176|  46.5k|            while (p && is_utf8_cont(*p)) {             // character
  ------------------
  |  Branch (176:20): [True: 46.5k, False: 0]
  |  Branch (176:25): [True: 23.3k, False: 23.2k]
  ------------------
  177|  23.3k|              if (st >= s.size() || *p != s[st]) {
  ------------------
  |  Branch (177:19): [True: 0, False: 23.3k]
  |  Branch (177:37): [True: 96, False: 23.2k]
  ------------------
  178|     96|                if (pos == std::string::npos)
  ------------------
  |  Branch (178:21): [True: 88, False: 8]
  ------------------
  179|     88|                  return 0;
  180|      8|                st = pos;
  181|      8|                break;
  182|     96|              }
  183|  23.2k|              p = nextchar(p);
  184|  23.2k|              ++st;
  185|  23.2k|            }
  186|  23.2k|            if (pos != std::string::npos && st != pos) {
  ------------------
  |  Branch (186:17): [True: 8, False: 23.2k]
  |  Branch (186:45): [True: 0, False: 8]
  ------------------
  187|      0|              ingroup = true;
  188|      0|              while (p && *p != ']' && ((p = nextchar(p)) != nullptr)) {
  ------------------
  |  Branch (188:22): [True: 0, False: 0]
  |  Branch (188:27): [True: 0, False: 0]
  |  Branch (188:40): [True: 0, False: 0]
  ------------------
  189|      0|              }
  190|      0|            }
  191|  23.2k|          } else if (pos != std::string::npos) {
  ------------------
  |  Branch (191:22): [True: 0, False: 0]
  ------------------
  192|      0|            ingroup = true;
  193|      0|            while (p && *p != ']' && ((p = nextchar(p)) != nullptr)) {
  ------------------
  |  Branch (193:20): [True: 0, False: 0]
  |  Branch (193:25): [True: 0, False: 0]
  |  Branch (193:38): [True: 0, False: 0]
  ------------------
  194|      0|            }
  195|      0|          }
  196|  2.38M|        } else if (pos != std::string::npos) {  // group
  ------------------
  |  Branch (196:20): [True: 46.4k, False: 2.33M]
  ------------------
  197|  46.4k|          p = nextchar(p);
  198|  46.4k|        } else
  199|  2.33M|          return 0;
  200|  2.40M|      }
  201|  2.47M|    }
  202|   139k|    if (!p)
  ------------------
  |  Branch (202:9): [True: 23.2k, False: 116k]
  ------------------
  203|  23.2k|      return 1;
  204|   139k|  }
  205|  2.35M|}
_ZN8PfxEntry8nextcharEPc:
  110|   162k|inline char* PfxEntry::nextchar(char* p) {
  111|   162k|  if (p) {
  ------------------
  |  Branch (111:7): [True: 162k, False: 0]
  ------------------
  112|   162k|    p++;
  113|   162k|    if (opts & aeLONGCOND) {
  ------------------
  |  |   69|   162k|#define aeLONGCOND (1 << 4)
  ------------------
  |  Branch (113:9): [True: 0, False: 162k]
  ------------------
  114|       |      // jump to the 2nd part of the condition
  115|      0|      if (p == c.conds + MAXCONDLEN_1)
  ------------------
  |  |   91|      0|#define MAXCONDLEN_1 (MAXCONDLEN - sizeof(char*))
  |  |  ------------------
  |  |  |  |   90|      0|#define MAXCONDLEN 20
  |  |  ------------------
  ------------------
  |  Branch (115:11): [True: 0, False: 0]
  ------------------
  116|      0|        return c.l.conds2;
  117|       |      // end of the MAXCONDLEN length condition
  118|   162k|    } else if (p == c.conds + MAXCONDLEN)
  ------------------
  |  |   90|   162k|#define MAXCONDLEN 20
  ------------------
  |  Branch (118:16): [True: 0, False: 162k]
  ------------------
  119|      0|      return nullptr;
  120|   162k|    return *p ? p : nullptr;
  ------------------
  |  Branch (120:12): [True: 139k, False: 23.2k]
  ------------------
  121|   162k|  }
  122|      0|  return nullptr;
  123|   162k|}
_ZN8SfxEntry14test_conditionEPKcS1_:
  496|   100k|inline int SfxEntry::test_condition(const char* st, const char* beg) {
  497|   100k|  const char* pos = nullptr;  // group with pos input position
  498|   100k|  bool neg = false;        // complementer
  499|   100k|  bool ingroup = false;    // character in the group
  500|   100k|  if (numconds == 0)
  ------------------
  |  Branch (500:7): [True: 100k, False: 2]
  ------------------
  501|   100k|    return 1;
  502|      2|  char* p = c.conds;
  503|      2|  st--;
  504|      2|  int i = 1;
  505|     16|  while (true) {
  ------------------
  |  Branch (505:10): [True: 16, Folded]
  ------------------
  506|     16|    switch (*p) {
  507|      0|      case '\0':
  ------------------
  |  Branch (507:7): [True: 0, False: 16]
  ------------------
  508|      0|        return 1;
  509|      2|      case '[':
  ------------------
  |  Branch (509:7): [True: 2, False: 14]
  ------------------
  510|      2|        p = nextchar(p);
  511|      2|        pos = st;
  512|      2|        break;
  513|      0|      case '^':
  ------------------
  |  Branch (513:7): [True: 0, False: 16]
  ------------------
  514|      0|        p = nextchar(p);
  515|      0|        neg = true;
  516|      0|        break;
  517|      2|      case ']':
  ------------------
  |  Branch (517:7): [True: 2, False: 14]
  ------------------
  518|      2|        if (!neg && !ingroup)
  ------------------
  |  Branch (518:13): [True: 2, False: 0]
  |  Branch (518:21): [True: 2, False: 0]
  ------------------
  519|      2|          return 0;
  520|      0|        i++;
  521|       |        // skip the next character
  522|      0|        if (!ingroup) {
  ------------------
  |  Branch (522:13): [True: 0, False: 0]
  ------------------
  523|      0|          for (; (opts & aeUTF8) && (st >= beg) && is_utf8_cont(*st); st--)
  ------------------
  |  |   66|      0|#define aeUTF8 (1 << 1)
  ------------------
  |  Branch (523:18): [True: 0, False: 0]
  |  Branch (523:37): [True: 0, False: 0]
  |  Branch (523:52): [True: 0, False: 0]
  ------------------
  524|      0|            ;
  525|      0|          st--;
  526|      0|        }
  527|      0|        pos = nullptr;
  528|      0|        neg = false;
  529|      0|        ingroup = false;
  530|      0|        p = nextchar(p);
  531|      0|        if (st < beg && p)
  ------------------
  |  Branch (531:13): [True: 0, False: 0]
  |  Branch (531:25): [True: 0, False: 0]
  ------------------
  532|      0|          return 0;  // word <= condition
  533|      0|        break;
  534|      0|      case '.':
  ------------------
  |  Branch (534:7): [True: 0, False: 16]
  ------------------
  535|      0|        if (!pos) {
  ------------------
  |  Branch (535:13): [True: 0, False: 0]
  ------------------
  536|       |          // dots are not metacharacters in groups: [.]
  537|      0|          p = nextchar(p);
  538|       |          // skip the next character
  539|      0|          for (st--; (opts & aeUTF8) && (st >= beg) && is_utf8_cont(*st);
  ------------------
  |  |   66|      0|#define aeUTF8 (1 << 1)
  ------------------
  |  Branch (539:22): [True: 0, False: 0]
  |  Branch (539:41): [True: 0, False: 0]
  |  Branch (539:56): [True: 0, False: 0]
  ------------------
  540|      0|               st--)
  541|      0|            ;
  542|      0|          if (st < beg) {  // word <= condition
  ------------------
  |  Branch (542:15): [True: 0, False: 0]
  ------------------
  543|      0|            if (p)
  ------------------
  |  Branch (543:17): [True: 0, False: 0]
  ------------------
  544|      0|              return 0;
  545|      0|            else
  546|      0|              return 1;
  547|      0|          }
  548|      0|          if ((opts & aeUTF8) && (*st & 0x80)) {  // head of the UTF-8 character
  ------------------
  |  |   66|      0|#define aeUTF8 (1 << 1)
  ------------------
  |  Branch (548:15): [True: 0, False: 0]
  |  Branch (548:34): [True: 0, False: 0]
  ------------------
  549|      0|            st--;
  550|      0|            if (st < beg) {  // word <= condition
  ------------------
  |  Branch (550:17): [True: 0, False: 0]
  ------------------
  551|      0|              if (p)
  ------------------
  |  Branch (551:19): [True: 0, False: 0]
  ------------------
  552|      0|                return 0;
  553|      0|              else
  554|      0|                return 1;
  555|      0|            }
  556|      0|          }
  557|      0|          break;
  558|      0|        }
  559|       |      /* FALLTHROUGH */
  560|     12|      default: {
  ------------------
  |  Branch (560:7): [True: 12, False: 4]
  ------------------
  561|     12|        if (*st == *p) {
  ------------------
  |  Branch (561:13): [True: 0, False: 12]
  ------------------
  562|      0|          p = nextchar(p);
  563|      0|          if ((opts & aeUTF8) && (*st & 0x80)) {
  ------------------
  |  |   66|      0|#define aeUTF8 (1 << 1)
  ------------------
  |  Branch (563:15): [True: 0, False: 0]
  |  Branch (563:34): [True: 0, False: 0]
  ------------------
  564|      0|            st--;
  565|      0|            while (p && (st >= beg)) {
  ------------------
  |  Branch (565:20): [True: 0, False: 0]
  |  Branch (565:25): [True: 0, False: 0]
  ------------------
  566|      0|              if (*p != *st) {
  ------------------
  |  Branch (566:19): [True: 0, False: 0]
  ------------------
  567|      0|                if (!pos)
  ------------------
  |  Branch (567:21): [True: 0, False: 0]
  ------------------
  568|      0|                  return 0;
  569|      0|                st = pos;
  570|      0|                break;
  571|      0|              }
  572|       |              // first byte of the UTF-8 multibyte character
  573|      0|              if (!is_utf8_cont(*p))
  ------------------
  |  Branch (573:19): [True: 0, False: 0]
  ------------------
  574|      0|                break;
  575|      0|              p = nextchar(p);
  576|      0|              st--;
  577|      0|            }
  578|      0|            if (pos && st != pos) {
  ------------------
  |  Branch (578:17): [True: 0, False: 0]
  |  Branch (578:24): [True: 0, False: 0]
  ------------------
  579|      0|              if (neg)
  ------------------
  |  Branch (579:19): [True: 0, False: 0]
  ------------------
  580|      0|                return 0;
  581|      0|              else if (i == numconds)
  ------------------
  |  Branch (581:24): [True: 0, False: 0]
  ------------------
  582|      0|                return 1;
  583|      0|              ingroup = true;
  584|      0|              while (p && *p != ']' && ((p = nextchar(p)) != nullptr)) {
  ------------------
  |  Branch (584:22): [True: 0, False: 0]
  |  Branch (584:27): [True: 0, False: 0]
  |  Branch (584:40): [True: 0, False: 0]
  ------------------
  585|      0|              }
  586|      0|              st--;
  587|      0|            }
  588|      0|            if (p && *p != ']')
  ------------------
  |  Branch (588:17): [True: 0, False: 0]
  |  Branch (588:22): [True: 0, False: 0]
  ------------------
  589|      0|              p = nextchar(p);
  590|      0|          } else if (pos) {
  ------------------
  |  Branch (590:22): [True: 0, False: 0]
  ------------------
  591|      0|            if (neg)
  ------------------
  |  Branch (591:17): [True: 0, False: 0]
  ------------------
  592|      0|              return 0;
  593|      0|            else if (i == numconds)
  ------------------
  |  Branch (593:22): [True: 0, False: 0]
  ------------------
  594|      0|              return 1;
  595|      0|            ingroup = true;
  596|      0|            while (p && *p != ']' && ((p = nextchar(p)) != nullptr)) {
  ------------------
  |  Branch (596:20): [True: 0, False: 0]
  |  Branch (596:25): [True: 0, False: 0]
  |  Branch (596:38): [True: 0, False: 0]
  ------------------
  597|      0|            }
  598|       |            // if (p && *p != ']') p = nextchar(p);
  599|      0|            st--;
  600|      0|          }
  601|      0|          if (!pos) {
  ------------------
  |  Branch (601:15): [True: 0, False: 0]
  ------------------
  602|      0|            i++;
  603|      0|            st--;
  604|      0|          }
  605|      0|          if (st < beg && p && *p != ']')
  ------------------
  |  Branch (605:15): [True: 0, False: 0]
  |  Branch (605:27): [True: 0, False: 0]
  |  Branch (605:32): [True: 0, False: 0]
  ------------------
  606|      0|            return 0;      // word <= condition
  607|     12|        } else if (pos) {  // group
  ------------------
  |  Branch (607:20): [True: 12, False: 0]
  ------------------
  608|     12|          p = nextchar(p);
  609|     12|        } else
  610|      0|          return 0;
  611|     12|      }
  612|     16|    }
  613|     14|    if (!p)
  ------------------
  |  Branch (613:9): [True: 0, False: 14]
  ------------------
  614|      0|      return 1;
  615|     14|  }
  616|      2|}
_ZN8SfxEntry8nextcharEPc:
  481|     14|inline char* SfxEntry::nextchar(char* p) {
  482|     14|  if (p) {
  ------------------
  |  Branch (482:7): [True: 14, False: 0]
  ------------------
  483|     14|    p++;
  484|     14|    if (opts & aeLONGCOND) {
  ------------------
  |  |   69|     14|#define aeLONGCOND (1 << 4)
  ------------------
  |  Branch (484:9): [True: 0, False: 14]
  ------------------
  485|       |      // jump to the 2nd part of the condition
  486|      0|      if (p == c.l.conds1 + MAXCONDLEN_1)
  ------------------
  |  |   91|      0|#define MAXCONDLEN_1 (MAXCONDLEN - sizeof(char*))
  |  |  ------------------
  |  |  |  |   90|      0|#define MAXCONDLEN 20
  |  |  ------------------
  ------------------
  |  Branch (486:11): [True: 0, False: 0]
  ------------------
  487|      0|        return c.l.conds2;
  488|       |      // end of the MAXCONDLEN length condition
  489|     14|    } else if (p == c.conds + MAXCONDLEN)
  ------------------
  |  |   90|     14|#define MAXCONDLEN 20
  ------------------
  |  Branch (489:16): [True: 0, False: 14]
  ------------------
  490|      0|      return nullptr;
  491|     14|    return *p ? p : nullptr;
  ------------------
  |  Branch (491:12): [True: 14, False: 0]
  ------------------
  492|     14|  }
  493|      0|  return nullptr;
  494|     14|}

_ZN8PfxEntry7getNextEv:
  134|  2.34M|  inline PfxEntry* getNext() { return next; }
_ZN8SfxEntry7getNextEv:
  216|    228|  inline SfxEntry* getNext() { return next; }
_ZN8PfxEntry6getKeyEv:
  124|  76.5k|  const char* getKey() { return appnd.c_str(); }
_ZN8PfxEntry7getFlagEv:
  123|    782|  FLAG getFlag() { return aflag; }
_ZN8PfxEntry9setFlgNxtEPS_:
  142|      8|  inline void setFlgNxt(PfxEntry* ptr) { flgnxt = ptr; }
_ZN8PfxEntry7setNextEPS_:
  139|      8|  inline void setNext(PfxEntry* ptr) { next = ptr; }
_ZN8PfxEntry9setNextEQEPS_:
  141|     14|  inline void setNextEQ(PfxEntry* ptr) { nexteq = ptr; }
_ZN8PfxEntry9setNextNEEPS_:
  140|     16|  inline void setNextNE(PfxEntry* ptr) { nextne = ptr; }
_ZN8PfxEntry9getNextEQEv:
  136|  53.7k|  inline PfxEntry* getNextEQ() { return nexteq; }
_ZN8PfxEntry9getNextNEEv:
  135|  22.0k|  inline PfxEntry* getNextNE() { return nextne; }
_ZN8SfxEntry6getKeyEv:
  205|   397k|  const char* getKey() { return rappnd.c_str(); }
_ZN8SfxEntry7getFlagEv:
  204|   119k|  FLAG getFlag() { return aflag; }
_ZN8SfxEntry9setFlgNxtEPS_:
  228|     34|  inline void setFlgNxt(SfxEntry* ptr) { flgnxt = ptr; }
_ZN8SfxEntry7setNextEPS_:
  225|     34|  inline void setNext(SfxEntry* ptr) { next = ptr; }
_ZN8SfxEntry9setNextEQEPS_:
  227|     88|  inline void setNextEQ(SfxEntry* ptr) { nexteq = ptr; }
_ZN8SfxEntry9setNextNEEPS_:
  226|     80|  inline void setNextNE(SfxEntry* ptr) { nextne = ptr; }
_ZN8SfxEntry9getNextEQEv:
  218|   345k|  inline SfxEntry* getNextEQ() { return nexteq; }
_ZN8SfxEntry9getNextNEEv:
  217|  52.1k|  inline SfxEntry* getNextNE() { return nextne; }
_ZN8PfxEntry7getContEv:
  131|  3.59M|  inline const unsigned short* getCont() { return contclass; }
_ZN8PfxEntry10getContLenEv:
  132|  1.19M|  inline unsigned short getContLen() { return contclasslen; }
_ZN8SfxEntry7getContEv:
  210|   430k|  inline const unsigned short* getCont() { return contclass; }
_ZN8SfxEntry10getContLenEv:
  211|  39.5k|  inline unsigned short getContLen() { return contclasslen; }
_ZN8SfxEntry9getKeyLenEv:
  214|   162k|  inline int getKeyLen() { return appnd.size(); }
_ZN8SfxEntry9getFlgNxtEv:
  223|  62.8k|  inline SfxEntry* getFlgNxt() { return flgnxt; }
_ZN8SfxEntry8getAffixEv:
  212|  36.3k|  inline const char* getAffix() { return appnd.c_str(); }
_ZNK8SfxEntry10allowCrossEv:
  171|     35|  bool allowCross() const { return ((opts & aeXPRODUCT) != 0); }
  ------------------
  |  |   65|     35|#define aeXPRODUCT (1 << 0)
  ------------------
_ZNK8PfxEntry10allowCrossEv:
   94|      3|  bool allowCross() const { return ((opts & aeXPRODUCT) != 0); }
  ------------------
  |  |   65|      3|#define aeXPRODUCT (1 << 0)
  ------------------
_ZN8PfxEntry9getKeyLenEv:
  127|  2.32k|  inline int getKeyLen() { return appnd.size(); }
_ZN8PfxEntry9getFlgNxtEv:
  137|    774|  inline PfxEntry* getFlgNxt() { return flgnxt; }

_ZN8AffixMgrC2EPKcRKNSt3__16vectorINS2_10unique_ptrI7HashMgrNS2_14default_deleteIS5_EEEENS2_9allocatorIS8_EEEES1_:
   93|     38|  : alldic(ptr)
   94|     38|  , pHMgr(ptr[0].get()) {
   95|       |
   96|       |  // register hash manager and load affix data from aff file
   97|     38|  csconv = nullptr;
   98|     38|  utf8 = 0;
   99|     38|  complexprefixes = 0;
  100|     38|  parsedmaptable = false;
  101|     38|  parsedbreaktable = false;
  102|     38|  iconvtable = nullptr;
  103|     38|  oconvtable = nullptr;
  104|       |  // allow simplified compound forms (see 3rd field of CHECKCOMPOUNDPATTERN)
  105|     38|  simplifiedcpd = 0;
  106|     38|  parsedcheckcpd = false;
  107|     38|  parseddefcpd = false;
  108|     38|  phone = nullptr;
  109|     38|  compoundflag = FLAG_NULL;        // permits word in compound forms
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  110|     38|  compoundbegin = FLAG_NULL;       // may be first word in compound forms
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  111|     38|  compoundmiddle = FLAG_NULL;      // may be middle word in compound forms
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  112|     38|  compoundend = FLAG_NULL;         // may be last word in compound forms
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  113|     38|  compoundroot = FLAG_NULL;        // compound word signing flag
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  114|     38|  compoundpermitflag = FLAG_NULL;  // compound permitting flag for suffixed word
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  115|     38|  compoundforbidflag = FLAG_NULL;  // compound fordidden flag for suffixed word
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  116|     38|  compoundmoresuffixes = 0;        // allow more suffixes within compound words
  117|     38|  checkcompounddup = 0;            // forbid double words in compounds
  118|     38|  checkcompoundrep = 0;  // forbid bad compounds (may be non-compound word with
  119|       |                         // a REP substitution)
  120|     38|  checkcompoundcase =
  121|     38|      0;  // forbid upper and lowercase combinations at word bounds
  122|     38|  checkcompoundtriple = 0;  // forbid compounds with triple letters
  123|     38|  simplifiedtriple = 0;     // allow simplified triple letters in compounds
  124|       |                            // (Schiff+fahrt -> Schiffahrt)
  125|     38|  forbiddenword = FORBIDDENWORD;  // forbidden word signing flag
  ------------------
  |  |  127|     38|#define FORBIDDENWORD 65510
  ------------------
  126|     38|  nosuggest = FLAG_NULL;  // don't suggest words signed with NOSUGGEST flag
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  127|     38|  nongramsuggest = FLAG_NULL;
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  128|     38|  langnum = 0;  // language code (see http://l10n.openoffice.org/languages.html)
  129|     38|  needaffix = FLAG_NULL;  // forbidden root, allowed only with suffixes
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  130|     38|  cpdwordmax = -1;        // default: unlimited wordcount in compound words
  131|     38|  cpdmin = -1;            // undefined
  132|     38|  cpdmaxsyllable = 0;     // default: unlimited syllablecount in compound words
  133|     38|  pfxappnd = nullptr;     // previous prefix for counting syllables of the prefix BUG
  134|     38|  sfxappnd = nullptr;     // previous suffix for counting syllables of the suffix BUG
  135|     38|  sfxextra = 0;     // modifier for syllable count of sfxappnd BUG
  136|     38|  checknum = 0;               // checking numbers, and word with numbers
  137|     38|  havecontclass = 0;  // flags of possible continuing classes (double affix)
  138|       |  // LEMMA_PRESENT: not put root into the morphological output. Lemma presents
  139|       |  // in morhological description in dictionary file. It's often combined with
  140|       |  // PSEUDOROOT.
  141|     38|  lemma_present = FLAG_NULL;
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  142|     38|  circumfix = FLAG_NULL;
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  143|     38|  onlyincompound = FLAG_NULL;
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  144|     38|  maxngramsugs = -1;  // undefined
  145|     38|  maxdiff = -1;       // undefined
  146|     38|  onlymaxdiff = 0;
  147|     38|  maxcpdsugs = -1;  // undefined
  148|     38|  nosplitsugs = 0;
  149|     38|  sugswithdots = 0;
  150|     38|  keepcase = 0;
  151|     38|  forceucase = 0;
  152|     38|  warn = 0;
  153|     38|  forbidwarn = 0;
  154|     38|  checksharps = 0;
  155|     38|  substandard = FLAG_NULL;
  ------------------
  |  |   96|     38|#define FLAG_NULL 0x00
  ------------------
  156|     38|  fullstrip = 0;
  157|       |
  158|     38|  sfx = nullptr;
  159|     38|  pfx = nullptr;
  160|       |
  161|  9.76k|  for (int i = 0; i < SETSIZE; i++) {
  ------------------
  |  |   61|  9.76k|#define SETSIZE 256
  ------------------
  |  Branch (161:19): [True: 9.72k, False: 38]
  ------------------
  162|  9.72k|    pStart[i] = nullptr;
  163|  9.72k|    sStart[i] = nullptr;
  164|  9.72k|    pFlag[i] = nullptr;
  165|  9.72k|    sFlag[i] = nullptr;
  166|  9.72k|  }
  167|       |
  168|     38|  memset(contclasses, 0, CONTSIZE * sizeof(char));
  ------------------
  |  |   62|     38|#define CONTSIZE 65536
  ------------------
  169|       |
  170|     38|  if (parse_file(affpath, key)) {
  ------------------
  |  Branch (170:7): [True: 0, False: 38]
  ------------------
  171|      0|    fprintf(stderr, "Failure loading aff file %s\n", affpath);
  172|      0|  }
  173|       |
  174|       |  /* get encoding for CHECKCOMPOUNDCASE */
  175|     38|  if (!utf8) {
  ------------------
  |  Branch (175:7): [True: 20, False: 18]
  ------------------
  176|     20|    csconv = get_current_cs(get_encoding());
  177|  5.14k|    for (int i = 0; i <= 255; i++) {
  ------------------
  |  Branch (177:21): [True: 5.12k, False: 20]
  ------------------
  178|  5.12k|      if ((csconv[i].cupper != csconv[i].clower) &&
  ------------------
  |  Branch (178:11): [True: 2.24k, False: 2.88k]
  ------------------
  179|  2.24k|          (wordchars.find((char)i) == std::string::npos)) {
  ------------------
  |  Branch (179:11): [True: 2.24k, False: 0]
  ------------------
  180|  2.24k|        wordchars.push_back((char)i);
  181|  2.24k|      }
  182|  5.12k|    }
  183|     20|  }
  184|       |
  185|       |  // default BREAK definition
  186|     38|  if (!parsedbreaktable) {
  ------------------
  |  Branch (186:7): [True: 34, False: 4]
  ------------------
  187|     34|    breaktable.emplace_back("-");
  188|     34|    breaktable.emplace_back("^-");
  189|     34|    breaktable.emplace_back("-$");
  190|     34|    parsedbreaktable = true;
  191|     34|  }
  192|       |
  193|     38|#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
  194|       |  // not entirely sure this is invalid, so only for fuzzing for now
  195|     38|  if (iconvtable && !iconvtable->check_against_breaktable(breaktable)) {
  ------------------
  |  Branch (195:7): [True: 2, False: 36]
  |  Branch (195:21): [True: 0, False: 2]
  ------------------
  196|      0|      delete iconvtable;
  197|      0|      iconvtable = nullptr;
  198|      0|  }
  199|     38|#endif
  200|       |
  201|     38|  if (cpdmin == -1)
  ------------------
  |  Branch (201:7): [True: 34, False: 4]
  ------------------
  202|     34|    cpdmin = MINCPDLEN;
  ------------------
  |  |   88|     34|#define MINCPDLEN 3
  ------------------
  203|     38|}
_ZN8AffixMgr13finishFileMgrEP7FileMgr:
  260|     38|void AffixMgr::finishFileMgr(FileMgr* afflst) {
  261|     38|  delete afflst;
  262|       |
  263|       |  // convert affix trees to sorted list
  264|     38|  process_pfx_tree_to_list();
  265|     38|  process_sfx_tree_to_list();
  266|     38|}
_ZN8AffixMgr10parse_fileEPKcS1_:
  269|     38|int AffixMgr::parse_file(const char* affpath, const char* key) {
  270|       |
  271|       |  // checking flag duplication
  272|     38|  char dupflags[CONTSIZE];
  273|     38|  char dupflags_ini = 1;
  274|       |
  275|       |  // first line indicator for removing byte order mark
  276|     38|  int firstline = 1;
  277|       |
  278|       |  // open the affix file
  279|     38|  FileMgr* afflst = new FileMgr(affpath, key);
  280|       |
  281|       |  // step one is to parse the affix file building up the internal
  282|       |  // affix data structures
  283|       |
  284|       |  // read in each line ignoring any that do not
  285|       |  // start with a known line type indicator
  286|     38|  std::string line;
  287|    646|  while (afflst->getline(line)) {
  ------------------
  |  Branch (287:10): [True: 608, False: 38]
  ------------------
  288|    608|    mychomp(line);
  289|       |
  290|       |    /* remove byte order mark */
  291|    608|    if (firstline) {
  ------------------
  |  Branch (291:9): [True: 38, False: 570]
  ------------------
  292|     38|      firstline = 0;
  293|       |      // Affix file begins with byte order mark: possible incompatibility with
  294|       |      // old Hunspell versions
  295|     38|      if (line.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
  ------------------
  |  Branch (295:11): [True: 0, False: 38]
  ------------------
  296|      0|        line.erase(0, 3);
  297|      0|      }
  298|     38|    }
  299|       |
  300|       |    /* parse in the keyboard string */
  301|    608|    if (line.compare(0, 3, "KEY", 3) == 0) {
  ------------------
  |  Branch (301:9): [True: 0, False: 608]
  ------------------
  302|      0|      if (!parse_string(line, keystring, afflst->getlinenum())) {
  ------------------
  |  Branch (302:11): [True: 0, False: 0]
  ------------------
  303|      0|        finishFileMgr(afflst);
  304|      0|        return 1;
  305|      0|      }
  306|      0|    }
  307|       |
  308|       |    /* parse in the try string */
  309|    608|    if (line.compare(0, 3, "TRY", 3) == 0) {
  ------------------
  |  Branch (309:9): [True: 2, False: 606]
  ------------------
  310|      2|      if (!parse_string(line, trystring, afflst->getlinenum())) {
  ------------------
  |  Branch (310:11): [True: 0, False: 2]
  ------------------
  311|      0|        finishFileMgr(afflst);
  312|      0|        return 1;
  313|      0|      }
  314|      2|    }
  315|       |
  316|       |    /* parse in the name of the character set used by the .dict and .aff */
  317|    608|    if (line.compare(0, 3, "SET", 3) == 0) {
  ------------------
  |  Branch (317:9): [True: 18, False: 590]
  ------------------
  318|     18|      if (!parse_string(line, encoding, afflst->getlinenum())) {
  ------------------
  |  Branch (318:11): [True: 0, False: 18]
  ------------------
  319|      0|        finishFileMgr(afflst);
  320|      0|        return 1;
  321|      0|      }
  322|     18|      if (encoding == "UTF-8") {
  ------------------
  |  Branch (322:11): [True: 18, False: 0]
  ------------------
  323|     18|        utf8 = 1;
  324|     18|      }
  325|     18|    }
  326|       |
  327|       |    /* parse COMPLEXPREFIXES for agglutinative languages with right-to-left
  328|       |     * writing system */
  329|    608|    if (line.compare(0, 15, "COMPLEXPREFIXES", 15) == 0)
  ------------------
  |  Branch (329:9): [True: 2, False: 606]
  ------------------
  330|      2|      complexprefixes = 1;
  331|       |
  332|       |    /* parse in the flag used by the controlled compound words */
  333|    608|    if (line.compare(0, 12, "COMPOUNDFLAG", 12) == 0) {
  ------------------
  |  Branch (333:9): [True: 8, False: 600]
  ------------------
  334|      8|      if (!parse_flag(line, &compoundflag, afflst)) {
  ------------------
  |  Branch (334:11): [True: 0, False: 8]
  ------------------
  335|      0|        finishFileMgr(afflst);
  336|      0|        return 1;
  337|      0|      }
  338|      8|    }
  339|       |
  340|       |    /* parse in the flag used by compound words */
  341|    608|    if (line.compare(0, 13, "COMPOUNDBEGIN", 13) == 0) {
  ------------------
  |  Branch (341:9): [True: 0, False: 608]
  ------------------
  342|      0|      if (complexprefixes) {
  ------------------
  |  Branch (342:11): [True: 0, False: 0]
  ------------------
  343|      0|        if (!parse_flag(line, &compoundend, afflst)) {
  ------------------
  |  Branch (343:13): [True: 0, False: 0]
  ------------------
  344|      0|          finishFileMgr(afflst);
  345|      0|          return 1;
  346|      0|        }
  347|      0|      } else {
  348|      0|        if (!parse_flag(line, &compoundbegin, afflst)) {
  ------------------
  |  Branch (348:13): [True: 0, False: 0]
  ------------------
  349|      0|          finishFileMgr(afflst);
  350|      0|          return 1;
  351|      0|        }
  352|      0|      }
  353|      0|    }
  354|       |
  355|       |    /* parse in the flag used by compound words */
  356|    608|    if (line.compare(0, 14, "COMPOUNDMIDDLE", 14) == 0) {
  ------------------
  |  Branch (356:9): [True: 0, False: 608]
  ------------------
  357|      0|      if (!parse_flag(line, &compoundmiddle, afflst)) {
  ------------------
  |  Branch (357:11): [True: 0, False: 0]
  ------------------
  358|      0|        finishFileMgr(afflst);
  359|      0|        return 1;
  360|      0|      }
  361|      0|    }
  362|       |
  363|       |    /* parse in the flag used by compound words */
  364|    608|    if (line.compare(0, 11, "COMPOUNDEND", 11) == 0) {
  ------------------
  |  Branch (364:9): [True: 0, False: 608]
  ------------------
  365|      0|      if (complexprefixes) {
  ------------------
  |  Branch (365:11): [True: 0, False: 0]
  ------------------
  366|      0|        if (!parse_flag(line, &compoundbegin, afflst)) {
  ------------------
  |  Branch (366:13): [True: 0, False: 0]
  ------------------
  367|      0|          finishFileMgr(afflst);
  368|      0|          return 1;
  369|      0|        }
  370|      0|      } else {
  371|      0|        if (!parse_flag(line, &compoundend, afflst)) {
  ------------------
  |  Branch (371:13): [True: 0, False: 0]
  ------------------
  372|      0|          finishFileMgr(afflst);
  373|      0|          return 1;
  374|      0|        }
  375|      0|      }
  376|      0|    }
  377|       |
  378|       |    /* parse in the data used by compound_check() method */
  379|    608|    if (line.compare(0, 15, "COMPOUNDWORDMAX", 15) == 0) {
  ------------------
  |  Branch (379:9): [True: 2, False: 606]
  ------------------
  380|      2|      if (!parse_num(line, &cpdwordmax, afflst)) {
  ------------------
  |  Branch (380:11): [True: 0, False: 2]
  ------------------
  381|      0|        finishFileMgr(afflst);
  382|      0|        return 1;
  383|      0|      }
  384|      2|    }
  385|       |
  386|       |    /* parse in the flag sign compounds in dictionary */
  387|    608|    if (line.compare(0, 12, "COMPOUNDROOT", 12) == 0) {
  ------------------
  |  Branch (387:9): [True: 0, False: 608]
  ------------------
  388|      0|      if (!parse_flag(line, &compoundroot, afflst)) {
  ------------------
  |  Branch (388:11): [True: 0, False: 0]
  ------------------
  389|      0|        finishFileMgr(afflst);
  390|      0|        return 1;
  391|      0|      }
  392|      0|    }
  393|       |
  394|       |    /* parse in the flag used by compound_check() method */
  395|    608|    if (line.compare(0, 18, "COMPOUNDPERMITFLAG", 18) == 0) {
  ------------------
  |  Branch (395:9): [True: 2, False: 606]
  ------------------
  396|      2|      if (!parse_flag(line, &compoundpermitflag, afflst)) {
  ------------------
  |  Branch (396:11): [True: 0, False: 2]
  ------------------
  397|      0|        finishFileMgr(afflst);
  398|      0|        return 1;
  399|      0|      }
  400|      2|    }
  401|       |
  402|       |    /* parse in the flag used by compound_check() method */
  403|    608|    if (line.compare(0, 18, "COMPOUNDFORBIDFLAG", 18) == 0) {
  ------------------
  |  Branch (403:9): [True: 2, False: 606]
  ------------------
  404|      2|      if (!parse_flag(line, &compoundforbidflag, afflst)) {
  ------------------
  |  Branch (404:11): [True: 0, False: 2]
  ------------------
  405|      0|        finishFileMgr(afflst);
  406|      0|        return 1;
  407|      0|      }
  408|      2|    }
  409|       |
  410|    608|    if (line.compare(0, 20, "COMPOUNDMORESUFFIXES", 20) == 0) {
  ------------------
  |  Branch (410:9): [True: 0, False: 608]
  ------------------
  411|      0|      compoundmoresuffixes = 1;
  412|      0|    }
  413|       |
  414|    608|    if (line.compare(0, 16, "CHECKCOMPOUNDDUP", 16) == 0) {
  ------------------
  |  Branch (414:9): [True: 0, False: 608]
  ------------------
  415|      0|      checkcompounddup = 1;
  416|      0|    }
  417|       |
  418|    608|    if (line.compare(0, 16, "CHECKCOMPOUNDREP", 16) == 0) {
  ------------------
  |  Branch (418:9): [True: 2, False: 606]
  ------------------
  419|      2|      checkcompoundrep = 1;
  420|      2|    }
  421|       |
  422|    608|    if (line.compare(0, 19, "CHECKCOMPOUNDTRIPLE", 19) == 0) {
  ------------------
  |  Branch (422:9): [True: 0, False: 608]
  ------------------
  423|      0|      checkcompoundtriple = 1;
  424|      0|    }
  425|       |
  426|    608|    if (line.compare(0, 16, "SIMPLIFIEDTRIPLE", 16) == 0) {
  ------------------
  |  Branch (426:9): [True: 0, False: 608]
  ------------------
  427|      0|      simplifiedtriple = 1;
  428|      0|    }
  429|       |
  430|    608|    if (line.compare(0, 17, "CHECKCOMPOUNDCASE", 17) == 0) {
  ------------------
  |  Branch (430:9): [True: 0, False: 608]
  ------------------
  431|      0|      checkcompoundcase = 1;
  432|      0|    }
  433|       |
  434|    608|    if (line.compare(0, 9, "NOSUGGEST", 9) == 0) {
  ------------------
  |  Branch (434:9): [True: 0, False: 608]
  ------------------
  435|      0|      if (!parse_flag(line, &nosuggest, afflst)) {
  ------------------
  |  Branch (435:11): [True: 0, False: 0]
  ------------------
  436|      0|        finishFileMgr(afflst);
  437|      0|        return 1;
  438|      0|      }
  439|      0|    }
  440|       |
  441|    608|    if (line.compare(0, 14, "NONGRAMSUGGEST", 14) == 0) {
  ------------------
  |  Branch (441:9): [True: 0, False: 608]
  ------------------
  442|      0|      if (!parse_flag(line, &nongramsuggest, afflst)) {
  ------------------
  |  Branch (442:11): [True: 0, False: 0]
  ------------------
  443|      0|        finishFileMgr(afflst);
  444|      0|        return 1;
  445|      0|      }
  446|      0|    }
  447|       |
  448|       |    /* parse in the flag used by forbidden words */
  449|    608|    if (line.compare(0, 13, "FORBIDDENWORD", 13) == 0) {
  ------------------
  |  Branch (449:9): [True: 2, False: 606]
  ------------------
  450|      2|      if (!parse_flag(line, &forbiddenword, afflst)) {
  ------------------
  |  Branch (450:11): [True: 0, False: 2]
  ------------------
  451|      0|        finishFileMgr(afflst);
  452|      0|        return 1;
  453|      0|      }
  454|      2|    }
  455|       |
  456|       |    /* parse in the flag used by forbidden words (is deprecated) */
  457|    608|    if (line.compare(0, 13, "LEMMA_PRESENT", 13) == 0) {
  ------------------
  |  Branch (457:9): [True: 0, False: 608]
  ------------------
  458|      0|      if (!parse_flag(line, &lemma_present, afflst)) {
  ------------------
  |  Branch (458:11): [True: 0, False: 0]
  ------------------
  459|      0|        finishFileMgr(afflst);
  460|      0|        return 1;
  461|      0|      }
  462|      0|    }
  463|       |
  464|       |    /* parse in the flag used by circumfixes */
  465|    608|    if (line.compare(0, 9, "CIRCUMFIX", 9) == 0) {
  ------------------
  |  Branch (465:9): [True: 2, False: 606]
  ------------------
  466|      2|      if (!parse_flag(line, &circumfix, afflst)) {
  ------------------
  |  Branch (466:11): [True: 0, False: 2]
  ------------------
  467|      0|        finishFileMgr(afflst);
  468|      0|        return 1;
  469|      0|      }
  470|      2|    }
  471|       |
  472|       |    /* parse in the flag used by fogemorphemes */
  473|    608|    if (line.compare(0, 14, "ONLYINCOMPOUND", 14) == 0) {
  ------------------
  |  Branch (473:9): [True: 0, False: 608]
  ------------------
  474|      0|      if (!parse_flag(line, &onlyincompound, afflst)) {
  ------------------
  |  Branch (474:11): [True: 0, False: 0]
  ------------------
  475|      0|        finishFileMgr(afflst);
  476|      0|        return 1;
  477|      0|      }
  478|      0|    }
  479|       |
  480|       |    /* parse in the flag used by `needaffixs' (is deprecated) */
  481|    608|    if (line.compare(0, 10, "PSEUDOROOT", 10) == 0) {
  ------------------
  |  Branch (481:9): [True: 0, False: 608]
  ------------------
  482|      0|      if (!parse_flag(line, &needaffix, afflst)) {
  ------------------
  |  Branch (482:11): [True: 0, False: 0]
  ------------------
  483|      0|        finishFileMgr(afflst);
  484|      0|        return 1;
  485|      0|      }
  486|      0|    }
  487|       |
  488|       |    /* parse in the flag used by `needaffixs' */
  489|    608|    if (line.compare(0, 9, "NEEDAFFIX", 9) == 0) {
  ------------------
  |  Branch (489:9): [True: 2, False: 606]
  ------------------
  490|      2|      if (!parse_flag(line, &needaffix, afflst)) {
  ------------------
  |  Branch (490:11): [True: 0, False: 2]
  ------------------
  491|      0|        finishFileMgr(afflst);
  492|      0|        return 1;
  493|      0|      }
  494|      2|    }
  495|       |
  496|       |    /* parse in the minimal length for words in compounds */
  497|    608|    if (line.compare(0, 11, "COMPOUNDMIN", 11) == 0) {
  ------------------
  |  Branch (497:9): [True: 4, False: 604]
  ------------------
  498|      4|      if (!parse_num(line, &cpdmin, afflst)) {
  ------------------
  |  Branch (498:11): [True: 0, False: 4]
  ------------------
  499|      0|        finishFileMgr(afflst);
  500|      0|        return 1;
  501|      0|      }
  502|      4|      if (cpdmin < 1)
  ------------------
  |  Branch (502:11): [True: 0, False: 4]
  ------------------
  503|      0|        cpdmin = 1;
  504|      4|    }
  505|       |
  506|       |    /* parse in the max. words and syllables in compounds */
  507|    608|    if (line.compare(0, 16, "COMPOUNDSYLLABLE", 16) == 0) {
  ------------------
  |  Branch (507:9): [True: 2, False: 606]
  ------------------
  508|      2|      if (!parse_cpdsyllable(line, afflst)) {
  ------------------
  |  Branch (508:11): [True: 0, False: 2]
  ------------------
  509|      0|        finishFileMgr(afflst);
  510|      0|        return 1;
  511|      0|      }
  512|      2|    }
  513|       |
  514|       |    /* parse in the flag used by compound_check() method */
  515|    608|    if (line.compare(0, 11, "SYLLABLENUM", 11) == 0) {
  ------------------
  |  Branch (515:9): [True: 0, False: 608]
  ------------------
  516|      0|      if (!parse_string(line, cpdsyllablenum, afflst->getlinenum())) {
  ------------------
  |  Branch (516:11): [True: 0, False: 0]
  ------------------
  517|      0|        finishFileMgr(afflst);
  518|      0|        return 1;
  519|      0|      }
  520|      0|    }
  521|       |
  522|       |    /* parse in the flag used by the controlled compound words */
  523|    608|    if (line.compare(0, 8, "CHECKNUM", 8) == 0) {
  ------------------
  |  Branch (523:9): [True: 0, False: 608]
  ------------------
  524|      0|      checknum = 1;
  525|      0|    }
  526|       |
  527|       |    /* parse in the extra word characters */
  528|    608|    if (line.compare(0, 9, "WORDCHARS", 9) == 0) {
  ------------------
  |  Branch (528:9): [True: 6, False: 602]
  ------------------
  529|      6|      if (!parse_array(line, wordchars, wordchars_utf16,
  ------------------
  |  Branch (529:11): [True: 0, False: 6]
  ------------------
  530|      6|                       utf8, afflst->getlinenum())) {
  531|      0|        finishFileMgr(afflst);
  532|      0|        return 1;
  533|      0|      }
  534|      6|    }
  535|       |
  536|       |    /* parse in the ignored characters (for example, Arabic optional diacretics
  537|       |     * charachters */
  538|    608|    if (line.compare(0, 6, "IGNORE", 6) == 0) {
  ------------------
  |  Branch (538:9): [True: 4, False: 604]
  ------------------
  539|      4|      if (!parse_array(line, ignorechars, ignorechars_utf16,
  ------------------
  |  Branch (539:11): [True: 0, False: 4]
  ------------------
  540|      4|                       utf8, afflst->getlinenum())) {
  541|      0|        finishFileMgr(afflst);
  542|      0|        return 1;
  543|      0|      }
  544|      4|    }
  545|       |
  546|       |    /* parse in the input conversion table */
  547|    608|    if (line.compare(0, 5, "ICONV", 5) == 0) {
  ------------------
  |  Branch (547:9): [True: 2, False: 606]
  ------------------
  548|      2|      if (!parse_convtable(line, afflst, &iconvtable, "ICONV")) {
  ------------------
  |  Branch (548:11): [True: 0, False: 2]
  ------------------
  549|      0|        finishFileMgr(afflst);
  550|      0|        return 1;
  551|      0|      }
  552|      2|    }
  553|       |
  554|       |    /* parse in the output conversion table */
  555|    608|    if (line.compare(0, 5, "OCONV", 5) == 0) {
  ------------------
  |  Branch (555:9): [True: 2, False: 606]
  ------------------
  556|      2|      if (!parse_convtable(line, afflst, &oconvtable, "OCONV")) {
  ------------------
  |  Branch (556:11): [True: 0, False: 2]
  ------------------
  557|      0|        finishFileMgr(afflst);
  558|      0|        return 1;
  559|      0|      }
  560|      2|    }
  561|       |
  562|       |    /* parse in the phonetic translation table */
  563|    608|    if (line.compare(0, 5, "PHONE", 5) == 0) {
  ------------------
  |  Branch (563:9): [True: 2, False: 606]
  ------------------
  564|      2|      if (!parse_phonetable(line, afflst)) {
  ------------------
  |  Branch (564:11): [True: 0, False: 2]
  ------------------
  565|      0|        finishFileMgr(afflst);
  566|      0|        return 1;
  567|      0|      }
  568|      2|    }
  569|       |
  570|       |    /* parse in the checkcompoundpattern table */
  571|    608|    if (line.compare(0, 20, "CHECKCOMPOUNDPATTERN", 20) == 0) {
  ------------------
  |  Branch (571:9): [True: 2, False: 606]
  ------------------
  572|      2|      if (!parse_checkcpdtable(line, afflst)) {
  ------------------
  |  Branch (572:11): [True: 0, False: 2]
  ------------------
  573|      0|        finishFileMgr(afflst);
  574|      0|        return 1;
  575|      0|      }
  576|      2|    }
  577|       |
  578|       |    /* parse in the defcompound table */
  579|    608|    if (line.compare(0, 12, "COMPOUNDRULE", 12) == 0) {
  ------------------
  |  Branch (579:9): [True: 0, False: 608]
  ------------------
  580|      0|      if (!parse_defcpdtable(line, afflst)) {
  ------------------
  |  Branch (580:11): [True: 0, False: 0]
  ------------------
  581|      0|        finishFileMgr(afflst);
  582|      0|        return 1;
  583|      0|      }
  584|      0|    }
  585|       |
  586|       |    /* parse in the related character map table */
  587|    608|    if (line.compare(0, 3, "MAP", 3) == 0) {
  ------------------
  |  Branch (587:9): [True: 2, False: 606]
  ------------------
  588|      2|      if (!parse_maptable(line, afflst)) {
  ------------------
  |  Branch (588:11): [True: 0, False: 2]
  ------------------
  589|      0|        finishFileMgr(afflst);
  590|      0|        return 1;
  591|      0|      }
  592|      2|    }
  593|       |
  594|       |    /* parse in the word breakpoints table */
  595|    608|    if (line.compare(0, 5, "BREAK", 5) == 0) {
  ------------------
  |  Branch (595:9): [True: 4, False: 604]
  ------------------
  596|      4|      if (!parse_breaktable(line, afflst)) {
  ------------------
  |  Branch (596:11): [True: 0, False: 4]
  ------------------
  597|      0|        finishFileMgr(afflst);
  598|      0|        return 1;
  599|      0|      }
  600|      4|    }
  601|       |
  602|       |    /* parse in the language for language specific codes */
  603|    608|    if (line.compare(0, 4, "LANG", 4) == 0) {
  ------------------
  |  Branch (603:9): [True: 2, False: 606]
  ------------------
  604|      2|      if (!parse_string(line, lang, afflst->getlinenum())) {
  ------------------
  |  Branch (604:11): [True: 0, False: 2]
  ------------------
  605|      0|        finishFileMgr(afflst);
  606|      0|        return 1;
  607|      0|      }
  608|      2|      langnum = get_lang_num(lang);
  609|      2|    }
  610|       |
  611|    608|    if (line.compare(0, 7, "VERSION", 7) == 0) {
  ------------------
  |  Branch (611:9): [True: 0, False: 608]
  ------------------
  612|      0|      size_t startpos = line.find_first_not_of(" \t", 7);
  613|      0|      if (startpos != std::string::npos) {
  ------------------
  |  Branch (613:11): [True: 0, False: 0]
  ------------------
  614|      0|          version = line.substr(startpos);
  615|      0|      }
  616|      0|    }
  617|       |
  618|    608|    if (line.compare(0, 12, "MAXNGRAMSUGS", 12) == 0) {
  ------------------
  |  Branch (618:9): [True: 4, False: 604]
  ------------------
  619|      4|      if (!parse_num(line, &maxngramsugs, afflst)) {
  ------------------
  |  Branch (619:11): [True: 0, False: 4]
  ------------------
  620|      0|        finishFileMgr(afflst);
  621|      0|        return 1;
  622|      0|      }
  623|      4|    }
  624|       |
  625|    608|    if (line.compare(0, 11, "ONLYMAXDIFF", 11) == 0)
  ------------------
  |  Branch (625:9): [True: 0, False: 608]
  ------------------
  626|      0|      onlymaxdiff = 1;
  627|       |
  628|    608|    if (line.compare(0, 7, "MAXDIFF", 7) == 0) {
  ------------------
  |  Branch (628:9): [True: 0, False: 608]
  ------------------
  629|      0|      if (!parse_num(line, &maxdiff, afflst)) {
  ------------------
  |  Branch (629:11): [True: 0, False: 0]
  ------------------
  630|      0|        finishFileMgr(afflst);
  631|      0|        return 1;
  632|      0|      }
  633|      0|    }
  634|       |
  635|    608|    if (line.compare(0, 10, "MAXCPDSUGS", 10) == 0) {
  ------------------
  |  Branch (635:9): [True: 0, False: 608]
  ------------------
  636|      0|      if (!parse_num(line, &maxcpdsugs, afflst)) {
  ------------------
  |  Branch (636:11): [True: 0, False: 0]
  ------------------
  637|      0|        finishFileMgr(afflst);
  638|      0|        return 1;
  639|      0|      }
  640|      0|    }
  641|       |
  642|    608|    if (line.compare(0, 11, "NOSPLITSUGS", 11) == 0) {
  ------------------
  |  Branch (642:9): [True: 0, False: 608]
  ------------------
  643|      0|      nosplitsugs = 1;
  644|      0|    }
  645|       |
  646|    608|    if (line.compare(0, 9, "FULLSTRIP", 9) == 0) {
  ------------------
  |  Branch (646:9): [True: 0, False: 608]
  ------------------
  647|      0|      fullstrip = 1;
  648|      0|    }
  649|       |
  650|    608|    if (line.compare(0, 12, "SUGSWITHDOTS", 12) == 0) {
  ------------------
  |  Branch (650:9): [True: 0, False: 608]
  ------------------
  651|      0|      sugswithdots = 1;
  652|      0|    }
  653|       |
  654|       |    /* parse in the flag used by forbidden words */
  655|    608|    if (line.compare(0, 8, "KEEPCASE", 8) == 0) {
  ------------------
  |  Branch (655:9): [True: 2, False: 606]
  ------------------
  656|      2|      if (!parse_flag(line, &keepcase, afflst)) {
  ------------------
  |  Branch (656:11): [True: 0, False: 2]
  ------------------
  657|      0|        finishFileMgr(afflst);
  658|      0|        return 1;
  659|      0|      }
  660|      2|    }
  661|       |
  662|       |    /* parse in the flag used by `forceucase' */
  663|    608|    if (line.compare(0, 10, "FORCEUCASE", 10) == 0) {
  ------------------
  |  Branch (663:9): [True: 0, False: 608]
  ------------------
  664|      0|      if (!parse_flag(line, &forceucase, afflst)) {
  ------------------
  |  Branch (664:11): [True: 0, False: 0]
  ------------------
  665|      0|        finishFileMgr(afflst);
  666|      0|        return 1;
  667|      0|      }
  668|      0|    }
  669|       |
  670|       |    /* parse in the flag used by `warn' */
  671|    608|    if (line.compare(0, 4, "WARN", 4) == 0) {
  ------------------
  |  Branch (671:9): [True: 2, False: 606]
  ------------------
  672|      2|      if (!parse_flag(line, &warn, afflst)) {
  ------------------
  |  Branch (672:11): [True: 0, False: 2]
  ------------------
  673|      0|        finishFileMgr(afflst);
  674|      0|        return 1;
  675|      0|      }
  676|      2|    }
  677|       |
  678|    608|    if (line.compare(0, 10, "FORBIDWARN", 10) == 0) {
  ------------------
  |  Branch (678:9): [True: 0, False: 608]
  ------------------
  679|      0|      forbidwarn = 1;
  680|      0|    }
  681|       |
  682|       |    /* parse in the flag used by the affix generator */
  683|    608|    if (line.compare(0, 11, "SUBSTANDARD", 11) == 0) {
  ------------------
  |  Branch (683:9): [True: 0, False: 608]
  ------------------
  684|      0|      if (!parse_flag(line, &substandard, afflst)) {
  ------------------
  |  Branch (684:11): [True: 0, False: 0]
  ------------------
  685|      0|        finishFileMgr(afflst);
  686|      0|        return 1;
  687|      0|      }
  688|      0|    }
  689|       |
  690|    608|    if (line.compare(0, 11, "CHECKSHARPS", 11) == 0) {
  ------------------
  |  Branch (690:9): [True: 0, False: 608]
  ------------------
  691|      0|      checksharps = 1;
  692|      0|    }
  693|       |
  694|       |    /* parse this affix: P - prefix, S - suffix */
  695|       |    // affix type
  696|    608|    char ft = ' ';
  697|    608|    if (line.compare(0, 3, "PFX", 3) == 0)
  ------------------
  |  Branch (697:9): [True: 12, False: 596]
  ------------------
  698|     12|      ft = complexprefixes ? 'S' : 'P';
  ------------------
  |  Branch (698:12): [True: 4, False: 8]
  ------------------
  699|    608|    if (line.compare(0, 3, "SFX", 3) == 0)
  ------------------
  |  Branch (699:9): [True: 14, False: 594]
  ------------------
  700|     14|      ft = complexprefixes ? 'P' : 'S';
  ------------------
  |  Branch (700:12): [True: 0, False: 14]
  ------------------
  701|    608|    if (ft != ' ') {
  ------------------
  |  Branch (701:9): [True: 26, False: 582]
  ------------------
  702|     26|      if (dupflags_ini) {
  ------------------
  |  Branch (702:11): [True: 18, False: 8]
  ------------------
  703|     18|        memset(dupflags, 0, sizeof(dupflags));
  704|     18|        dupflags_ini = 0;
  705|     18|      }
  706|     26|      if (!parse_affix(line, ft, afflst, dupflags)) {
  ------------------
  |  Branch (706:11): [True: 0, False: 26]
  ------------------
  707|      0|        finishFileMgr(afflst);
  708|      0|        return 1;
  709|      0|      }
  710|     26|    }
  711|    608|  }
  712|       |
  713|     38|  finishFileMgr(afflst);
  714|       |  // affix trees are sorted now
  715|       |
  716|       |  // now we can speed up performance greatly taking advantage of the
  717|       |  // relationship between the affixes and the idea of "subsets".
  718|       |
  719|       |  // View each prefix as a potential leading subset of another and view
  720|       |  // each suffix (reversed) as a potential trailing subset of another.
  721|       |
  722|       |  // To illustrate this relationship if we know the prefix "ab" is found in the
  723|       |  // word to examine, only prefixes that "ab" is a leading subset of need be
  724|       |  // examined.
  725|       |  // Furthermore is "ab" is not present then none of the prefixes that "ab" is
  726|       |  // is a subset need be examined.
  727|       |  // The same argument goes for suffix string that are reversed.
  728|       |
  729|       |  // Then to top this off why not examine the first char of the word to quickly
  730|       |  // limit the set of prefixes to examine (i.e. the prefixes to examine must
  731|       |  // be leading supersets of the first character of the word (if they exist)
  732|       |
  733|       |  // To take advantage of this "subset" relationship, we need to add two links
  734|       |  // from entry.  One to take next if the current prefix is found (call it
  735|       |  // nexteq)
  736|       |  // and one to take next if the current prefix is not found (call it nextne).
  737|       |
  738|       |  // Since we have built ordered lists, all that remains is to properly
  739|       |  // initialize
  740|       |  // the nextne and nexteq pointers that relate them
  741|       |
  742|     38|  process_pfx_order();
  743|     38|  process_sfx_order();
  744|       |
  745|     38|  return 0;
  746|     38|}
_ZN8AffixMgr13build_pfxtreeEP8PfxEntry:
  752|      8|int AffixMgr::build_pfxtree(PfxEntry* pfxptr) {
  753|      8|  PfxEntry* ptr;
  754|      8|  PfxEntry* pptr;
  755|      8|  PfxEntry* ep = pfxptr;
  756|       |
  757|       |  // get the right starting points
  758|      8|  const char* key = ep->getKey();
  759|      8|  const auto flg = (unsigned char)(ep->getFlag() & 0x00FF);
  760|       |
  761|       |  // first index by flag which must exist
  762|      8|  ptr = pFlag[flg];
  763|      8|  ep->setFlgNxt(ptr);
  764|      8|  pFlag[flg] = ep;
  765|       |
  766|       |  // handle the special case of null affix string
  767|      8|  if (*key == '\0') {
  ------------------
  |  Branch (767:7): [True: 2, False: 6]
  ------------------
  768|       |    // always inset them at head of list at element 0
  769|      2|    ptr = pStart[0];
  770|      2|    ep->setNext(ptr);
  771|      2|    pStart[0] = ep;
  772|      2|    return 0;
  773|      2|  }
  774|       |
  775|       |  // now handle the normal case
  776|      6|  ep->setNextEQ(nullptr);
  777|      6|  ep->setNextNE(nullptr);
  778|       |
  779|      6|  unsigned char sp = *((const unsigned char*)key);
  780|      6|  ptr = pStart[sp];
  781|       |
  782|       |  // handle the first insert
  783|      6|  if (!ptr) {
  ------------------
  |  Branch (783:7): [True: 4, False: 2]
  ------------------
  784|      4|    pStart[sp] = ep;
  785|      4|    return 0;
  786|      4|  }
  787|       |
  788|       |  // otherwise use binary tree insertion so that a sorted
  789|       |  // list can easily be generated later
  790|      2|  pptr = nullptr;
  791|      2|  for (;;) {
  792|      2|    pptr = ptr;
  793|      2|    if (strcmp(ep->getKey(), ptr->getKey()) <= 0) {
  ------------------
  |  Branch (793:9): [True: 0, False: 2]
  ------------------
  794|      0|      ptr = ptr->getNextEQ();
  795|      0|      if (!ptr) {
  ------------------
  |  Branch (795:11): [True: 0, False: 0]
  ------------------
  796|      0|        pptr->setNextEQ(ep);
  797|      0|        break;
  798|      0|      }
  799|      2|    } else {
  800|      2|      ptr = ptr->getNextNE();
  801|      2|      if (!ptr) {
  ------------------
  |  Branch (801:11): [True: 2, False: 0]
  ------------------
  802|      2|        pptr->setNextNE(ep);
  803|      2|        break;
  804|      2|      }
  805|      2|    }
  806|      2|  }
  807|      2|  return 0;
  808|      6|}
_ZN8AffixMgr13build_sfxtreeEP8SfxEntry:
  813|     34|int AffixMgr::build_sfxtree(SfxEntry* sfxptr) {
  814|       |
  815|     34|  sfxptr->initReverseWord();
  816|       |
  817|     34|  SfxEntry* ptr;
  818|     34|  SfxEntry* pptr;
  819|     34|  SfxEntry* ep = sfxptr;
  820|       |
  821|       |  /* get the right starting point */
  822|     34|  const char* key = ep->getKey();
  823|     34|  const auto flg = (unsigned char)(ep->getFlag() & 0x00FF);
  824|       |
  825|       |  // first index by flag which must exist
  826|     34|  ptr = sFlag[flg];
  827|     34|  ep->setFlgNxt(ptr);
  828|     34|  sFlag[flg] = ep;
  829|       |
  830|       |  // next index by affix string
  831|       |
  832|       |  // handle the special case of null affix string
  833|     34|  if (*key == '\0') {
  ------------------
  |  Branch (833:7): [True: 0, False: 34]
  ------------------
  834|       |    // always inset them at head of list at element 0
  835|      0|    ptr = sStart[0];
  836|      0|    ep->setNext(ptr);
  837|      0|    sStart[0] = ep;
  838|      0|    return 0;
  839|      0|  }
  840|       |
  841|       |  // now handle the normal case
  842|     34|  ep->setNextEQ(nullptr);
  843|     34|  ep->setNextNE(nullptr);
  844|       |
  845|     34|  unsigned char sp = *((const unsigned char*)key);
  846|     34|  ptr = sStart[sp];
  847|       |
  848|       |  // handle the first insert
  849|     34|  if (!ptr) {
  ------------------
  |  Branch (849:7): [True: 22, False: 12]
  ------------------
  850|     22|    sStart[sp] = ep;
  851|     22|    return 0;
  852|     22|  }
  853|       |
  854|       |  // otherwise use binary tree insertion so that a sorted
  855|       |  // list can easily be generated later
  856|     12|  pptr = nullptr;
  857|     20|  for (;;) {
  858|     20|    pptr = ptr;
  859|     20|    if (strcmp(ep->getKey(), ptr->getKey()) <= 0) {
  ------------------
  |  Branch (859:9): [True: 18, False: 2]
  ------------------
  860|     18|      ptr = ptr->getNextEQ();
  861|     18|      if (!ptr) {
  ------------------
  |  Branch (861:11): [True: 10, False: 8]
  ------------------
  862|     10|        pptr->setNextEQ(ep);
  863|     10|        break;
  864|     10|      }
  865|     18|    } else {
  866|      2|      ptr = ptr->getNextNE();
  867|      2|      if (!ptr) {
  ------------------
  |  Branch (867:11): [True: 2, False: 0]
  ------------------
  868|      2|        pptr->setNextNE(ep);
  869|      2|        break;
  870|      2|      }
  871|      2|    }
  872|     20|  }
  873|     12|  return 0;
  874|     34|}
_ZN8AffixMgr24process_pfx_tree_to_listEv:
  877|     38|int AffixMgr::process_pfx_tree_to_list() {
  878|  9.72k|  for (int i = 1; i < SETSIZE; i++) {
  ------------------
  |  |   61|  9.72k|#define SETSIZE 256
  ------------------
  |  Branch (878:19): [True: 9.69k, False: 38]
  ------------------
  879|  9.69k|    pStart[i] = process_pfx_in_order(pStart[i], nullptr);
  880|  9.69k|  }
  881|     38|  return 0;
  882|     38|}
_ZN8AffixMgr20process_pfx_in_orderEP8PfxEntryS1_:
  884|  9.70k|PfxEntry* AffixMgr::process_pfx_in_order(PfxEntry* ptr, PfxEntry* nptr) {
  885|  9.70k|  if (ptr) {
  ------------------
  |  Branch (885:7): [True: 6, False: 9.69k]
  ------------------
  886|      6|    nptr = process_pfx_in_order(ptr->getNextNE(), nptr);
  887|      6|    ptr->setNext(nptr);
  888|      6|    nptr = process_pfx_in_order(ptr->getNextEQ(), ptr);
  889|      6|  }
  890|  9.70k|  return nptr;
  891|  9.70k|}
_ZN8AffixMgr24process_sfx_tree_to_listEv:
  894|     38|int AffixMgr::process_sfx_tree_to_list() {
  895|  9.72k|  for (int i = 1; i < SETSIZE; i++) {
  ------------------
  |  |   61|  9.72k|#define SETSIZE 256
  ------------------
  |  Branch (895:19): [True: 9.69k, False: 38]
  ------------------
  896|  9.69k|    sStart[i] = process_sfx_in_order(sStart[i], nullptr);
  897|  9.69k|  }
  898|     38|  return 0;
  899|     38|}
_ZN8AffixMgr20process_sfx_in_orderEP8SfxEntryS1_:
  901|  9.75k|SfxEntry* AffixMgr::process_sfx_in_order(SfxEntry* ptr, SfxEntry* nptr) {
  902|  9.75k|  if (ptr) {
  ------------------
  |  Branch (902:7): [True: 34, False: 9.72k]
  ------------------
  903|     34|    nptr = process_sfx_in_order(ptr->getNextNE(), nptr);
  904|     34|    ptr->setNext(nptr);
  905|     34|    nptr = process_sfx_in_order(ptr->getNextEQ(), ptr);
  906|     34|  }
  907|  9.75k|  return nptr;
  908|  9.75k|}
_ZN8AffixMgr17process_pfx_orderEv:
  912|     38|int AffixMgr::process_pfx_order() {
  913|     38|  PfxEntry* ptr;
  914|       |
  915|       |  // loop through each prefix list starting point
  916|  9.72k|  for (int i = 1; i < SETSIZE; i++) {
  ------------------
  |  |   61|  9.72k|#define SETSIZE 256
  ------------------
  |  Branch (916:19): [True: 9.69k, False: 38]
  ------------------
  917|  9.69k|    ptr = pStart[i];
  918|       |
  919|       |    // look through the remainder of the list
  920|       |    //  and find next entry with affix that
  921|       |    // the current one is not a subset of
  922|       |    // mark that as destination for NextNE
  923|       |    // use next in list that you are a subset
  924|       |    // of as NextEQ
  925|       |
  926|  9.69k|    for (; ptr != nullptr; ptr = ptr->getNext()) {
  ------------------
  |  Branch (926:12): [True: 6, False: 9.69k]
  ------------------
  927|      6|      PfxEntry* nptr = ptr->getNext();
  928|      8|      for (; nptr != nullptr; nptr = nptr->getNext()) {
  ------------------
  |  Branch (928:14): [True: 2, False: 6]
  ------------------
  929|      2|        if (!isSubset(ptr->getKey(), nptr->getKey()))
  ------------------
  |  Branch (929:13): [True: 0, False: 2]
  ------------------
  930|      0|          break;
  931|      2|      }
  932|      6|      ptr->setNextNE(nptr);
  933|      6|      ptr->setNextEQ(nullptr);
  934|      6|      if ((ptr->getNext()) &&
  ------------------
  |  Branch (934:11): [True: 2, False: 4]
  ------------------
  935|      2|          isSubset(ptr->getKey(), (ptr->getNext())->getKey()))
  ------------------
  |  Branch (935:11): [True: 2, False: 0]
  ------------------
  936|      2|        ptr->setNextEQ(ptr->getNext());
  937|      6|    }
  938|       |
  939|       |    // now clean up by adding smart search termination strings:
  940|       |    // if you are already a superset of the previous prefix
  941|       |    // but not a subset of the next, search can end here
  942|       |    // so set NextNE properly
  943|       |
  944|  9.69k|    ptr = pStart[i];
  945|  9.69k|    for (; ptr != nullptr; ptr = ptr->getNext()) {
  ------------------
  |  Branch (945:12): [True: 6, False: 9.69k]
  ------------------
  946|      6|      PfxEntry* nptr = ptr->getNext();
  947|      6|      PfxEntry* mptr = nullptr;
  948|      8|      for (; nptr != nullptr; nptr = nptr->getNext()) {
  ------------------
  |  Branch (948:14): [True: 2, False: 6]
  ------------------
  949|      2|        if (!isSubset(ptr->getKey(), nptr->getKey()))
  ------------------
  |  Branch (949:13): [True: 0, False: 2]
  ------------------
  950|      0|          break;
  951|      2|        mptr = nptr;
  952|      2|      }
  953|      6|      if (mptr)
  ------------------
  |  Branch (953:11): [True: 2, False: 4]
  ------------------
  954|      2|        mptr->setNextNE(nullptr);
  955|      6|    }
  956|  9.69k|  }
  957|     38|  return 0;
  958|     38|}
_ZN8AffixMgr17process_sfx_orderEv:
  962|     38|int AffixMgr::process_sfx_order() {
  963|     38|  SfxEntry* ptr;
  964|       |
  965|       |  // loop through each prefix list starting point
  966|  9.72k|  for (int i = 1; i < SETSIZE; i++) {
  ------------------
  |  |   61|  9.72k|#define SETSIZE 256
  ------------------
  |  Branch (966:19): [True: 9.69k, False: 38]
  ------------------
  967|  9.69k|    ptr = sStart[i];
  968|       |
  969|       |    // look through the remainder of the list
  970|       |    //  and find next entry with affix that
  971|       |    // the current one is not a subset of
  972|       |    // mark that as destination for NextNE
  973|       |    // use next in list that you are a subset
  974|       |    // of as NextEQ
  975|       |
  976|  9.72k|    for (; ptr != nullptr; ptr = ptr->getNext()) {
  ------------------
  |  Branch (976:12): [True: 34, False: 9.69k]
  ------------------
  977|     34|      SfxEntry* nptr = ptr->getNext();
  978|     52|      for (; nptr != nullptr; nptr = nptr->getNext()) {
  ------------------
  |  Branch (978:14): [True: 20, False: 32]
  ------------------
  979|     20|        if (!isSubset(ptr->getKey(), nptr->getKey()))
  ------------------
  |  Branch (979:13): [True: 2, False: 18]
  ------------------
  980|      2|          break;
  981|     20|      }
  982|     34|      ptr->setNextNE(nptr);
  983|     34|      ptr->setNextEQ(nullptr);
  984|     34|      if ((ptr->getNext()) &&
  ------------------
  |  Branch (984:11): [True: 12, False: 22]
  ------------------
  985|     12|          isSubset(ptr->getKey(), (ptr->getNext())->getKey()))
  ------------------
  |  Branch (985:11): [True: 10, False: 2]
  ------------------
  986|     10|        ptr->setNextEQ(ptr->getNext());
  987|     34|    }
  988|       |
  989|       |    // now clean up by adding smart search termination strings:
  990|       |    // if you are already a superset of the previous suffix
  991|       |    // but not a subset of the next, search can end here
  992|       |    // so set NextNE properly
  993|       |
  994|  9.69k|    ptr = sStart[i];
  995|  9.72k|    for (; ptr != nullptr; ptr = ptr->getNext()) {
  ------------------
  |  Branch (995:12): [True: 34, False: 9.69k]
  ------------------
  996|     34|      SfxEntry* nptr = ptr->getNext();
  997|     34|      SfxEntry* mptr = nullptr;
  998|     52|      for (; nptr != nullptr; nptr = nptr->getNext()) {
  ------------------
  |  Branch (998:14): [True: 20, False: 32]
  ------------------
  999|     20|        if (!isSubset(ptr->getKey(), nptr->getKey()))
  ------------------
  |  Branch (999:13): [True: 2, False: 18]
  ------------------
 1000|      2|          break;
 1001|     18|        mptr = nptr;
 1002|     18|      }
 1003|     34|      if (mptr)
  ------------------
  |  Branch (1003:11): [True: 10, False: 24]
  ------------------
 1004|     10|        mptr->setNextNE(nullptr);
 1005|     34|    }
 1006|  9.69k|  }
 1007|     38|  return 0;
 1008|     38|}
_ZN8AffixMgr7condlenERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1021|      8|int AffixMgr::condlen(const std::string& s) {
 1022|      8|  int l = 0;
 1023|      8|  bool group = false;
 1024|      8|  size_t i = 0;
 1025|     42|  while (i < s.size()) {
  ------------------
  |  Branch (1025:10): [True: 34, False: 8]
  ------------------
 1026|     34|    if (s[i] == '[') {
  ------------------
  |  Branch (1026:9): [True: 4, False: 30]
  ------------------
 1027|      4|      group = true;
 1028|      4|      ++l;
 1029|      4|      ++i;
 1030|     30|    } else if (s[i] == ']') {
  ------------------
  |  Branch (1030:16): [True: 4, False: 26]
  ------------------
 1031|      4|      group = false;
 1032|      4|      ++i;
 1033|     26|    } else if (group) {
  ------------------
  |  Branch (1033:16): [True: 18, False: 8]
  ------------------
 1034|     18|      ++i;
 1035|     18|    } else {
 1036|      8|      ++l;
 1037|      8|      i = utf8 ? utf8_next(s, i) : i + 1;
  ------------------
  |  Branch (1037:11): [True: 8, False: 0]
  ------------------
 1038|      8|    }
 1039|     34|  }
 1040|      8|  return l;
 1041|      8|}
_ZN8AffixMgr8encodeitER8AffEntryRKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 1043|     42|int AffixMgr::encodeit(AffEntry& entry, const std::string& cs) {
 1044|     42|  if (cs.compare(".") != 0) {
  ------------------
  |  Branch (1044:7): [True: 8, False: 34]
  ------------------
 1045|      8|    entry.numconds = (char)condlen(cs);
 1046|      8|    const size_t cslen = cs.size();
 1047|      8|    const size_t short_part = std::min<size_t>(MAXCONDLEN, cslen);
  ------------------
  |  |   90|      8|#define MAXCONDLEN 20
  ------------------
 1048|      8|    memcpy(entry.c.conds, cs.data(), short_part);
 1049|      8|    if (short_part < MAXCONDLEN) {
  ------------------
  |  |   90|      8|#define MAXCONDLEN 20
  ------------------
  |  Branch (1049:9): [True: 8, False: 0]
  ------------------
 1050|       |      //blank out the remaining space
 1051|      8|      memset(entry.c.conds + short_part, 0, MAXCONDLEN - short_part);
  ------------------
  |  |   90|      8|#define MAXCONDLEN 20
  ------------------
 1052|      8|    } else if (cs[MAXCONDLEN]) {
  ------------------
  |  |   90|      0|#define MAXCONDLEN 20
  ------------------
  |  Branch (1052:16): [True: 0, False: 0]
  ------------------
 1053|       |      //there is more conditions than fit in fixed space, so its
 1054|       |      //a long condition
 1055|      0|      entry.opts |= aeLONGCOND;
  ------------------
  |  |   69|      0|#define aeLONGCOND (1 << 4)
  ------------------
 1056|      0|      size_t remaining = cs.size() - MAXCONDLEN_1;
  ------------------
  |  |   91|      0|#define MAXCONDLEN_1 (MAXCONDLEN - sizeof(char*))
  |  |  ------------------
  |  |  |  |   90|      0|#define MAXCONDLEN 20
  |  |  ------------------
  ------------------
 1057|      0|      entry.c.l.conds2 = new char[1 + remaining];
 1058|      0|      memcpy(entry.c.l.conds2, cs.data() + MAXCONDLEN_1, remaining);
  ------------------
  |  |   91|      0|#define MAXCONDLEN_1 (MAXCONDLEN - sizeof(char*))
  |  |  ------------------
  |  |  |  |   90|      0|#define MAXCONDLEN 20
  |  |  ------------------
  ------------------
 1059|      0|      entry.c.l.conds2[remaining] = 0;
 1060|      0|    }
 1061|     34|  } else {
 1062|     34|    entry.numconds = 0;
 1063|     34|    entry.c.conds[0] = '\0';
 1064|     34|  }
 1065|     42|  return 0;
 1066|     42|}
_ZN8AffixMgr12prefix_checkERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiicR12AffixScratcht:
 1083|   505M|                                      const FLAG needflag) {
 1084|   505M|  struct hentry* rv = nullptr;
 1085|       |
 1086|   505M|  pfx = nullptr;
 1087|   505M|  pfxappnd = nullptr;
 1088|   505M|  sfxappnd = nullptr;
 1089|   505M|  sfxextra = 0;
 1090|       |
 1091|       |  // first handle the special case of 0 length prefixes
 1092|   505M|  PfxEntry* pe = pStart[0];
 1093|   506M|  while (pe) {
  ------------------
  |  Branch (1093:10): [True: 1.17M, False: 505M]
  ------------------
 1094|  1.17M|    if (
 1095|       |        // fogemorpheme
 1096|  1.17M|        ((in_compound != IN_CPD_NOT) ||
  ------------------
  |  |   72|  1.17M|#define IN_CPD_NOT 0
  ------------------
  |  Branch (1096:10): [True: 0, False: 1.17M]
  ------------------
 1097|  1.17M|         !(pe->getCont() &&
  ------------------
  |  Branch (1097:12): [True: 1.17M, False: 0]
  ------------------
 1098|  1.17M|           (TESTAFF(pe->getCont(), onlyincompound, pe->getContLen())))) &&
  ------------------
  |  |   99|  1.17M|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1098:12): [True: 0, False: 1.17M]
  ------------------
 1099|       |        // permit prefixes in compounds
 1100|  1.17M|        ((in_compound != IN_CPD_END) ||
  ------------------
  |  |   74|  1.17M|#define IN_CPD_END 2
  ------------------
  |  Branch (1100:10): [True: 1.17M, False: 0]
  ------------------
 1101|      0|         (pe->getCont() &&
  ------------------
  |  Branch (1101:11): [True: 0, False: 0]
  ------------------
 1102|  1.17M|          (TESTAFF(pe->getCont(), compoundpermitflag, pe->getContLen()))))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1102:11): [True: 0, False: 0]
  ------------------
 1103|       |      // check prefix
 1104|  1.17M|      rv = pe->checkword(word, start, len, in_compound, needflag, scratch);
 1105|  1.17M|      if (rv) {
  ------------------
  |  Branch (1105:11): [True: 0, False: 1.17M]
  ------------------
 1106|      0|        pfx = pe;  // BUG: pfx not stateless
 1107|      0|        return rv;
 1108|      0|      }
 1109|  1.17M|    }
 1110|  1.17M|    pe = pe->getNext();
 1111|  1.17M|  }
 1112|       |
 1113|       |  // now handle the general case
 1114|   505M|  unsigned char sp = word[start];
 1115|   505M|  PfxEntry* pptr = pStart[sp];
 1116|       |
 1117|   505M|  while (pptr) {
  ------------------
  |  Branch (1117:10): [True: 39.9k, False: 505M]
  ------------------
 1118|  39.9k|    if (isSubset(pptr->getKey(), word.c_str() + start)) {
  ------------------
  |  Branch (1118:9): [True: 28.8k, False: 11.0k]
  ------------------
 1119|  28.8k|      if (
 1120|       |          // fogemorpheme
 1121|  28.8k|          ((in_compound != IN_CPD_NOT) ||
  ------------------
  |  |   72|  28.8k|#define IN_CPD_NOT 0
  ------------------
  |  Branch (1121:12): [True: 0, False: 28.8k]
  ------------------
 1122|  28.8k|           !(pptr->getCont() &&
  ------------------
  |  Branch (1122:14): [True: 24.8k, False: 4.08k]
  ------------------
 1123|  24.8k|             (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen())))) &&
  ------------------
  |  |   99|  24.8k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1123:14): [True: 0, False: 24.8k]
  ------------------
 1124|       |          // permit prefixes in compounds
 1125|  28.8k|          ((in_compound != IN_CPD_END) ||
  ------------------
  |  |   74|  28.8k|#define IN_CPD_END 2
  ------------------
  |  Branch (1125:12): [True: 28.8k, False: 0]
  ------------------
 1126|      0|           (pptr->getCont() && (TESTAFF(pptr->getCont(), compoundpermitflag,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1126:13): [True: 0, False: 0]
  |  Branch (1126:32): [True: 0, False: 0]
  ------------------
 1127|  28.8k|                                        pptr->getContLen()))))) {
 1128|       |        // check prefix
 1129|  28.8k|        rv = pptr->checkword(word, start, len, in_compound, needflag, scratch);
 1130|  28.8k|        if (rv) {
  ------------------
  |  Branch (1130:13): [True: 0, False: 28.8k]
  ------------------
 1131|      0|          pfx = pptr;  // BUG: pfx not stateless
 1132|      0|          return rv;
 1133|      0|        }
 1134|  28.8k|      }
 1135|  28.8k|      pptr = pptr->getNextEQ();
 1136|  28.8k|    } else {
 1137|  11.0k|      pptr = pptr->getNextNE();
 1138|  11.0k|    }
 1139|  39.9k|  }
 1140|       |
 1141|   505M|  return nullptr;
 1142|   505M|}
_ZN8AffixMgr19prefix_check_twosfxERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiicR12AffixScratcht:
 1150|  13.4M|                                             const FLAG needflag) {
 1151|  13.4M|  struct hentry* rv = nullptr;
 1152|       |
 1153|  13.4M|  pfx = nullptr;
 1154|  13.4M|  sfxappnd = nullptr;
 1155|  13.4M|  sfxextra = 0;
 1156|       |
 1157|       |  // first handle the special case of 0 length prefixes
 1158|  13.4M|  PfxEntry* pe = pStart[0];
 1159|       |
 1160|  14.6M|  while (pe) {
  ------------------
  |  Branch (1160:10): [True: 1.17M, False: 13.4M]
  ------------------
 1161|  1.17M|    rv = pe->check_twosfx(word, start, len, in_compound, needflag, scratch);
 1162|  1.17M|    if (rv)
  ------------------
  |  Branch (1162:9): [True: 0, False: 1.17M]
  ------------------
 1163|      0|      return rv;
 1164|  1.17M|    pe = pe->getNext();
 1165|  1.17M|  }
 1166|       |
 1167|       |  // now handle the general case
 1168|  13.4M|  unsigned char sp = word[start];
 1169|  13.4M|  PfxEntry* pptr = pStart[sp];
 1170|       |
 1171|  13.4M|  while (pptr) {
  ------------------
  |  Branch (1171:10): [True: 35.8k, False: 13.4M]
  ------------------
 1172|  35.8k|    if (isSubset(pptr->getKey(), word.c_str() + start)) {
  ------------------
  |  Branch (1172:9): [True: 24.8k, False: 11.0k]
  ------------------
 1173|  24.8k|      rv = pptr->check_twosfx(word, start, len, in_compound, needflag, scratch);
 1174|  24.8k|      if (rv) {
  ------------------
  |  Branch (1174:11): [True: 0, False: 24.8k]
  ------------------
 1175|      0|        pfx = pptr;
 1176|      0|        return rv;
 1177|      0|      }
 1178|  24.8k|      pptr = pptr->getNextEQ();
 1179|  24.8k|    } else {
 1180|  11.0k|      pptr = pptr->getNextNE();
 1181|  11.0k|    }
 1182|  35.8k|  }
 1183|       |
 1184|  13.4M|  return nullptr;
 1185|  13.4M|}
_ZN8AffixMgr18prefix_check_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiicR12AffixScratcht:
 1193|  10.6k|                                         const FLAG needflag) {
 1194|       |
 1195|  10.6k|  std::string result;
 1196|       |
 1197|  10.6k|  pfx = nullptr;
 1198|  10.6k|  sfxappnd = nullptr;
 1199|  10.6k|  sfxextra = 0;
 1200|       |
 1201|       |  // first handle the special case of 0 length prefixes
 1202|  10.6k|  PfxEntry* pe = pStart[0];
 1203|  11.2k|  while (pe) {
  ------------------
  |  Branch (1203:10): [True: 564, False: 10.6k]
  ------------------
 1204|    564|    std::string st = pe->check_morph(word, start, len, in_compound, needflag, scratch);
 1205|    564|    if (!st.empty()) {
  ------------------
  |  Branch (1205:9): [True: 0, False: 564]
  ------------------
 1206|      0|      result.append(st);
 1207|      0|    }
 1208|    564|    pe = pe->getNext();
 1209|    564|  }
 1210|       |
 1211|       |  // now handle the general case
 1212|  10.6k|  unsigned char sp = word[start];
 1213|  10.6k|  PfxEntry* pptr = pStart[sp];
 1214|       |
 1215|  10.6k|  while (pptr) {
  ------------------
  |  Branch (1215:10): [True: 0, False: 10.6k]
  ------------------
 1216|      0|    if (isSubset(pptr->getKey(), word.c_str() + start)) {
  ------------------
  |  Branch (1216:9): [True: 0, False: 0]
  ------------------
 1217|      0|      std::string st = pptr->check_morph(word, start, len, in_compound, needflag, scratch);
 1218|      0|      if (!st.empty()) {
  ------------------
  |  Branch (1218:11): [True: 0, False: 0]
  ------------------
 1219|       |        // fogemorpheme
 1220|      0|        if ((in_compound != IN_CPD_NOT) ||
  ------------------
  |  |   72|      0|#define IN_CPD_NOT 0
  ------------------
  |  Branch (1220:13): [True: 0, False: 0]
  ------------------
 1221|      0|            !((pptr->getCont() && (TESTAFF(pptr->getCont(), onlyincompound,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1221:16): [True: 0, False: 0]
  |  Branch (1221:35): [True: 0, False: 0]
  ------------------
 1222|      0|                                           pptr->getContLen()))))) {
 1223|      0|          result.append(st);
 1224|      0|          pfx = pptr;
 1225|      0|        }
 1226|      0|      }
 1227|      0|      pptr = pptr->getNextEQ();
 1228|      0|    } else {
 1229|      0|      pptr = pptr->getNextNE();
 1230|      0|    }
 1231|      0|  }
 1232|       |
 1233|  10.6k|  return result;
 1234|  10.6k|}
_ZN8AffixMgr25prefix_check_twosfx_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiicR12AffixScratcht:
 1242|  3.33k|                                                const FLAG needflag) {
 1243|  3.33k|  std::string result;
 1244|       |
 1245|  3.33k|  pfx = nullptr;
 1246|  3.33k|  sfxappnd = nullptr;
 1247|  3.33k|  sfxextra = 0;
 1248|       |
 1249|       |  // first handle the special case of 0 length prefixes
 1250|  3.33k|  PfxEntry* pe = pStart[0];
 1251|  3.90k|  while (pe) {
  ------------------
  |  Branch (1251:10): [True: 564, False: 3.33k]
  ------------------
 1252|    564|    std::string st = pe->check_twosfx_morph(word, start, len, in_compound, needflag, scratch);
 1253|    564|    if (!st.empty()) {
  ------------------
  |  Branch (1253:9): [True: 0, False: 564]
  ------------------
 1254|      0|      result.append(st);
 1255|      0|    }
 1256|    564|    pe = pe->getNext();
 1257|    564|  }
 1258|       |
 1259|       |  // now handle the general case
 1260|  3.33k|  unsigned char sp = word[start];
 1261|  3.33k|  PfxEntry* pptr = pStart[sp];
 1262|       |
 1263|  3.33k|  while (pptr) {
  ------------------
  |  Branch (1263:10): [True: 0, False: 3.33k]
  ------------------
 1264|      0|    if (isSubset(pptr->getKey(), word.c_str() + start)) {
  ------------------
  |  Branch (1264:9): [True: 0, False: 0]
  ------------------
 1265|      0|      std::string st = pptr->check_twosfx_morph(word, start, len, in_compound, needflag, scratch);
 1266|      0|      if (!st.empty()) {
  ------------------
  |  Branch (1266:11): [True: 0, False: 0]
  ------------------
 1267|      0|        result.append(st);
 1268|      0|        pfx = pptr;
 1269|      0|      }
 1270|      0|      pptr = pptr->getNextEQ();
 1271|      0|    } else {
 1272|      0|      pptr = pptr->getNextNE();
 1273|      0|    }
 1274|      0|  }
 1275|       |
 1276|  3.33k|  return result;
 1277|  3.33k|}
_ZN8AffixMgr12get_syllableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1553|    332|short AffixMgr::get_syllable(const std::string& word) {
 1554|    332|  if (cpdmaxsyllable == 0)
  ------------------
  |  Branch (1554:7): [True: 0, False: 332]
  ------------------
 1555|      0|    return 0;
 1556|       |
 1557|    332|  short num = 0;
 1558|       |
 1559|    332|  if (!utf8) {
  ------------------
  |  Branch (1559:7): [True: 0, False: 332]
  ------------------
 1560|      0|    num = (short)std::count_if(word.begin(), word.end(),
 1561|      0|          [&](char c) {
 1562|      0|            return std::binary_search(cpdvowels.begin(), cpdvowels.end(), c);
 1563|      0|          });
 1564|    332|  } else if (!cpdvowels_utf16.empty()) {
  ------------------
  |  Branch (1564:14): [True: 332, False: 0]
  ------------------
 1565|    332|    std::vector<w_char> w;
 1566|    332|    u8_u16(w, word);
 1567|    332|    num = (short)std::count_if(w.begin(), w.end(),
 1568|    332|          [&](w_char wc) {
 1569|    332|            return std::binary_search(cpdvowels_utf16.begin(), cpdvowels_utf16.end(), wc);
 1570|    332|          });
 1571|    332|  }
 1572|       |
 1573|    332|  return num;
 1574|    332|}
_ZN8AffixMgr10setcminmaxEPmS0_PKcm:
 1576|  18.0M|void AffixMgr::setcminmax(size_t* cmin, size_t* cmax, const char* word, size_t len) {
 1577|  18.0M|  if (utf8) {
  ------------------
  |  Branch (1577:7): [True: 1.54M, False: 16.5M]
  ------------------
 1578|  1.54M|    int i;
 1579|  4.60M|    for (*cmin = 0, i = 0; (i < cpdmin) && *cmin < len; i++) {
  ------------------
  |  Branch (1579:28): [True: 3.08M, False: 1.52M]
  |  Branch (1579:44): [True: 3.06M, False: 22.0k]
  ------------------
 1580|  3.42M|      for ((*cmin)++; *cmin < len && is_utf8_cont(word[*cmin]); (*cmin)++)
  ------------------
  |  Branch (1580:23): [True: 3.38M, False: 37.6k]
  |  Branch (1580:38): [True: 364k, False: 3.02M]
  ------------------
 1581|   364k|        ;
 1582|  3.06M|    }
 1583|  3.08M|    for (*cmax = len, i = 0; (i < (cpdmin - 1)) && *cmax > 0; i++) {
  ------------------
  |  Branch (1583:30): [True: 1.54M, False: 1.53M]
  |  Branch (1583:52): [True: 1.53M, False: 3.06k]
  ------------------
 1584|  2.47M|      for ((*cmax)--; *cmax > 0 && is_utf8_cont(word[*cmax]); (*cmax)--)
  ------------------
  |  Branch (1584:23): [True: 2.45M, False: 18.9k]
  |  Branch (1584:36): [True: 933k, False: 1.52M]
  ------------------
 1585|   933k|        ;
 1586|  1.53M|    }
 1587|  16.5M|  } else {
 1588|  16.5M|    *cmin = cpdmin;
 1589|  16.5M|    *cmax = len - cpdmin + 1;
 1590|  16.5M|  }
 1591|  18.0M|}
_ZN8AffixMgr14compound_checkERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEssssPP6hentrySB_ccPiR12AffixScratch:
 1605|  18.0M|                                        AffixScratch& scratch) {
 1606|  18.0M|  short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;
 1607|  18.0M|  hentry *rv = nullptr, *rv_first;
 1608|  18.0M|  std::string st;
 1609|  18.0M|  char ch = '\0', affixed;
 1610|  18.0M|  size_t cmin, cmax;
 1611|  18.0M|  int striple = 0, soldi = 0, oldcmin = 0, oldcmax = 0, oldlen = 0, checkedstriple = 0;
 1612|  18.0M|  hentry** oldwords = words;
 1613|  18.0M|  size_t scpd = 0, len = word.size();
 1614|       |
 1615|       |  // protect subsequent words[wnum + 1] reads and any recursion
 1616|  18.0M|  if (wnum + 1 >= maxwordnum)
  ------------------
  |  Branch (1616:7): [True: 0, False: 18.0M]
  ------------------
 1617|      0|    return nullptr;
 1618|       |
 1619|  18.0M|  int checked_prefix;
 1620|       |
 1621|       |  // add a time limit to handle possible
 1622|       |  // combinatorical explosion of the overlapping words
 1623|       |
 1624|  18.0M|  HUNSPELL_THREAD_LOCAL std::chrono::steady_clock::time_point clock_time_start;
  ------------------
  |  |   60|  18.0M|#  define HUNSPELL_THREAD_LOCAL thread_local
  ------------------
 1625|  18.0M|  HUNSPELL_THREAD_LOCAL bool timelimit_exceeded;
  ------------------
  |  |   60|  18.0M|#  define HUNSPELL_THREAD_LOCAL thread_local
  ------------------
 1626|       |
 1627|       |  // get the current time
 1628|  18.0M|  std::chrono::steady_clock::time_point clock_now = std::chrono::steady_clock::now();
 1629|       |
 1630|  18.0M|  if (wnum == 0) {
  ------------------
  |  Branch (1630:7): [True: 18.0M, False: 106]
  ------------------
 1631|       |      // set the start time
 1632|  18.0M|      clock_time_start = clock_now;
 1633|  18.0M|      timelimit_exceeded = false;
 1634|  18.0M|  }
 1635|    106|  else if (clock_now - clock_time_start > TIMELIMIT_MS)
  ------------------
  |  |  106|    106|#define TIMELIMIT_MS std::chrono::milliseconds(50)
  ------------------
  |  Branch (1635:12): [True: 0, False: 106]
  ------------------
 1636|      0|      timelimit_exceeded = true;
 1637|       |
 1638|  18.0M|  setcminmax(&cmin, &cmax, word.c_str(), len);
 1639|       |
 1640|  18.0M|  st.assign(word);
 1641|       |
 1642|   485M|  for (size_t i = cmin; i < cmax; ++i) {
  ------------------
  |  Branch (1642:25): [True: 468M, False: 17.3M]
  ------------------
 1643|       |    // go to end of the UTF-8 character
 1644|   468M|    if (utf8) {
  ------------------
  |  Branch (1644:9): [True: 38.4M, False: 429M]
  ------------------
 1645|  47.7M|      for (; is_utf8_cont(st[i]); i++)
  ------------------
  |  Branch (1645:14): [True: 9.29M, False: 38.4M]
  ------------------
 1646|  9.29M|        ;
 1647|  38.4M|      if (i >= cmax)
  ------------------
  |  Branch (1647:11): [True: 195k, False: 38.3M]
  ------------------
 1648|   195k|        return nullptr;
 1649|  38.4M|    }
 1650|       |
 1651|   468M|    words = oldwords;
 1652|   468M|    int onlycpdrule = (words) ? 1 : 0;
  ------------------
  |  Branch (1652:23): [True: 0, False: 468M]
  ------------------
 1653|       |
 1654|   468M|    do {  // onlycpdrule loop
 1655|       |
 1656|   468M|      oldnumsyllable = numsyllable;
 1657|   468M|      oldwordnum = wordnum;
 1658|   468M|      checked_prefix = 0;
 1659|       |
 1660|   468M|      do {  // simplified checkcompoundpattern loop
 1661|       |
 1662|   468M|        if (timelimit_exceeded ||
  ------------------
  |  Branch (1662:13): [True: 0, False: 468M]
  |  Branch (1662:13): [True: 0, False: 468M]
  ------------------
 1663|   468M|            std::chrono::steady_clock::now() - clock_time_start > TIMELIMIT_MS) {
  ------------------
  |  |  106|   468M|#define TIMELIMIT_MS std::chrono::milliseconds(50)
  ------------------
  |  Branch (1663:13): [True: 0, False: 468M]
  ------------------
 1664|      0|          timelimit_exceeded = true;
 1665|      0|          return nullptr;
 1666|      0|        }
 1667|       |
 1668|   468M|        if (scpd > 0) {
  ------------------
  |  Branch (1668:13): [True: 0, False: 468M]
  ------------------
 1669|      0|          for (; scpd <= checkcpdtable.size() &&
  ------------------
  |  Branch (1669:18): [True: 0, False: 0]
  ------------------
 1670|      0|                 (checkcpdtable[scpd - 1].pattern3.empty() ||
  ------------------
  |  Branch (1670:19): [True: 0, False: 0]
  ------------------
 1671|      0|                  i > word.size() ||
  ------------------
  |  Branch (1671:19): [True: 0, False: 0]
  ------------------
 1672|      0|                  word.compare(i, checkcpdtable[scpd - 1].pattern3.size(), checkcpdtable[scpd - 1].pattern3) != 0);
  ------------------
  |  Branch (1672:19): [True: 0, False: 0]
  ------------------
 1673|      0|               scpd++)
 1674|      0|            ;
 1675|       |
 1676|      0|          if (scpd > checkcpdtable.size())
  ------------------
  |  Branch (1676:15): [True: 0, False: 0]
  ------------------
 1677|      0|            break;  // break simplified checkcompoundpattern loop
 1678|      0|          st.replace(i, std::string::npos, checkcpdtable[scpd - 1].pattern);
 1679|      0|          soldi = i;
 1680|      0|          i += checkcpdtable[scpd - 1].pattern.size();
 1681|      0|          st.replace(i, std::string::npos, checkcpdtable[scpd - 1].pattern2);
 1682|      0|          st.replace(i + checkcpdtable[scpd - 1].pattern2.size(), std::string::npos,
 1683|      0|                 word.substr(soldi + checkcpdtable[scpd - 1].pattern3.size()));
 1684|       |
 1685|      0|          oldlen = len;
 1686|      0|          len += checkcpdtable[scpd - 1].pattern.size() +
 1687|      0|                 checkcpdtable[scpd - 1].pattern2.size() -
 1688|      0|                 checkcpdtable[scpd - 1].pattern3.size();
 1689|      0|          oldcmin = cmin;
 1690|      0|          oldcmax = cmax;
 1691|      0|          setcminmax(&cmin, &cmax, st.c_str(), len);
 1692|       |
 1693|      0|          cmax = len - cpdmin + 1;
 1694|      0|        }
 1695|       |
 1696|   468M|        if (i >= st.size())
  ------------------
  |  Branch (1696:13): [True: 525k, False: 467M]
  ------------------
 1697|   525k|          return nullptr;
 1698|       |
 1699|   467M|        ch = st[i];
 1700|   467M|        st[i] = '\0';
 1701|       |
 1702|   467M|        sfx = nullptr;
 1703|   467M|        pfx = nullptr;
 1704|       |
 1705|       |        // FIRST WORD
 1706|       |
 1707|   467M|        affixed = 1;
 1708|   467M|        rv = lookup(st.c_str(), i);  // perhaps without prefix
 1709|       |
 1710|       |        // forbid dictionary stems with COMPOUNDFORBIDFLAG in
 1711|       |        // compound words, overriding the effect of COMPOUNDPERMITFLAG
 1712|   467M|        if ((rv) && compoundforbidflag &&
  ------------------
  |  Branch (1712:13): [True: 1.10M, False: 466M]
  |  Branch (1712:21): [True: 59.6k, False: 1.04M]
  ------------------
 1713|  59.6k|                TESTAFF(rv->astr, compoundforbidflag, rv->alen) && !hu_mov_rule) {
  ------------------
  |  |   99|   467M|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 59.6k]
  |  |  ------------------
  ------------------
  |  Branch (1713:68): [True: 0, False: 0]
  ------------------
 1714|      0|            bool would_continue = !onlycpdrule && simplifiedcpd;
  ------------------
  |  Branch (1714:35): [True: 0, False: 0]
  |  Branch (1714:51): [True: 0, False: 0]
  ------------------
 1715|      0|            if (!scpd && would_continue) {
  ------------------
  |  Branch (1715:17): [True: 0, False: 0]
  |  Branch (1715:26): [True: 0, False: 0]
  ------------------
 1716|       |                // given the while conditions that continue jumps to, this situation
 1717|       |                // never ends
 1718|      0|                HUNSPELL_WARNING(stderr, "break infinite loop\n");
 1719|      0|                break;
 1720|      0|            }
 1721|       |
 1722|      0|            if (scpd > 0 && would_continue) {
  ------------------
  |  Branch (1722:17): [True: 0, False: 0]
  |  Branch (1722:29): [True: 0, False: 0]
  ------------------
 1723|       |                // under these conditions we loop again, but the assumption above
 1724|       |                // appears to be that cmin and cmax are the original values they
 1725|       |                // had in the outside loop
 1726|      0|                cmin = oldcmin;
 1727|      0|                cmax = oldcmax;
 1728|      0|            }
 1729|      0|            continue;
 1730|      0|        }
 1731|       |
 1732|       |        // search homonym with compound flag
 1733|   468M|        while ((rv) && !hu_mov_rule &&
  ------------------
  |  Branch (1733:16): [True: 1.10M, False: 467M]
  |  Branch (1733:24): [True: 1.10M, False: 96]
  ------------------
 1734|  1.10M|               ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
  ------------------
  |  |   99|   350k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 350k]
  |  |  ------------------
  ------------------
  |  Branch (1734:18): [True: 350k, False: 758k]
  ------------------
 1735|  1.10M|                !((compoundflag && !words && !onlycpdrule &&
  ------------------
  |  Branch (1735:20): [True: 1.10M, False: 0]
  |  Branch (1735:36): [True: 1.10M, False: 0]
  |  Branch (1735:46): [True: 1.10M, False: 0]
  ------------------
 1736|  1.10M|                   TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|  1.10M|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 168, False: 1.10M]
  |  |  ------------------
  ------------------
 1737|  1.10M|                  (compoundbegin && !wordnum && !onlycpdrule &&
  ------------------
  |  Branch (1737:20): [True: 0, False: 1.10M]
  |  Branch (1737:37): [True: 0, False: 0]
  |  Branch (1737:49): [True: 0, False: 0]
  ------------------
 1738|      0|                   TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1739|  1.10M|                  (compoundmiddle && wordnum && !words && !onlycpdrule &&
  ------------------
  |  Branch (1739:20): [True: 0, False: 1.10M]
  |  Branch (1739:38): [True: 0, False: 0]
  |  Branch (1739:49): [True: 0, False: 0]
  |  Branch (1739:59): [True: 0, False: 0]
  ------------------
 1740|      0|                   TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1741|  1.10M|                  (!defcpdtable.empty() && onlycpdrule &&
  ------------------
  |  Branch (1741:20): [True: 0, False: 1.10M]
  |  Branch (1741:44): [True: 0, False: 0]
  ------------------
 1742|      0|                   ((!words && !wordnum &&
  ------------------
  |  Branch (1742:22): [True: 0, False: 0]
  |  Branch (1742:32): [True: 0, False: 0]
  ------------------
 1743|      0|                     defcpd_check(&words, wnum, maxwordnum, rv, rwords, 0)) ||
  ------------------
  |  Branch (1743:22): [True: 0, False: 0]
  ------------------
 1744|      0|                    (words &&
  ------------------
  |  Branch (1744:22): [True: 0, False: 0]
  ------------------
 1745|      0|                     defcpd_check(&words, wnum, maxwordnum, rv, rwords, 0))))) ||
  ------------------
  |  Branch (1745:22): [True: 0, False: 0]
  ------------------
 1746|    168|                (scpd != 0 && checkcpdtable[scpd - 1].cond != FLAG_NULL &&
  ------------------
  |  |   96|    168|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1746:18): [True: 0, False: 168]
  |  Branch (1746:31): [True: 0, False: 0]
  ------------------
 1747|  1.10M|                 !TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond, rv->alen)))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1747:18): [True: 0, False: 0]
  ------------------
 1748|  1.10M|          rv = rv->next_homonym;
 1749|  1.10M|        }
 1750|       |
 1751|   467M|        if (rv)
  ------------------
  |  Branch (1751:13): [True: 264, False: 467M]
  ------------------
 1752|    264|          affixed = 0;
 1753|       |
 1754|   467M|        if (!rv) {
  ------------------
  |  Branch (1754:13): [True: 467M, False: 264]
  ------------------
 1755|   467M|          if (onlycpdrule)
  ------------------
  |  Branch (1755:15): [True: 0, False: 467M]
  ------------------
 1756|      0|            break;
 1757|   467M|          if (compoundflag &&
  ------------------
  |  Branch (1757:15): [True: 467M, False: 0]
  ------------------
 1758|   467M|              !(rv = prefix_check(st, 0, i,
  ------------------
  |  Branch (1758:15): [True: 467M, False: 0]
  ------------------
 1759|   467M|                                  hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
  ------------------
  |  |   75|  69.7k|#define IN_CPD_OTHER 3
  ------------------
                                                hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
  ------------------
  |  |   73|   935M|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (1759:35): [True: 69.7k, False: 467M]
  ------------------
 1760|   467M|                                  scratch, compoundflag))) {
 1761|   467M|            if (((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   96|   467M|#define FLAG_NULL 0x00
  ------------------
                          if (((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   75|  69.7k|#define IN_CPD_OTHER 3
  ------------------
                          if (((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   73|   935M|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (1761:18): [True: 0, False: 467M]
  |  Branch (1761:93): [True: 69.7k, False: 467M]
  ------------------
 1762|   467M|                 (compoundmoresuffixes && (rv = suffix_check_twosfx(st, 0, i, 0, nullptr, scratch, compoundflag)))) &&
  ------------------
  |  Branch (1762:19): [True: 0, False: 467M]
  |  Branch (1762:43): [True: 0, False: 0]
  ------------------
 1763|      0|                !hu_mov_rule && sfx->getCont() &&
  ------------------
  |  Branch (1763:17): [True: 0, False: 0]
  |  Branch (1763:33): [True: 0, False: 0]
  ------------------
 1764|      0|                ((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1764:19): [True: 0, False: 0]
  ------------------
 1765|      0|                 (compoundend && TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1765:19): [True: 0, False: 0]
  ------------------
 1766|      0|              rv = nullptr;
 1767|      0|            }
 1768|   467M|          }
 1769|       |
 1770|   467M|          if (rv ||
  ------------------
  |  Branch (1770:15): [True: 0, False: 467M]
  ------------------
 1771|   467M|              (((wordnum == 0) && compoundbegin &&
  ------------------
  |  Branch (1771:17): [True: 467M, False: 70.5k]
  |  Branch (1771:35): [True: 0, False: 467M]
  ------------------
 1772|      0|                ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
                              ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                              ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (1772:18): [True: 0, False: 0]
  |  Branch (1772:94): [True: 0, False: 0]
  ------------------
 1773|      0|                 (compoundmoresuffixes && (rv = suffix_check_twosfx(st, 0, i, 0, nullptr, scratch,
  ------------------
  |  Branch (1773:19): [True: 0, False: 0]
  |  Branch (1773:43): [True: 0, False: 0]
  ------------------
 1774|      0|                                                                    compoundbegin))) ||  // twofold suffixes + compound
 1775|      0|                 (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundbegin)))) ||
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                               (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundbegin)))) ||
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (1775:18): [True: 0, False: 0]
  |  Branch (1775:47): [True: 0, False: 0]
  ------------------
 1776|   467M|               ((wordnum > 0) && compoundmiddle &&
  ------------------
  |  Branch (1776:17): [True: 630, False: 467M]
  |  Branch (1776:34): [True: 0, False: 630]
  ------------------
 1777|      0|                ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
                              ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                              ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (1777:18): [True: 0, False: 0]
  |  Branch (1777:95): [True: 0, False: 0]
  ------------------
 1778|      0|                 (compoundmoresuffixes && (rv = suffix_check_twosfx(st, 0, i, 0, nullptr, scratch,
  ------------------
  |  Branch (1778:19): [True: 0, False: 0]
  |  Branch (1778:43): [True: 0, False: 0]
  ------------------
 1779|      0|                                                                    compoundmiddle))) ||  // twofold suffixes + compound
 1780|      0|                 (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundmiddle))))))
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                               (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundmiddle))))))
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (1780:18): [True: 0, False: 0]
  |  Branch (1780:47): [True: 0, False: 0]
  ------------------
 1781|      0|            checked_prefix = 1;
 1782|       |          // else check forbiddenwords and needaffix
 1783|   467M|        } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|    386|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 193]
  |  |  ------------------
  ------------------
  |  Branch (1783:20): [True: 193, False: 71]
  |  Branch (1783:20): [True: 1, False: 263]
  ------------------
 1784|    193|                                TESTAFF(rv->astr, needaffix, rv->alen) ||
  ------------------
  |  |   99|    386|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 193]
  |  |  ------------------
  ------------------
 1785|    193|                                TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
  ------------------
  |  |   99|    386|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 1, False: 192]
  |  |  ------------------
  ------------------
 1786|    192|                                (is_sug && nosuggest &&
  ------------------
  |  Branch (1786:34): [True: 0, False: 192]
  |  Branch (1786:44): [True: 0, False: 0]
  ------------------
 1787|      1|                                 TESTAFF(rv->astr, nosuggest, rv->alen)))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1788|      1|          st[i] = ch;
 1789|       |          // continue;
 1790|      1|          break;
 1791|      1|        }
 1792|       |
 1793|       |        // check non_compound flag in suffix and prefix
 1794|   467M|        if ((rv) && !hu_mov_rule &&
  ------------------
  |  Branch (1794:13): [True: 263, False: 467M]
  |  Branch (1794:21): [True: 168, False: 95]
  ------------------
 1795|    168|            ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (1795:15): [True: 0, False: 168]
  |  Branch (1795:22): [True: 0, False: 0]
  ------------------
 1796|      0|              TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1797|    168|             (sfx && sfx->getCont() &&
  ------------------
  |  Branch (1797:15): [True: 0, False: 168]
  |  Branch (1797:22): [True: 0, False: 0]
  ------------------
 1798|      0|              TESTAFF(sfx->getCont(), compoundforbidflag,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1799|    168|                      sfx->getContLen())))) {
 1800|      0|          rv = nullptr;
 1801|      0|        }
 1802|       |
 1803|       |        // check compoundend flag in suffix and prefix
 1804|   467M|        if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&
  ------------------
  |  Branch (1804:13): [True: 263, False: 467M]
  |  Branch (1804:21): [True: 263, False: 0]
  |  Branch (1804:40): [True: 0, False: 263]
  |  Branch (1804:55): [True: 0, False: 0]
  ------------------
 1805|      0|            ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (1805:15): [True: 0, False: 0]
  |  Branch (1805:22): [True: 0, False: 0]
  ------------------
 1806|      0|              TESTAFF(pfx->getCont(), compoundend, pfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1807|      0|             (sfx && sfx->getCont() &&
  ------------------
  |  Branch (1807:15): [True: 0, False: 0]
  |  Branch (1807:22): [True: 0, False: 0]
  ------------------
 1808|      0|              TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1809|      0|          rv = nullptr;
 1810|      0|        }
 1811|       |
 1812|       |        // check compoundmiddle flag in suffix and prefix
 1813|   467M|        if ((rv) && !checked_prefix && (wordnum == 0) && compoundmiddle &&
  ------------------
  |  Branch (1813:13): [True: 263, False: 467M]
  |  Branch (1813:21): [True: 263, False: 0]
  |  Branch (1813:40): [True: 168, False: 95]
  |  Branch (1813:58): [True: 0, False: 168]
  ------------------
 1814|      0|            !hu_mov_rule &&
  ------------------
  |  Branch (1814:13): [True: 0, False: 0]
  ------------------
 1815|      0|            ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (1815:15): [True: 0, False: 0]
  |  Branch (1815:22): [True: 0, False: 0]
  ------------------
 1816|      0|              TESTAFF(pfx->getCont(), compoundmiddle, pfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1817|      0|             (sfx && sfx->getCont() &&
  ------------------
  |  Branch (1817:15): [True: 0, False: 0]
  |  Branch (1817:22): [True: 0, False: 0]
  ------------------
 1818|      0|              TESTAFF(sfx->getCont(), compoundmiddle, sfx->getContLen())))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1819|      0|          rv = nullptr;
 1820|      0|        }
 1821|       |
 1822|       |        // check forbiddenwords
 1823|   467M|        if ((rv) && (rv->astr) &&
  ------------------
  |  Branch (1823:13): [True: 263, False: 467M]
  |  Branch (1823:13): [True: 0, False: 467M]
  |  Branch (1823:21): [True: 192, False: 71]
  ------------------
 1824|    192|            (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|    384|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 192]
  |  |  ------------------
  ------------------
 1825|    192|             TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
  ------------------
  |  |   99|    384|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 192]
  |  |  ------------------
  ------------------
 1826|    192|             (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1826:15): [True: 0, False: 192]
  |  Branch (1826:25): [True: 0, False: 0]
  ------------------
 1827|      0|          return nullptr;
 1828|      0|        }
 1829|       |
 1830|       |        // increment word number, if the second root has a compoundroot flag
 1831|   467M|        if ((rv) && compoundroot &&
  ------------------
  |  Branch (1831:13): [True: 263, False: 467M]
  |  Branch (1831:21): [True: 0, False: 263]
  ------------------
 1832|      0|            (TESTAFF(rv->astr, compoundroot, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1832:13): [True: 0, False: 0]
  ------------------
 1833|      0|          wordnum++;
 1834|      0|        }
 1835|       |
 1836|       |        // first word is acceptable in compound words?
 1837|   467M|        if (((rv) &&
  ------------------
  |  Branch (1837:13): [True: 190, False: 467M]
  |  Branch (1837:14): [True: 263, False: 467M]
  ------------------
 1838|    263|             (checked_prefix || (words && words[wnum]) ||
  ------------------
  |  Branch (1838:15): [True: 0, False: 263]
  |  Branch (1838:34): [True: 0, False: 263]
  |  Branch (1838:43): [True: 0, False: 0]
  ------------------
 1839|    263|              (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|    263|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 190, False: 73]
  |  |  ------------------
  ------------------
  |  Branch (1839:16): [True: 263, False: 0]
  ------------------
 1840|     73|              ((oldwordnum == 0) && compoundbegin &&
  ------------------
  |  Branch (1840:16): [True: 0, False: 73]
  |  Branch (1840:37): [True: 0, False: 0]
  ------------------
 1841|      0|               TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1842|     73|              ((oldwordnum > 0) && compoundmiddle &&
  ------------------
  |  Branch (1842:16): [True: 0, False: 73]
  |  Branch (1842:36): [True: 0, False: 0]
  ------------------
 1843|      0|               TESTAFF(rv->astr, compoundmiddle, rv->alen))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1844|       |
 1845|       |              // LANG_hu section: spec. Hungarian rule
 1846|     73|              || ((langnum == LANG_hu) && hu_mov_rule &&
  ------------------
  |  Branch (1846:19): [True: 73, False: 0]
  |  Branch (1846:43): [True: 73, False: 0]
  ------------------
 1847|     73|                  (TESTAFF(
  ------------------
  |  |   99|    146|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 73]
  |  |  ------------------
  ------------------
 1848|     73|                       rv->astr, 'F',
 1849|     73|                       rv->alen) ||  // XXX hardwired Hungarian dictionary codes
 1850|     73|                   TESTAFF(rv->astr, 'G', rv->alen) ||
  ------------------
  |  |   99|    146|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 73]
  |  |  ------------------
  ------------------
 1851|     73|                   TESTAFF(rv->astr, 'H', rv->alen)))
  ------------------
  |  |   99|     73|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 73]
  |  |  ------------------
  ------------------
 1852|       |              // END of LANG_hu section
 1853|    263|              ) &&
 1854|    190|             (
 1855|       |                 // test CHECKCOMPOUNDPATTERN conditions
 1856|    190|                 scpd == 0 || checkcpdtable[scpd - 1].cond == FLAG_NULL ||
  ------------------
  |  |   96|    190|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1856:18): [True: 190, False: 0]
  |  Branch (1856:31): [True: 0, False: 0]
  ------------------
 1857|      0|                 TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond, rv->alen)) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1858|    190|             !((checkcompoundtriple && scpd == 0 &&
  ------------------
  |  Branch (1858:17): [True: 0, False: 190]
  |  Branch (1858:40): [True: 0, False: 0]
  ------------------
 1859|      0|                !words && i < word.size() && // test triple letters
  ------------------
  |  Branch (1859:17): [True: 0, False: 0]
  |  Branch (1859:27): [True: 0, False: 0]
  ------------------
 1860|      0|                (word[i - 1] == word[i]) &&
  ------------------
  |  Branch (1860:17): [True: 0, False: 0]
  ------------------
 1861|      0|                (((i > 1) && (word[i - 1] == word[i - 2])) ||
  ------------------
  |  Branch (1861:19): [True: 0, False: 0]
  |  Branch (1861:30): [True: 0, False: 0]
  ------------------
 1862|      0|                 ((word[i - 1] == word[i + 1]))  // may be word[i+1] == '\0'
  ------------------
  |  Branch (1862:18): [True: 0, False: 0]
  ------------------
 1863|      0|                 )) ||
 1864|    190|               (checkcompoundcase && scpd == 0 && !words && i < word.size() &&
  ------------------
  |  Branch (1864:17): [True: 0, False: 190]
  |  Branch (1864:38): [True: 0, False: 0]
  |  Branch (1864:51): [True: 0, False: 0]
  |  Branch (1864:61): [True: 0, False: 0]
  ------------------
 1865|      0|                cpdcase_check(word, i))))
  ------------------
  |  Branch (1865:17): [True: 0, False: 0]
  ------------------
 1866|       |            // LANG_hu section: spec. Hungarian rule
 1867|   467M|            || ((!rv) && (langnum == LANG_hu) && hu_mov_rule &&
  ------------------
  |  Branch (1867:17): [True: 467M, False: 73]
  |  Branch (1867:26): [True: 38.3M, False: 429M]
  |  Branch (1867:50): [True: 69.7k, False: 38.2M]
  ------------------
 1868|  69.7k|                (rv = affix_check(st, 0, i, scratch)) &&
  ------------------
  |  Branch (1868:17): [True: 0, False: 69.7k]
  ------------------
 1869|      0|                (sfx && sfx->getCont() &&
  ------------------
  |  Branch (1869:18): [True: 0, False: 0]
  |  Branch (1869:25): [True: 0, False: 0]
  ------------------
 1870|      0|                 (  // XXX hardwired Hungarian dic. codes
 1871|      0|                     TESTAFF(sfx->getCont(), (unsigned short)'x',
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1872|      0|                             sfx->getContLen()) ||
 1873|      0|                     TESTAFF(
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1874|      0|                         sfx->getCont(), (unsigned short)'%',
 1875|    190|                         sfx->getContLen()))))) {  // first word is ok condition
 1876|       |
 1877|       |          // LANG_hu section: spec. Hungarian rule
 1878|    190|          if (langnum == LANG_hu) {
  ------------------
  |  Branch (1878:15): [True: 166, False: 24]
  ------------------
 1879|       |            // calculate syllable number of the word
 1880|    166|            numsyllable += get_syllable(st.substr(0, i));
 1881|       |            // + 1 word, if syllable number of the prefix > 1 (hungarian
 1882|       |            // convention)
 1883|    166|            if (pfx && (get_syllable(pfx->getKey()) > 1))
  ------------------
  |  Branch (1883:17): [True: 0, False: 166]
  |  Branch (1883:17): [True: 0, False: 166]
  |  Branch (1883:24): [True: 0, False: 0]
  ------------------
 1884|      0|              wordnum++;
 1885|    166|          }
 1886|       |          // END of LANG_hu section
 1887|       |
 1888|       |          // NEXT WORD(S)
 1889|    190|          rv_first = rv;
 1890|    190|          st[i] = ch;
 1891|       |
 1892|    190|          do {  // striple loop
 1893|       |
 1894|       |            // check simplifiedtriple
 1895|    190|            if (simplifiedtriple) {
  ------------------
  |  Branch (1895:17): [True: 0, False: 190]
  ------------------
 1896|      0|              if (striple) {
  ------------------
  |  Branch (1896:19): [True: 0, False: 0]
  ------------------
 1897|      0|                checkedstriple = 1;
 1898|      0|                i--;  // check "fahrt" instead of "ahrt" in "Schiffahrt"
 1899|      0|              } else if (i > 2 && i <= word.size() && word[i - 1] == word[i - 2])
  ------------------
  |  Branch (1899:26): [True: 0, False: 0]
  |  Branch (1899:35): [True: 0, False: 0]
  |  Branch (1899:55): [True: 0, False: 0]
  ------------------
 1900|      0|                striple = 1;
 1901|      0|            }
 1902|       |
 1903|    190|            rv = lookup(st.c_str() + i, st.size() - i);  // perhaps without prefix
 1904|       |
 1905|       |            // search homonym with compound flag
 1906|    190|            while ((rv) && ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1906:20): [True: 0, False: 190]
  |  Branch (1906:30): [True: 0, False: 0]
  ------------------
 1907|      0|                            !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1907:32): [True: 0, False: 0]
  |  Branch (1907:48): [True: 0, False: 0]
  ------------------
 1908|      0|                              (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1908:32): [True: 0, False: 0]
  |  Branch (1908:47): [True: 0, False: 0]
  ------------------
 1909|      0|                              (!defcpdtable.empty() && words && defcpd_check(&words, wnum + 1, maxwordnum, rv, nullptr, 1))) ||
  ------------------
  |  Branch (1909:32): [True: 0, False: 0]
  |  Branch (1909:56): [True: 0, False: 0]
  |  Branch (1909:65): [True: 0, False: 0]
  ------------------
 1910|      0|                            (scpd != 0 && checkcpdtable[scpd - 1].cond2 != FLAG_NULL &&
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1910:30): [True: 0, False: 0]
  |  Branch (1910:43): [True: 0, False: 0]
  ------------------
 1911|      0|                             !TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen)))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1911:30): [True: 0, False: 0]
  ------------------
 1912|      0|              rv = rv->next_homonym;
 1913|      0|            }
 1914|       |
 1915|       |            // check FORCEUCASE
 1916|    190|            if (rv && forceucase &&
  ------------------
  |  Branch (1916:17): [True: 0, False: 190]
  |  Branch (1916:23): [True: 0, False: 0]
  ------------------
 1917|      0|                (TESTAFF(rv->astr, forceucase, rv->alen)) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1917:17): [True: 0, False: 0]
  ------------------
 1918|      0|                !(info && *info & SPELL_ORIGCAP))
  ------------------
  |  |   83|      0|#define SPELL_ORIGCAP (1 << 5)
  ------------------
  |  Branch (1918:19): [True: 0, False: 0]
  |  Branch (1918:27): [True: 0, False: 0]
  ------------------
 1919|      0|              rv = nullptr;
 1920|       |
 1921|    190|            if (rv && words && words[wnum + 1])
  ------------------
  |  Branch (1921:17): [True: 0, False: 190]
  |  Branch (1921:23): [True: 0, False: 0]
  |  Branch (1921:32): [True: 0, False: 0]
  ------------------
 1922|      0|              return rv_first;
 1923|       |
 1924|    190|            oldnumsyllable2 = numsyllable;
 1925|    190|            oldwordnum2 = wordnum;
 1926|       |
 1927|       |            // LANG_hu section: spec. Hungarian rule, XXX hardwired dictionary
 1928|       |            // code
 1929|    190|            if ((rv) && (langnum == LANG_hu) &&
  ------------------
  |  Branch (1929:17): [True: 0, False: 190]
  |  Branch (1929:17): [True: 0, False: 190]
  |  Branch (1929:25): [True: 0, False: 0]
  ------------------
 1930|      0|                (TESTAFF(rv->astr, 'I', rv->alen)) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1930:17): [True: 0, False: 0]
  ------------------
 1931|      0|                !(TESTAFF(rv->astr, 'J', rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1931:17): [True: 0, False: 0]
  ------------------
 1932|      0|              numsyllable--;
 1933|      0|            }
 1934|       |            // END of LANG_hu section
 1935|       |
 1936|       |            // increment word number, if the second root has a compoundroot flag
 1937|    190|            if ((rv) && (compoundroot) &&
  ------------------
  |  Branch (1937:17): [True: 0, False: 190]
  |  Branch (1937:25): [True: 0, False: 0]
  ------------------
 1938|      0|                (TESTAFF(rv->astr, compoundroot, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (1938:17): [True: 0, False: 0]
  ------------------
 1939|      0|              wordnum++;
 1940|      0|            }
 1941|       |
 1942|       |            // check forbiddenwords
 1943|    190|            if ((rv) && (rv->astr) &&
  ------------------
  |  Branch (1943:17): [True: 0, False: 190]
  |  Branch (1943:17): [True: 0, False: 190]
  |  Branch (1943:25): [True: 0, False: 0]
  ------------------
 1944|      0|                (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1945|      0|                 TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1946|      0|                 (is_sug && nosuggest &&
  ------------------
  |  Branch (1946:19): [True: 0, False: 0]
  |  Branch (1946:29): [True: 0, False: 0]
  ------------------
 1947|      0|                  TESTAFF(rv->astr, nosuggest, rv->alen))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1948|      0|              return nullptr;
 1949|       |
 1950|       |            // second word is acceptable, as a root?
 1951|       |            // hungarian conventions: compounding is acceptable,
 1952|       |            // when compound forms consist of 2 words, or if more,
 1953|       |            // then the syllable number of root words must be 6, or lesser.
 1954|       |
 1955|    190|            if ((rv) &&
  ------------------
  |  Branch (1955:17): [True: 0, False: 190]
  |  Branch (1955:17): [True: 0, False: 190]
  ------------------
 1956|      0|                ((compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1956:19): [True: 0, False: 0]
  ------------------
 1957|      0|                 (compoundend && TESTAFF(rv->astr, compoundend, rv->alen))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1957:19): [True: 0, False: 0]
  ------------------
 1958|      0|                (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
  ------------------
  |  Branch (1958:19): [True: 0, False: 0]
  |  Branch (1958:41): [True: 0, False: 0]
  ------------------
 1959|      0|                 ((cpdmaxsyllable != 0) &&
  ------------------
  |  Branch (1959:19): [True: 0, False: 0]
  ------------------
 1960|      0|                  (numsyllable + get_syllable(std::string(HENTRY_WORD(rv), rv->blen)) <=
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
  |  Branch (1960:19): [True: 0, False: 0]
  ------------------
 1961|      0|                   cpdmaxsyllable))) &&
 1962|      0|                (
 1963|       |                    // test CHECKCOMPOUNDPATTERN
 1964|      0|                    checkcpdtable.empty() || scpd != 0 ||
  ------------------
  |  Branch (1964:21): [True: 0, False: 0]
  |  Branch (1964:46): [True: 0, False: 0]
  ------------------
 1965|      0|                    (i < word.size() && !cpdpat_check(word, i, rv_first, rv, 0))) &&
  ------------------
  |  Branch (1965:22): [True: 0, False: 0]
  |  Branch (1965:41): [True: 0, False: 0]
  ------------------
 1966|      0|                ((!checkcompounddup || (rv != rv_first)))
  ------------------
  |  Branch (1966:19): [True: 0, False: 0]
  |  Branch (1966:40): [True: 0, False: 0]
  ------------------
 1967|       |                // test CHECKCOMPOUNDPATTERN conditions
 1968|      0|                &&
 1969|      0|                (scpd == 0 || checkcpdtable[scpd - 1].cond2 == FLAG_NULL ||
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1969:18): [True: 0, False: 0]
  |  Branch (1969:31): [True: 0, False: 0]
  ------------------
 1970|      0|                 TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1971|       |              // forbid compound word, if it is a non-compound word with typical
 1972|       |              // fault
 1973|      0|              if ((checkcompoundrep && cpdrep_check(word, len, scratch, timelimit_exceeded, clock_time_start)) ||
  ------------------
  |  Branch (1973:20): [True: 0, False: 0]
  |  Branch (1973:40): [True: 0, False: 0]
  ------------------
 1974|      0|                  cpdwordpair_check(word, len, scratch, timelimit_exceeded, clock_time_start))
  ------------------
  |  Branch (1974:19): [True: 0, False: 0]
  ------------------
 1975|      0|                return nullptr;
 1976|      0|              return rv_first;
 1977|      0|            }
 1978|       |
 1979|    190|            numsyllable = oldnumsyllable2;
 1980|    190|            wordnum = oldwordnum2;
 1981|       |
 1982|       |            // perhaps second word has prefix or/and suffix
 1983|    190|            sfx = nullptr;
 1984|    190|            sfxflag = FLAG_NULL;
  ------------------
  |  |   96|    190|#define FLAG_NULL 0x00
  ------------------
 1985|    190|            rv = (compoundflag && !onlycpdrule && i < word.size()) ? affix_check(word, i, word.size() - i, scratch, compoundflag, IN_CPD_END)
  ------------------
  |  |   74|    190|#define IN_CPD_END 2
  ------------------
  |  Branch (1985:19): [True: 190, False: 0]
  |  Branch (1985:35): [True: 190, False: 0]
  |  Branch (1985:51): [True: 190, False: 0]
  ------------------
 1986|    190|                                                                   : nullptr;
 1987|    190|            if (!rv && compoundend && !onlycpdrule) {
  ------------------
  |  Branch (1987:17): [True: 190, False: 0]
  |  Branch (1987:24): [True: 0, False: 190]
  |  Branch (1987:39): [True: 0, False: 0]
  ------------------
 1988|      0|              sfx = nullptr;
 1989|      0|              pfx = nullptr;
 1990|      0|              if (i < word.size())
  ------------------
  |  Branch (1990:19): [True: 0, False: 0]
  ------------------
 1991|      0|                rv = affix_check(word, i, word.size() - i, scratch, compoundend, IN_CPD_END);
  ------------------
  |  |   74|      0|#define IN_CPD_END 2
  ------------------
 1992|      0|            }
 1993|       |
 1994|    190|            if (!rv && !defcpdtable.empty() && words) {
  ------------------
  |  Branch (1994:17): [True: 190, False: 0]
  |  Branch (1994:24): [True: 0, False: 190]
  |  Branch (1994:48): [True: 0, False: 0]
  ------------------
 1995|      0|              if (i < word.size())
  ------------------
  |  Branch (1995:19): [True: 0, False: 0]
  ------------------
 1996|      0|                rv = affix_check(word, i, word.size() - i, scratch, 0, IN_CPD_END);
  ------------------
  |  |   74|      0|#define IN_CPD_END 2
  ------------------
 1997|      0|              if (rv && defcpd_check(&words, wnum + 1, maxwordnum, rv, nullptr, 1))
  ------------------
  |  Branch (1997:19): [True: 0, False: 0]
  |  Branch (1997:25): [True: 0, False: 0]
  ------------------
 1998|      0|                return rv_first;
 1999|      0|              rv = nullptr;
 2000|      0|            }
 2001|       |
 2002|       |            // test CHECKCOMPOUNDPATTERN conditions (allowed forms)
 2003|    190|            if (rv &&
  ------------------
  |  Branch (2003:17): [True: 0, False: 190]
  ------------------
 2004|      0|                !(scpd == 0 || checkcpdtable[scpd - 1].cond2 == FLAG_NULL ||
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
  |  Branch (2004:19): [True: 0, False: 0]
  |  Branch (2004:32): [True: 0, False: 0]
  ------------------
 2005|      0|                  TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen)))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2006|      0|              rv = nullptr;
 2007|       |
 2008|       |            // test CHECKCOMPOUNDPATTERN conditions (forbidden compounds)
 2009|    190|            if (rv && !checkcpdtable.empty() && scpd == 0 &&
  ------------------
  |  Branch (2009:17): [True: 0, False: 190]
  |  Branch (2009:23): [True: 0, False: 0]
  |  Branch (2009:49): [True: 0, False: 0]
  ------------------
 2010|      0|                cpdpat_check(word, i, rv_first, rv, affixed))
  ------------------
  |  Branch (2010:17): [True: 0, False: 0]
  ------------------
 2011|      0|              rv = nullptr;
 2012|       |
 2013|       |            // check non_compound flag in suffix and prefix
 2014|    190|            if ((rv) && ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (2014:17): [True: 0, False: 190]
  |  Branch (2014:27): [True: 0, False: 0]
  |  Branch (2014:34): [True: 0, False: 0]
  ------------------
 2015|      0|                          TESTAFF(pfx->getCont(), compoundforbidflag,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2016|      0|                                  pfx->getContLen())) ||
 2017|      0|                         (sfx && sfx->getCont() &&
  ------------------
  |  Branch (2017:27): [True: 0, False: 0]
  |  Branch (2017:34): [True: 0, False: 0]
  ------------------
 2018|      0|                          TESTAFF(sfx->getCont(), compoundforbidflag,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2019|      0|                                  sfx->getContLen())))) {
 2020|      0|              rv = nullptr;
 2021|      0|            }
 2022|       |
 2023|       |            // check FORCEUCASE
 2024|    190|            if (rv && forceucase &&
  ------------------
  |  Branch (2024:17): [True: 0, False: 190]
  |  Branch (2024:23): [True: 0, False: 0]
  ------------------
 2025|      0|                (TESTAFF(rv->astr, forceucase, rv->alen)) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2025:17): [True: 0, False: 0]
  ------------------
 2026|      0|                !(info && *info & SPELL_ORIGCAP))
  ------------------
  |  |   83|      0|#define SPELL_ORIGCAP (1 << 5)
  ------------------
  |  Branch (2026:19): [True: 0, False: 0]
  |  Branch (2026:27): [True: 0, False: 0]
  ------------------
 2027|      0|              rv = nullptr;
 2028|       |
 2029|       |            // check forbiddenwords
 2030|    190|            if ((rv) && (rv->astr) &&
  ------------------
  |  Branch (2030:17): [True: 0, False: 190]
  |  Branch (2030:17): [True: 0, False: 190]
  |  Branch (2030:25): [True: 0, False: 0]
  ------------------
 2031|      0|                (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2032|      0|                 TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2033|      0|                 (is_sug && nosuggest &&
  ------------------
  |  Branch (2033:19): [True: 0, False: 0]
  |  Branch (2033:29): [True: 0, False: 0]
  ------------------
 2034|      0|                  TESTAFF(rv->astr, nosuggest, rv->alen))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2035|      0|              return nullptr;
 2036|       |
 2037|       |            // pfxappnd = prefix of word+i, or NULL
 2038|       |            // calculate syllable number of prefix.
 2039|       |            // hungarian convention: when syllable number of prefix is more,
 2040|       |            // than 1, the prefix+word counts as two words.
 2041|       |
 2042|    190|            if (langnum == LANG_hu) {
  ------------------
  |  Branch (2042:17): [True: 166, False: 24]
  ------------------
 2043|    166|              if (i < word.size()) {
  ------------------
  |  Branch (2043:19): [True: 166, False: 0]
  ------------------
 2044|       |                // calculate syllable number of the word
 2045|    166|                numsyllable += get_syllable(word.substr(i));
 2046|    166|              }
 2047|       |
 2048|       |              // - affix syllable num.
 2049|       |              // XXX only second suffix (inflections, not derivations)
 2050|    166|              if (sfxappnd) {
  ------------------
  |  Branch (2050:19): [True: 0, False: 166]
  ------------------
 2051|      0|                std::string tmp(sfxappnd);
 2052|      0|                reverseword(tmp);
 2053|      0|                numsyllable -= short(get_syllable(tmp) + sfxextra);
 2054|    166|              } else {
 2055|    166|                numsyllable -= short(sfxextra);
 2056|    166|              }
 2057|       |
 2058|       |              // + 1 word, if syllable number of the prefix > 1 (hungarian
 2059|       |              // convention)
 2060|    166|              if (pfx && (get_syllable(pfx->getKey()) > 1))
  ------------------
  |  Branch (2060:19): [True: 0, False: 166]
  |  Branch (2060:19): [True: 0, False: 166]
  |  Branch (2060:26): [True: 0, False: 0]
  ------------------
 2061|      0|                wordnum++;
 2062|       |
 2063|       |              // increment syllable num, if last word has a SYLLABLENUM flag
 2064|       |              // and the suffix is beginning `s'
 2065|       |
 2066|    166|              if (!cpdsyllablenum.empty()) {
  ------------------
  |  Branch (2066:19): [True: 0, False: 166]
  ------------------
 2067|      0|                switch (sfxflag) {
  ------------------
  |  Branch (2067:25): [True: 0, False: 0]
  ------------------
 2068|      0|                  case 'c': {
  ------------------
  |  Branch (2068:19): [True: 0, False: 0]
  ------------------
 2069|      0|                    numsyllable += 2;
 2070|      0|                    break;
 2071|      0|                  }
 2072|      0|                  case 'J': {
  ------------------
  |  Branch (2072:19): [True: 0, False: 0]
  ------------------
 2073|      0|                    numsyllable += 1;
 2074|      0|                    break;
 2075|      0|                  }
 2076|      0|                  case 'I': {
  ------------------
  |  Branch (2076:19): [True: 0, False: 0]
  ------------------
 2077|      0|                    if (rv && TESTAFF(rv->astr, 'J', rv->alen))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2077:25): [True: 0, False: 0]
  |  Branch (2077:25): [True: 0, False: 0]
  ------------------
 2078|      0|                      numsyllable += 1;
 2079|      0|                    break;
 2080|      0|                  }
 2081|      0|                }
 2082|      0|              }
 2083|    166|            }
 2084|       |
 2085|       |            // increment word number, if the second word has a compoundroot flag
 2086|    190|            if ((rv) && (compoundroot) &&
  ------------------
  |  Branch (2086:17): [True: 0, False: 190]
  |  Branch (2086:25): [True: 0, False: 0]
  ------------------
 2087|      0|                (TESTAFF(rv->astr, compoundroot, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2087:17): [True: 0, False: 0]
  ------------------
 2088|      0|              wordnum++;
 2089|      0|            }
 2090|       |            // second word is acceptable, as a word with prefix or/and suffix?
 2091|       |            // hungarian conventions: compounding is acceptable,
 2092|       |            // when compound forms consist 2 word, otherwise
 2093|       |            // the syllable number of root words is 6, or lesser.
 2094|    190|            if ((rv) &&
  ------------------
  |  Branch (2094:17): [True: 0, False: 190]
  ------------------
 2095|      0|                (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
  ------------------
  |  Branch (2095:19): [True: 0, False: 0]
  |  Branch (2095:41): [True: 0, False: 0]
  ------------------
 2096|      0|                 ((cpdmaxsyllable != 0) && (numsyllable <= cpdmaxsyllable))) &&
  ------------------
  |  Branch (2096:19): [True: 0, False: 0]
  |  Branch (2096:44): [True: 0, False: 0]
  ------------------
 2097|      0|                ((!checkcompounddup || (rv != rv_first)))) {
  ------------------
  |  Branch (2097:19): [True: 0, False: 0]
  |  Branch (2097:40): [True: 0, False: 0]
  ------------------
 2098|       |              // forbid compound word, if it is a non-compound word with typical
 2099|       |              // fault
 2100|      0|              if ((checkcompoundrep && cpdrep_check(word, len, scratch, timelimit_exceeded, clock_time_start)) ||
  ------------------
  |  Branch (2100:20): [True: 0, False: 0]
  |  Branch (2100:40): [True: 0, False: 0]
  ------------------
 2101|      0|                  cpdwordpair_check(word, len, scratch, timelimit_exceeded, clock_time_start))
  ------------------
  |  Branch (2101:19): [True: 0, False: 0]
  ------------------
 2102|      0|                return nullptr;
 2103|      0|              return rv_first;
 2104|      0|            }
 2105|       |
 2106|    190|            numsyllable = oldnumsyllable2;
 2107|    190|            wordnum = oldwordnum2;
 2108|       |
 2109|       |            // perhaps second word is a compound word (recursive call)
 2110|       |            // (only if SPELL_COMPOUND_2 is not set and maxwordnum is not exceeded)
 2111|    190|            if ((!info || !(*info & SPELL_COMPOUND_2)) && wordnum + 2 < maxwordnum && wnum + 1 < maxwordnum) {
  ------------------
  |  |   85|    190|#define SPELL_COMPOUND_2 (1 << 7)  // permit only 2 dictionary words in the compound
  ------------------
  |  Branch (2111:18): [True: 0, False: 190]
  |  Branch (2111:27): [True: 106, False: 84]
  |  Branch (2111:59): [True: 106, False: 0]
  |  Branch (2111:87): [True: 106, False: 0]
  ------------------
 2112|    106|              rv = compound_check(st.substr(i), wordnum + 1,
 2113|    106|                                  numsyllable, maxwordnum, wnum + 1, words, rwords, 0,
 2114|    106|                                  is_sug, info, scratch);
 2115|       |
 2116|    106|              if (rv && !checkcpdtable.empty() && i < word.size() &&
  ------------------
  |  Branch (2116:19): [True: 0, False: 106]
  |  Branch (2116:25): [True: 0, False: 0]
  |  Branch (2116:51): [True: 0, False: 0]
  ------------------
 2117|      0|                  ((scpd == 0 &&
  ------------------
  |  Branch (2117:21): [True: 0, False: 0]
  ------------------
 2118|      0|                    cpdpat_check(word, i, rv_first, rv, affixed)) ||
  ------------------
  |  Branch (2118:21): [True: 0, False: 0]
  ------------------
 2119|      0|                   (scpd != 0 &&
  ------------------
  |  Branch (2119:21): [True: 0, False: 0]
  ------------------
 2120|      0|                    !cpdpat_check(word, i, rv_first, rv, affixed))))
  ------------------
  |  Branch (2120:21): [True: 0, False: 0]
  ------------------
 2121|      0|                rv = nullptr;
 2122|    106|            } else {
 2123|     84|              rv = nullptr;
 2124|     84|            }
 2125|    190|            if (rv) {
  ------------------
  |  Branch (2125:17): [True: 0, False: 190]
  ------------------
 2126|       |              // forbid compound word, if it is a non-compound word with typical
 2127|       |              // fault, or a dictionary word pair
 2128|       |
 2129|      0|              if (cpdwordpair_check(word, len, scratch, timelimit_exceeded, clock_time_start))
  ------------------
  |  Branch (2129:19): [True: 0, False: 0]
  ------------------
 2130|      0|                return nullptr;
 2131|       |
 2132|      0|              if (checkcompoundrep || forbiddenword) {
  ------------------
  |  Branch (2132:19): [True: 0, False: 0]
  |  Branch (2132:39): [True: 0, False: 0]
  ------------------
 2133|      0|                if (checkcompoundrep && cpdrep_check(word, len, scratch, timelimit_exceeded, clock_time_start))
  ------------------
  |  Branch (2133:21): [True: 0, False: 0]
  |  Branch (2133:41): [True: 0, False: 0]
  ------------------
 2134|      0|                  return nullptr;
 2135|       |
 2136|       |                // check first part
 2137|      0|                if (i < word.size() && word.compare(i, rv->blen, rv->word, rv->blen) == 0) {
  ------------------
  |  Branch (2137:21): [True: 0, False: 0]
  |  Branch (2137:40): [True: 0, False: 0]
  ------------------
 2138|      0|                  char r = st[i + rv->blen];
 2139|      0|                  st[i + rv->blen] = '\0';
 2140|       |
 2141|      0|                  if ((checkcompoundrep && cpdrep_check(st, i + rv->blen, scratch, timelimit_exceeded, clock_time_start)) ||
  ------------------
  |  Branch (2141:24): [True: 0, False: 0]
  |  Branch (2141:44): [True: 0, False: 0]
  ------------------
 2142|      0|                      cpdwordpair_check(st, i + rv->blen, scratch, timelimit_exceeded, clock_time_start)) {
  ------------------
  |  Branch (2142:23): [True: 0, False: 0]
  ------------------
 2143|      0|                    st[ + i + rv->blen] = r;
 2144|      0|                    continue;
 2145|      0|                  }
 2146|       |
 2147|      0|                  if (forbiddenword) {
  ------------------
  |  Branch (2147:23): [True: 0, False: 0]
  ------------------
 2148|      0|                    struct hentry* rv2 = lookup(word.c_str(), word.size());
 2149|      0|                    if (!rv2 && len <= word.size())
  ------------------
  |  Branch (2149:25): [True: 0, False: 0]
  |  Branch (2149:33): [True: 0, False: 0]
  ------------------
 2150|      0|                      rv2 = affix_check(word, 0, len, scratch);
 2151|      0|                    if (rv2 && rv2->astr &&
  ------------------
  |  Branch (2151:25): [True: 0, False: 0]
  |  Branch (2151:32): [True: 0, False: 0]
  ------------------
 2152|      0|                        TESTAFF(rv2->astr, forbiddenword, rv2->alen) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2153|      0|                        (strncmp(rv2->word, st.c_str(), i + rv->blen) == 0)) {
  ------------------
  |  Branch (2153:25): [True: 0, False: 0]
  ------------------
 2154|      0|                      return nullptr;
 2155|      0|                    }
 2156|      0|                  }
 2157|      0|                  st[i + rv->blen] = r;
 2158|      0|                }
 2159|      0|              }
 2160|      0|              return rv_first;
 2161|      0|            }
 2162|    190|          } while (striple && !checkedstriple);  // end of striple loop
  ------------------
  |  Branch (2162:20): [True: 0, False: 190]
  |  Branch (2162:31): [True: 0, False: 0]
  ------------------
 2163|       |
 2164|    190|          if (checkedstriple) {
  ------------------
  |  Branch (2164:15): [True: 0, False: 190]
  ------------------
 2165|      0|            i++;
 2166|      0|            checkedstriple = 0;
 2167|      0|            striple = 0;
 2168|      0|          }
 2169|       |
 2170|    190|        }  // first word is ok condition
 2171|       |
 2172|   467M|        if (soldi != 0) {
  ------------------
  |  Branch (2172:13): [True: 0, False: 467M]
  ------------------
 2173|      0|          i = soldi;
 2174|      0|          soldi = 0;
 2175|      0|          len = oldlen;
 2176|      0|          cmin = oldcmin;
 2177|      0|          cmax = oldcmax;
 2178|      0|        }
 2179|   467M|        scpd++;
 2180|       |
 2181|   467M|      } while (!onlycpdrule && simplifiedcpd &&
  ------------------
  |  Branch (2181:16): [True: 467M, False: 0]
  |  Branch (2181:32): [True: 0, False: 467M]
  ------------------
 2182|      0|               scpd <= checkcpdtable.size());  // end of simplifiedcpd loop
  ------------------
  |  Branch (2182:16): [True: 0, False: 0]
  ------------------
 2183|       |
 2184|   467M|      scpd = 0;
 2185|   467M|      wordnum = oldwordnum;
 2186|   467M|      numsyllable = oldnumsyllable;
 2187|       |
 2188|   467M|      if (soldi != 0) {
  ------------------
  |  Branch (2188:11): [True: 0, False: 467M]
  ------------------
 2189|      0|        i = soldi;
 2190|      0|        st.assign(word);  // XXX add more optim.
 2191|      0|        soldi = 0;
 2192|      0|        len = oldlen;
 2193|      0|        cmin = oldcmin;
 2194|      0|        cmax = oldcmax;
 2195|      0|      } else
 2196|   467M|        st[i] = ch;
 2197|       |
 2198|   467M|    } while (!defcpdtable.empty() && oldwordnum == 0 &&
  ------------------
  |  Branch (2198:14): [True: 0, False: 467M]
  |  Branch (2198:38): [True: 0, False: 0]
  ------------------
 2199|      0|             onlycpdrule++ < 1);  // end of onlycpd loop
  ------------------
  |  Branch (2199:14): [True: 0, False: 0]
  ------------------
 2200|   468M|  }
 2201|       |
 2202|  17.3M|  return nullptr;
 2203|  18.0M|}
_ZN8AffixMgr20compound_check_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEssssPP6hentrySB_cRS6_PS7_R12AffixScratch:
 2217|  1.75k|                                   AffixScratch& scratch) {
 2218|  1.75k|  short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;
 2219|  1.75k|  hentry *rv = nullptr, *rv_first;
 2220|  1.75k|  std::string st, presult;
 2221|  1.75k|  char ch, affixed = 0;
 2222|  1.75k|  int checked_prefix, ok = 0;
 2223|  1.75k|  size_t cmin, cmax;
 2224|  1.75k|  hentry** oldwords = words;
 2225|  1.75k|  size_t len = word.size();
 2226|       |
 2227|       |  // protect subsequent words[wnum + 1] reads and any recursion
 2228|  1.75k|  if (wnum + 1 >= maxwordnum)
  ------------------
  |  Branch (2228:7): [True: 0, False: 1.75k]
  ------------------
 2229|      0|    return 0;
 2230|       |
 2231|       |  // add a time limit to handle possible
 2232|       |  // combinatorical explosion of the overlapping words
 2233|       |
 2234|  1.75k|  HUNSPELL_THREAD_LOCAL std::chrono::steady_clock::time_point clock_time_start;
  ------------------
  |  |   60|  1.75k|#  define HUNSPELL_THREAD_LOCAL thread_local
  ------------------
 2235|  1.75k|  HUNSPELL_THREAD_LOCAL bool timelimit_exceeded;
  ------------------
  |  |   60|  1.75k|#  define HUNSPELL_THREAD_LOCAL thread_local
  ------------------
 2236|       |
 2237|       |  // get the current time
 2238|  1.75k|  std::chrono::steady_clock::time_point clock_now = std::chrono::steady_clock::now();
 2239|       |
 2240|  1.75k|  if (wnum == 0) {
  ------------------
  |  Branch (2240:7): [True: 1.75k, False: 0]
  ------------------
 2241|       |      // set the start time
 2242|  1.75k|      clock_time_start = clock_now;
 2243|  1.75k|      timelimit_exceeded = false;
 2244|  1.75k|  }
 2245|      0|  else if (clock_now - clock_time_start > TIMELIMIT_MS)
  ------------------
  |  |  106|      0|#define TIMELIMIT_MS std::chrono::milliseconds(50)
  ------------------
  |  Branch (2245:12): [True: 0, False: 0]
  ------------------
 2246|      0|      timelimit_exceeded = true;
 2247|       |
 2248|  1.75k|  setcminmax(&cmin, &cmax, word.c_str(), len);
 2249|       |
 2250|  1.75k|  st.assign(word);
 2251|       |
 2252|  25.1k|  for (size_t i = cmin; i < cmax; ++i) {
  ------------------
  |  Branch (2252:25): [True: 23.5k, False: 1.58k]
  ------------------
 2253|       |    // go to end of the UTF-8 character
 2254|  23.5k|    if (utf8) {
  ------------------
  |  Branch (2254:9): [True: 8.00k, False: 15.5k]
  ------------------
 2255|  10.8k|      for (; is_utf8_cont(st[i]); i++)
  ------------------
  |  Branch (2255:14): [True: 2.85k, False: 8.00k]
  ------------------
 2256|  2.85k|        ;
 2257|  8.00k|      if (i >= cmax)
  ------------------
  |  Branch (2257:11): [True: 64, False: 7.94k]
  ------------------
 2258|     64|        return 0;
 2259|  8.00k|    }
 2260|       |
 2261|  23.5k|    words = oldwords;
 2262|  23.5k|    int onlycpdrule = (words) ? 1 : 0;
  ------------------
  |  Branch (2262:23): [True: 0, False: 23.5k]
  ------------------
 2263|       |
 2264|  23.5k|    do {  // onlycpdrule loop
 2265|       |
 2266|  23.5k|      if (timelimit_exceeded)
  ------------------
  |  Branch (2266:11): [True: 0, False: 23.5k]
  ------------------
 2267|      0|        return 0;
 2268|       |
 2269|  23.5k|      oldnumsyllable = numsyllable;
 2270|  23.5k|      oldwordnum = wordnum;
 2271|  23.5k|      checked_prefix = 0;
 2272|       |
 2273|  23.5k|      if (i >= st.size())
  ------------------
  |  Branch (2273:11): [True: 111, False: 23.4k]
  ------------------
 2274|    111|        return 0;
 2275|       |
 2276|  23.4k|      ch = st[i];
 2277|  23.4k|      st[i] = '\0';
 2278|  23.4k|      sfx = nullptr;
 2279|       |
 2280|       |      // FIRST WORD
 2281|       |
 2282|  23.4k|      affixed = 1;
 2283|       |
 2284|  23.4k|      presult.clear();
 2285|  23.4k|      if (partresult)
  ------------------
  |  Branch (2285:11): [True: 0, False: 23.4k]
  ------------------
 2286|      0|        presult.append(*partresult);
 2287|       |
 2288|  23.4k|      rv = lookup(st.c_str(), i);  // perhaps without prefix
 2289|       |
 2290|       |      // forbid dictionary stems with COMPOUNDFORBIDFLAG in
 2291|       |      // compound words, overriding the effect of COMPOUNDPERMITFLAG
 2292|  23.4k|      if ((rv) && compoundforbidflag &&
  ------------------
  |  Branch (2292:11): [True: 123, False: 23.3k]
  |  Branch (2292:19): [True: 27, False: 96]
  ------------------
 2293|     27|              TESTAFF(rv->astr, compoundforbidflag, rv->alen) && !hu_mov_rule)
  ------------------
  |  |   99|  23.4k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 27]
  |  |  ------------------
  ------------------
  |  Branch (2293:66): [True: 0, False: 0]
  ------------------
 2294|      0|          continue;
 2295|       |
 2296|       |      // search homonym with compound flag
 2297|  23.5k|      while ((rv) && !hu_mov_rule &&
  ------------------
  |  Branch (2297:14): [True: 123, False: 23.4k]
  |  Branch (2297:22): [True: 123, False: 0]
  ------------------
 2298|    123|             ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
  ------------------
  |  |   99|     32|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 32]
  |  |  ------------------
  ------------------
  |  Branch (2298:16): [True: 32, False: 91]
  ------------------
 2299|    123|              !((compoundflag && !words && !onlycpdrule &&
  ------------------
  |  Branch (2299:18): [True: 123, False: 0]
  |  Branch (2299:34): [True: 123, False: 0]
  |  Branch (2299:44): [True: 123, False: 0]
  ------------------
 2300|    123|                 TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|    123|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 123]
  |  |  ------------------
  ------------------
 2301|    123|                (compoundbegin && !wordnum && !onlycpdrule &&
  ------------------
  |  Branch (2301:18): [True: 0, False: 123]
  |  Branch (2301:35): [True: 0, False: 0]
  |  Branch (2301:47): [True: 0, False: 0]
  ------------------
 2302|      0|                 TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2303|    123|                (compoundmiddle && wordnum && !words && !onlycpdrule &&
  ------------------
  |  Branch (2303:18): [True: 0, False: 123]
  |  Branch (2303:36): [True: 0, False: 0]
  |  Branch (2303:47): [True: 0, False: 0]
  |  Branch (2303:57): [True: 0, False: 0]
  ------------------
 2304|      0|                 TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2305|    123|                (!defcpdtable.empty() && onlycpdrule &&
  ------------------
  |  Branch (2305:18): [True: 0, False: 123]
  |  Branch (2305:42): [True: 0, False: 0]
  ------------------
 2306|      0|                 ((!words && !wordnum &&
  ------------------
  |  Branch (2306:20): [True: 0, False: 0]
  |  Branch (2306:30): [True: 0, False: 0]
  ------------------
 2307|      0|                   defcpd_check(&words, wnum, maxwordnum, rv, rwords, 0)) ||
  ------------------
  |  Branch (2307:20): [True: 0, False: 0]
  ------------------
 2308|      0|                  (words &&
  ------------------
  |  Branch (2308:20): [True: 0, False: 0]
  ------------------
 2309|    123|                   defcpd_check(&words, wnum, maxwordnum, rv, rwords, 0))))))) {
  ------------------
  |  Branch (2309:20): [True: 0, False: 0]
  ------------------
 2310|    123|        rv = rv->next_homonym;
 2311|    123|      }
 2312|       |
 2313|       |
 2314|  23.4k|      if (rv)
  ------------------
  |  Branch (2314:11): [True: 0, False: 23.4k]
  ------------------
 2315|      0|        affixed = 0;
 2316|       |
 2317|  23.4k|      if (rv) {
  ------------------
  |  Branch (2317:11): [True: 0, False: 23.4k]
  ------------------
 2318|      0|        presult.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2319|      0|        presult.append(MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 2320|      0|        presult.append(st, 0, i);
 2321|      0|        if (!HENTRY_FIND(rv, MORPH_STEM)) {
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
  |  Branch (2321:13): [True: 0, False: 0]
  ------------------
 2322|      0|          presult.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2323|      0|          presult.append(MORPH_STEM);
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
 2324|      0|          presult.append(st, 0, i);
 2325|      0|        }
 2326|      0|        if (HENTRY_DATA(rv)) {
  ------------------
  |  Branch (2326:13): [True: 0, False: 0]
  ------------------
 2327|      0|          presult.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2328|      0|          presult.append(HENTRY_DATA2(rv));
 2329|      0|        }
 2330|      0|      }
 2331|       |
 2332|  23.4k|      if (!rv) {
  ------------------
  |  Branch (2332:11): [True: 23.4k, False: 0]
  ------------------
 2333|  23.4k|        if (compoundflag &&
  ------------------
  |  Branch (2333:13): [True: 23.4k, False: 0]
  ------------------
 2334|  23.4k|            !(rv =
  ------------------
  |  Branch (2334:13): [True: 23.4k, False: 0]
  ------------------
 2335|  23.4k|                  prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                                prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
  ------------------
  |  |   73|  46.8k|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2335:42): [True: 0, False: 23.4k]
  ------------------
 2336|  23.4k|                               scratch, compoundflag))) {
 2337|  23.4k|          if (((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   96|  23.4k|#define FLAG_NULL 0x00
  ------------------
                        if (((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                        if (((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   73|  46.8k|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2337:16): [True: 0, False: 23.4k]
  |  Branch (2337:91): [True: 0, False: 23.4k]
  ------------------
 2338|  23.4k|               (compoundmoresuffixes && (rv = suffix_check_twosfx(st, 0, i, 0, nullptr, scratch, compoundflag)))) &&
  ------------------
  |  Branch (2338:17): [True: 0, False: 23.4k]
  |  Branch (2338:41): [True: 0, False: 0]
  ------------------
 2339|      0|              !hu_mov_rule && sfx->getCont() &&
  ------------------
  |  Branch (2339:15): [True: 0, False: 0]
  |  Branch (2339:31): [True: 0, False: 0]
  ------------------
 2340|      0|              ((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2340:17): [True: 0, False: 0]
  ------------------
 2341|      0|               (compoundend && TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2341:17): [True: 0, False: 0]
  ------------------
 2342|      0|            rv = nullptr;
 2343|      0|          }
 2344|  23.4k|        }
 2345|       |
 2346|  23.4k|        if (rv ||
  ------------------
  |  Branch (2346:13): [True: 0, False: 23.4k]
  ------------------
 2347|  23.4k|            (((wordnum == 0) && compoundbegin &&
  ------------------
  |  Branch (2347:15): [True: 23.4k, False: 0]
  |  Branch (2347:33): [True: 0, False: 23.4k]
  ------------------
 2348|      0|              ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
                            ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                            ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2348:16): [True: 0, False: 0]
  |  Branch (2348:92): [True: 0, False: 0]
  ------------------
 2349|      0|               (compoundmoresuffixes && (rv = suffix_check_twosfx(st, 0, i, 0, nullptr, scratch,
  ------------------
  |  Branch (2349:17): [True: 0, False: 0]
  |  Branch (2349:41): [True: 0, False: 0]
  ------------------
 2350|      0|                                                                  compoundbegin))) ||  // twofold suffix+compound
 2351|      0|               (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundbegin)))) ||
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                             (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundbegin)))) ||
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2351:16): [True: 0, False: 0]
  |  Branch (2351:45): [True: 0, False: 0]
  ------------------
 2352|  23.4k|             ((wordnum > 0) && compoundmiddle &&
  ------------------
  |  Branch (2352:15): [True: 0, False: 23.4k]
  |  Branch (2352:32): [True: 0, False: 0]
  ------------------
 2353|      0|              ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
                            ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                            ((rv = suffix_check(st, 0, i, 0, nullptr, scratch, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2353:16): [True: 0, False: 0]
  |  Branch (2353:93): [True: 0, False: 0]
  ------------------
 2354|      0|               (compoundmoresuffixes && (rv = suffix_check_twosfx(st, 0, i, 0, nullptr, scratch,
  ------------------
  |  Branch (2354:17): [True: 0, False: 0]
  |  Branch (2354:41): [True: 0, False: 0]
  ------------------
 2355|      0|                                                                  compoundmiddle))) ||  // twofold suffix+compound
 2356|      0|               (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundmiddle)))))) {
  ------------------
  |  |   75|      0|#define IN_CPD_OTHER 3
  ------------------
                             (rv = prefix_check(st, 0, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, scratch, compoundmiddle)))))) {
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2356:16): [True: 0, False: 0]
  |  Branch (2356:45): [True: 0, False: 0]
  ------------------
 2357|      0|          std::string p;
 2358|      0|          if (compoundflag)
  ------------------
  |  Branch (2358:15): [True: 0, False: 0]
  ------------------
 2359|      0|            p = affix_check_morph(st, 0, i, scratch, compoundflag);
 2360|      0|          if (p.empty()) {
  ------------------
  |  Branch (2360:15): [True: 0, False: 0]
  ------------------
 2361|      0|            if ((wordnum == 0) && compoundbegin) {
  ------------------
  |  Branch (2361:17): [True: 0, False: 0]
  |  Branch (2361:35): [True: 0, False: 0]
  ------------------
 2362|      0|              p = affix_check_morph(st, 0, i, scratch, compoundbegin);
 2363|      0|            } else if ((wordnum > 0) && compoundmiddle) {
  ------------------
  |  Branch (2363:24): [True: 0, False: 0]
  |  Branch (2363:41): [True: 0, False: 0]
  ------------------
 2364|      0|              p = affix_check_morph(st, 0, i, scratch, compoundmiddle);
 2365|      0|            }
 2366|      0|          }
 2367|      0|          if (!p.empty()) {
  ------------------
  |  Branch (2367:15): [True: 0, False: 0]
  ------------------
 2368|      0|            presult.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2369|      0|            presult.append(MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 2370|      0|            presult.append(st, 0, i);
 2371|      0|            line_uniq_app(p, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2372|      0|            presult.append(p);
 2373|      0|          }
 2374|      0|          checked_prefix = 1;
 2375|      0|        }
 2376|       |        // else check forbiddenwords
 2377|  23.4k|      } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2377:18): [True: 0, False: 0]
  |  Branch (2377:18): [True: 0, False: 0]
  ------------------
 2378|      0|                              TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2379|      0|                              TESTAFF(rv->astr, needaffix, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2380|      0|        st[i] = ch;
 2381|      0|        continue;
 2382|      0|      }
 2383|       |
 2384|       |      // check non_compound flag in suffix and prefix
 2385|  23.4k|      if ((rv) && !hu_mov_rule &&
  ------------------
  |  Branch (2385:11): [True: 0, False: 23.4k]
  |  Branch (2385:19): [True: 0, False: 0]
  ------------------
 2386|      0|          ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (2386:13): [True: 0, False: 0]
  |  Branch (2386:20): [True: 0, False: 0]
  ------------------
 2387|      0|            TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2388|      0|           (sfx && sfx->getCont() &&
  ------------------
  |  Branch (2388:13): [True: 0, False: 0]
  |  Branch (2388:20): [True: 0, False: 0]
  ------------------
 2389|      0|            TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2390|      0|        continue;
 2391|      0|      }
 2392|       |
 2393|       |      // check compoundend flag in suffix and prefix
 2394|  23.4k|      if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&
  ------------------
  |  Branch (2394:11): [True: 0, False: 23.4k]
  |  Branch (2394:19): [True: 0, False: 0]
  |  Branch (2394:38): [True: 0, False: 0]
  |  Branch (2394:53): [True: 0, False: 0]
  ------------------
 2395|      0|          ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (2395:13): [True: 0, False: 0]
  |  Branch (2395:20): [True: 0, False: 0]
  ------------------
 2396|      0|            TESTAFF(pfx->getCont(), compoundend, pfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2397|      0|           (sfx && sfx->getCont() &&
  ------------------
  |  Branch (2397:13): [True: 0, False: 0]
  |  Branch (2397:20): [True: 0, False: 0]
  ------------------
 2398|      0|            TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2399|      0|        continue;
 2400|      0|      }
 2401|       |
 2402|       |      // check compoundmiddle flag in suffix and prefix
 2403|  23.4k|      if ((rv) && !checked_prefix && (wordnum == 0) && compoundmiddle &&
  ------------------
  |  Branch (2403:11): [True: 0, False: 23.4k]
  |  Branch (2403:19): [True: 0, False: 0]
  |  Branch (2403:38): [True: 0, False: 0]
  |  Branch (2403:56): [True: 0, False: 0]
  ------------------
 2404|      0|          !hu_mov_rule &&
  ------------------
  |  Branch (2404:11): [True: 0, False: 0]
  ------------------
 2405|      0|          ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (2405:13): [True: 0, False: 0]
  |  Branch (2405:20): [True: 0, False: 0]
  ------------------
 2406|      0|            TESTAFF(pfx->getCont(), compoundmiddle, pfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2407|      0|           (sfx && sfx->getCont() &&
  ------------------
  |  Branch (2407:13): [True: 0, False: 0]
  |  Branch (2407:20): [True: 0, False: 0]
  ------------------
 2408|      0|            TESTAFF(sfx->getCont(), compoundmiddle, sfx->getContLen())))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2409|      0|        rv = nullptr;
 2410|      0|      }
 2411|       |
 2412|       |      // check forbiddenwords
 2413|  23.4k|      if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2413:11): [True: 0, False: 23.4k]
  |  Branch (2413:11): [True: 0, False: 23.4k]
  |  Branch (2413:19): [True: 0, False: 0]
  ------------------
 2414|      0|                                 TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen)))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2415|      0|        continue;
 2416|       |
 2417|       |      // increment word number, if the second root has a compoundroot flag
 2418|  23.4k|      if ((rv) && (compoundroot) &&
  ------------------
  |  Branch (2418:11): [True: 0, False: 23.4k]
  |  Branch (2418:19): [True: 0, False: 0]
  ------------------
 2419|      0|          (TESTAFF(rv->astr, compoundroot, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2419:11): [True: 0, False: 0]
  ------------------
 2420|      0|        wordnum++;
 2421|      0|      }
 2422|       |
 2423|       |      // first word is acceptable in compound words?
 2424|  23.4k|      if (((rv) &&
  ------------------
  |  Branch (2424:11): [True: 0, False: 23.4k]
  |  Branch (2424:12): [True: 0, False: 23.4k]
  ------------------
 2425|      0|           (checked_prefix || (words && words[wnum]) || (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2425:13): [True: 0, False: 0]
  |  Branch (2425:32): [True: 0, False: 0]
  |  Branch (2425:41): [True: 0, False: 0]
  |  Branch (2425:58): [True: 0, False: 0]
  ------------------
 2426|      0|            ((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2426:14): [True: 0, False: 0]
  |  Branch (2426:35): [True: 0, False: 0]
  ------------------
 2427|      0|            ((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2427:14): [True: 0, False: 0]
  |  Branch (2427:34): [True: 0, False: 0]
  ------------------
 2428|       |            // LANG_hu section: spec. Hungarian rule
 2429|      0|            || ((langnum == LANG_hu) &&  // hu_mov_rule
  ------------------
  |  Branch (2429:17): [True: 0, False: 0]
  ------------------
 2430|      0|                hu_mov_rule &&
  ------------------
  |  Branch (2430:17): [True: 0, False: 0]
  ------------------
 2431|      0|                (TESTAFF(rv->astr, 'F', rv->alen) || TESTAFF(rv->astr, 'G', rv->alen) || TESTAFF(rv->astr, 'H', rv->alen)))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
                              (TESTAFF(rv->astr, 'F', rv->alen) || TESTAFF(rv->astr, 'G', rv->alen) || TESTAFF(rv->astr, 'H', rv->alen)))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
                              (TESTAFF(rv->astr, 'F', rv->alen) || TESTAFF(rv->astr, 'G', rv->alen) || TESTAFF(rv->astr, 'H', rv->alen)))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2432|       |            // END of LANG_hu section
 2433|      0|            ) &&
 2434|      0|           !((checkcompoundtriple && !words &&  // test triple letters
  ------------------
  |  Branch (2434:15): [True: 0, False: 0]
  |  Branch (2434:38): [True: 0, False: 0]
  ------------------
 2435|      0|              (word[i - 1] == word[i]) &&
  ------------------
  |  Branch (2435:15): [True: 0, False: 0]
  ------------------
 2436|      0|              (((i > 1) && (word[i - 1] == word[i - 2])) || ((word[i - 1] == word[i + 1]))  // may be word[i+1] == '\0'
  ------------------
  |  Branch (2436:17): [True: 0, False: 0]
  |  Branch (2436:28): [True: 0, False: 0]
  |  Branch (2436:61): [True: 0, False: 0]
  ------------------
 2437|      0|               )) ||
 2438|      0|             (
 2439|       |                 // test CHECKCOMPOUNDPATTERN
 2440|      0|                 !checkcpdtable.empty() && !words && cpdpat_check(word, i, rv, nullptr, affixed)) ||
  ------------------
  |  Branch (2440:18): [True: 0, False: 0]
  |  Branch (2440:44): [True: 0, False: 0]
  |  Branch (2440:54): [True: 0, False: 0]
  ------------------
 2441|      0|             (checkcompoundcase && !words && cpdcase_check(word, i))))
  ------------------
  |  Branch (2441:15): [True: 0, False: 0]
  |  Branch (2441:36): [True: 0, False: 0]
  |  Branch (2441:46): [True: 0, False: 0]
  ------------------
 2442|       |          // LANG_hu section: spec. Hungarian rule
 2443|  23.4k|          || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st, 0, i, scratch)) &&
  ------------------
  |  Branch (2443:15): [True: 23.4k, False: 0]
  |  Branch (2443:24): [True: 7.94k, False: 15.4k]
  |  Branch (2443:48): [True: 0, False: 7.94k]
  |  Branch (2443:63): [True: 0, False: 0]
  ------------------
 2444|      0|              (sfx && sfx->getCont() &&
  ------------------
  |  Branch (2444:16): [True: 0, False: 0]
  |  Branch (2444:23): [True: 0, False: 0]
  ------------------
 2445|      0|               (TESTAFF(sfx->getCont(), (unsigned short)'x', sfx->getContLen()) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2446|      0|                TESTAFF(sfx->getCont(), (unsigned short)'%', sfx->getContLen()))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2447|       |          // END of LANG_hu section
 2448|  23.4k|      ) {
 2449|       |        // LANG_hu section: spec. Hungarian rule
 2450|      0|        if (langnum == LANG_hu) {
  ------------------
  |  Branch (2450:13): [True: 0, False: 0]
  ------------------
 2451|       |          // calculate syllable number of the word
 2452|      0|          numsyllable += get_syllable(st.substr(0, i));
 2453|       |
 2454|       |          // + 1 word, if syllable number of the prefix > 1 (hungarian
 2455|       |          // convention)
 2456|      0|          if (pfx && (get_syllable(pfx->getKey()) > 1))
  ------------------
  |  Branch (2456:15): [True: 0, False: 0]
  |  Branch (2456:15): [True: 0, False: 0]
  |  Branch (2456:22): [True: 0, False: 0]
  ------------------
 2457|      0|            wordnum++;
 2458|      0|        }
 2459|       |        // END of LANG_hu section
 2460|       |
 2461|       |        // NEXT WORD(S)
 2462|      0|        rv_first = rv;
 2463|      0|        rv = lookup(word.c_str() + i, word.size() - i);  // perhaps without prefix
 2464|       |
 2465|       |        // search homonym with compound flag
 2466|      0|        while ((rv) && ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2466:16): [True: 0, False: 0]
  |  Branch (2466:26): [True: 0, False: 0]
  ------------------
 2467|      0|                        !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2467:28): [True: 0, False: 0]
  |  Branch (2467:44): [True: 0, False: 0]
  ------------------
 2468|      0|                          (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2468:28): [True: 0, False: 0]
  |  Branch (2468:43): [True: 0, False: 0]
  ------------------
 2469|      0|                          (!defcpdtable.empty() && words && defcpd_check(&words, wnum + 1, maxwordnum, rv, nullptr, 1))))) {
  ------------------
  |  Branch (2469:28): [True: 0, False: 0]
  |  Branch (2469:52): [True: 0, False: 0]
  |  Branch (2469:61): [True: 0, False: 0]
  ------------------
 2470|      0|          rv = rv->next_homonym;
 2471|      0|        }
 2472|       |
 2473|      0|        if (rv && words && words[wnum + 1]) {
  ------------------
  |  Branch (2473:13): [True: 0, False: 0]
  |  Branch (2473:19): [True: 0, False: 0]
  |  Branch (2473:28): [True: 0, False: 0]
  ------------------
 2474|      0|          result.append(presult);
 2475|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2476|      0|          result.append(MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 2477|      0|          result.append(word, i, word.size());
 2478|      0|          if (complexprefixes && HENTRY_DATA(rv))
  ------------------
  |  Branch (2478:15): [True: 0, False: 0]
  |  Branch (2478:34): [True: 0, False: 0]
  ------------------
 2479|      0|            result.append(HENTRY_DATA2(rv));
 2480|      0|          if (!HENTRY_FIND(rv, MORPH_STEM)) {
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
  |  Branch (2480:15): [True: 0, False: 0]
  ------------------
 2481|      0|            result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2482|      0|            result.append(MORPH_STEM);
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
 2483|      0|            result.append(HENTRY_WORD(rv));
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 2484|      0|          }
 2485|       |          // store the pointer of the hash entry
 2486|      0|          if (!complexprefixes && HENTRY_DATA(rv)) {
  ------------------
  |  Branch (2486:15): [True: 0, False: 0]
  |  Branch (2486:35): [True: 0, False: 0]
  ------------------
 2487|      0|            result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2488|      0|            result.append(HENTRY_DATA2(rv));
 2489|      0|          }
 2490|      0|          result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2491|      0|          return 0;
 2492|      0|        }
 2493|       |
 2494|      0|        oldnumsyllable2 = numsyllable;
 2495|      0|        oldwordnum2 = wordnum;
 2496|       |
 2497|       |        // LANG_hu section: spec. Hungarian rule
 2498|      0|        if ((rv) && (langnum == LANG_hu) &&
  ------------------
  |  Branch (2498:13): [True: 0, False: 0]
  |  Branch (2498:13): [True: 0, False: 0]
  |  Branch (2498:21): [True: 0, False: 0]
  ------------------
 2499|      0|            (TESTAFF(rv->astr, 'I', rv->alen)) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2499:13): [True: 0, False: 0]
  ------------------
 2500|      0|            !(TESTAFF(rv->astr, 'J', rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2500:13): [True: 0, False: 0]
  ------------------
 2501|      0|          numsyllable--;
 2502|      0|        }
 2503|       |        // END of LANG_hu section
 2504|       |        // increment word number, if the second root has a compoundroot flag
 2505|      0|        if ((rv) && (compoundroot) &&
  ------------------
  |  Branch (2505:13): [True: 0, False: 0]
  |  Branch (2505:21): [True: 0, False: 0]
  ------------------
 2506|      0|            (TESTAFF(rv->astr, compoundroot, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2506:13): [True: 0, False: 0]
  ------------------
 2507|      0|          wordnum++;
 2508|      0|        }
 2509|       |
 2510|       |        // check forbiddenwords
 2511|      0|        if ((rv) && (rv->astr) &&
  ------------------
  |  Branch (2511:13): [True: 0, False: 0]
  |  Branch (2511:13): [True: 0, False: 0]
  |  Branch (2511:21): [True: 0, False: 0]
  ------------------
 2512|      0|            (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2513|      0|             TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2514|      0|          st[i] = ch;
 2515|      0|          continue;
 2516|      0|        }
 2517|       |
 2518|       |        // second word is acceptable, as a root?
 2519|       |        // hungarian conventions: compounding is acceptable,
 2520|       |        // when compound forms consist of 2 words, or if more,
 2521|       |        // then the syllable number of root words must be 6, or lesser.
 2522|      0|        if ((rv) &&
  ------------------
  |  Branch (2522:13): [True: 0, False: 0]
  |  Branch (2522:13): [True: 0, False: 0]
  ------------------
 2523|      0|            ((compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2523:15): [True: 0, False: 0]
  ------------------
 2524|      0|             (compoundend && TESTAFF(rv->astr, compoundend, rv->alen))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2524:15): [True: 0, False: 0]
  ------------------
 2525|      0|            (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
  ------------------
  |  Branch (2525:15): [True: 0, False: 0]
  |  Branch (2525:37): [True: 0, False: 0]
  ------------------
 2526|      0|             ((cpdmaxsyllable != 0) &&
  ------------------
  |  Branch (2526:15): [True: 0, False: 0]
  ------------------
 2527|      0|              (numsyllable + get_syllable(std::string(HENTRY_WORD(rv), rv->blen)) <=
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
  |  Branch (2527:15): [True: 0, False: 0]
  ------------------
 2528|      0|               cpdmaxsyllable))) &&
 2529|      0|            ((!checkcompounddup || (rv != rv_first)))) {
  ------------------
  |  Branch (2529:15): [True: 0, False: 0]
  |  Branch (2529:36): [True: 0, False: 0]
  ------------------
 2530|       |          // bad compound word
 2531|      0|          result.append(presult);
 2532|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2533|      0|          result.append(MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 2534|      0|          result.append(word, i, word.size());
 2535|       |
 2536|      0|          if (HENTRY_DATA(rv)) {
  ------------------
  |  Branch (2536:15): [True: 0, False: 0]
  ------------------
 2537|      0|            if (complexprefixes)
  ------------------
  |  Branch (2537:17): [True: 0, False: 0]
  ------------------
 2538|      0|              result.append(HENTRY_DATA2(rv));
 2539|      0|            if (!HENTRY_FIND(rv, MORPH_STEM)) {
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
  |  Branch (2539:17): [True: 0, False: 0]
  ------------------
 2540|      0|              result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2541|      0|              result.append(MORPH_STEM);
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
 2542|      0|              result.append(HENTRY_WORD(rv));
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 2543|      0|            }
 2544|       |            // store the pointer of the hash entry
 2545|      0|            if (!complexprefixes) {
  ------------------
  |  Branch (2545:17): [True: 0, False: 0]
  ------------------
 2546|      0|              result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2547|      0|              result.append(HENTRY_DATA2(rv));
 2548|      0|            }
 2549|      0|          }
 2550|      0|          result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2551|      0|          ok = 1;
 2552|      0|        }
 2553|       |
 2554|      0|        numsyllable = oldnumsyllable2;
 2555|      0|        wordnum = oldwordnum2;
 2556|       |
 2557|       |        // perhaps second word has prefix or/and suffix
 2558|      0|        sfx = nullptr;
 2559|      0|        sfxflag = FLAG_NULL;
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
 2560|       |
 2561|      0|        if (compoundflag && !onlycpdrule)
  ------------------
  |  Branch (2561:13): [True: 0, False: 0]
  |  Branch (2561:29): [True: 0, False: 0]
  ------------------
 2562|      0|          rv = affix_check(word, i, word.size() - i, scratch, compoundflag);
 2563|      0|        else
 2564|      0|          rv = nullptr;
 2565|       |
 2566|      0|        if (!rv && compoundend && !onlycpdrule) {
  ------------------
  |  Branch (2566:13): [True: 0, False: 0]
  |  Branch (2566:20): [True: 0, False: 0]
  |  Branch (2566:35): [True: 0, False: 0]
  ------------------
 2567|      0|          sfx = nullptr;
 2568|      0|          pfx = nullptr;
 2569|      0|          rv = affix_check(word, i, word.size() - i, scratch, compoundend);
 2570|      0|        }
 2571|       |
 2572|      0|        if (!rv && !defcpdtable.empty() && words) {
  ------------------
  |  Branch (2572:13): [True: 0, False: 0]
  |  Branch (2572:20): [True: 0, False: 0]
  |  Branch (2572:44): [True: 0, False: 0]
  ------------------
 2573|      0|          rv = affix_check(word, i, word.size() - i, scratch, 0, IN_CPD_END);
  ------------------
  |  |   74|      0|#define IN_CPD_END 2
  ------------------
 2574|      0|          if (rv && words && defcpd_check(&words, wnum + 1, maxwordnum, rv, nullptr, 1)) {
  ------------------
  |  Branch (2574:15): [True: 0, False: 0]
  |  Branch (2574:21): [True: 0, False: 0]
  |  Branch (2574:30): [True: 0, False: 0]
  ------------------
 2575|      0|            std::string m;
 2576|      0|            if (compoundflag)
  ------------------
  |  Branch (2576:17): [True: 0, False: 0]
  ------------------
 2577|      0|              m = affix_check_morph(word, i, word.size() - i, scratch, compoundflag);
 2578|      0|            if (m.empty() && compoundend) {
  ------------------
  |  Branch (2578:17): [True: 0, False: 0]
  |  Branch (2578:30): [True: 0, False: 0]
  ------------------
 2579|      0|              m = affix_check_morph(word, i, word.size() - i, scratch, compoundend);
 2580|      0|            }
 2581|      0|            result.append(presult);
 2582|      0|            if (!m.empty()) {
  ------------------
  |  Branch (2582:17): [True: 0, False: 0]
  ------------------
 2583|      0|              result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2584|      0|              result.append(MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 2585|      0|              result.append(word, i, word.size());
 2586|      0|              line_uniq_app(m, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2587|      0|              result.append(m);
 2588|      0|            }
 2589|      0|            result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2590|      0|            ok = 1;
 2591|      0|          }
 2592|      0|        }
 2593|       |
 2594|       |        // check non_compound flag in suffix and prefix
 2595|      0|        if ((rv) &&
  ------------------
  |  Branch (2595:13): [True: 0, False: 0]
  ------------------
 2596|      0|            ((pfx && pfx->getCont() &&
  ------------------
  |  Branch (2596:15): [True: 0, False: 0]
  |  Branch (2596:22): [True: 0, False: 0]
  ------------------
 2597|      0|              TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2598|      0|             (sfx && sfx->getCont() &&
  ------------------
  |  Branch (2598:15): [True: 0, False: 0]
  |  Branch (2598:22): [True: 0, False: 0]
  ------------------
 2599|      0|              TESTAFF(sfx->getCont(), compoundforbidflag,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2600|      0|                      sfx->getContLen())))) {
 2601|      0|          rv = nullptr;
 2602|      0|        }
 2603|       |
 2604|       |        // check forbiddenwords
 2605|      0|        if ((rv) && (rv->astr) &&
  ------------------
  |  Branch (2605:13): [True: 0, False: 0]
  |  Branch (2605:13): [True: 0, False: 0]
  |  Branch (2605:21): [True: 0, False: 0]
  ------------------
 2606|      0|            (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2607|      0|             TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen)) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2608|      0|            (!TESTAFF(rv->astr, needaffix, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2608:13): [True: 0, False: 0]
  ------------------
 2609|      0|          st[i] = ch;
 2610|      0|          continue;
 2611|      0|        }
 2612|       |
 2613|      0|        if (langnum == LANG_hu) {
  ------------------
  |  Branch (2613:13): [True: 0, False: 0]
  ------------------
 2614|       |          // calculate syllable number of the word
 2615|      0|          numsyllable += get_syllable(word.c_str() + i);
 2616|       |
 2617|       |          // - affix syllable num.
 2618|       |          // XXX only second suffix (inflections, not derivations)
 2619|      0|          if (sfxappnd) {
  ------------------
  |  Branch (2619:15): [True: 0, False: 0]
  ------------------
 2620|      0|            std::string tmp(sfxappnd);
 2621|      0|            reverseword(tmp);
 2622|      0|            numsyllable -= short(get_syllable(tmp) + sfxextra);
 2623|      0|          } else {
 2624|      0|            numsyllable -= short(sfxextra);
 2625|      0|          }
 2626|       |
 2627|       |          // + 1 word, if syllable number of the prefix > 1 (hungarian
 2628|       |          // convention)
 2629|      0|          if (pfx && (get_syllable(pfx->getKey()) > 1))
  ------------------
  |  Branch (2629:15): [True: 0, False: 0]
  |  Branch (2629:15): [True: 0, False: 0]
  |  Branch (2629:22): [True: 0, False: 0]
  ------------------
 2630|      0|            wordnum++;
 2631|       |
 2632|       |          // increment syllable num, if last word has a SYLLABLENUM flag
 2633|       |          // and the suffix is beginning `s'
 2634|       |
 2635|      0|          if (!cpdsyllablenum.empty()) {
  ------------------
  |  Branch (2635:15): [True: 0, False: 0]
  ------------------
 2636|      0|            switch (sfxflag) {
  ------------------
  |  Branch (2636:21): [True: 0, False: 0]
  ------------------
 2637|      0|              case 'c': {
  ------------------
  |  Branch (2637:15): [True: 0, False: 0]
  ------------------
 2638|      0|                numsyllable += 2;
 2639|      0|                break;
 2640|      0|              }
 2641|      0|              case 'J': {
  ------------------
  |  Branch (2641:15): [True: 0, False: 0]
  ------------------
 2642|      0|                numsyllable += 1;
 2643|      0|                break;
 2644|      0|              }
 2645|      0|              case 'I': {
  ------------------
  |  Branch (2645:15): [True: 0, False: 0]
  ------------------
 2646|      0|                if (rv && TESTAFF(rv->astr, 'J', rv->alen))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2646:21): [True: 0, False: 0]
  |  Branch (2646:21): [True: 0, False: 0]
  ------------------
 2647|      0|                  numsyllable += 1;
 2648|      0|                break;
 2649|      0|              }
 2650|      0|            }
 2651|      0|          }
 2652|      0|        }
 2653|       |
 2654|       |        // increment word number, if the second word has a compoundroot flag
 2655|      0|        if ((rv) && (compoundroot) &&
  ------------------
  |  Branch (2655:13): [True: 0, False: 0]
  |  Branch (2655:21): [True: 0, False: 0]
  ------------------
 2656|      0|            (TESTAFF(rv->astr, compoundroot, rv->alen))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2656:13): [True: 0, False: 0]
  ------------------
 2657|      0|          wordnum++;
 2658|      0|        }
 2659|       |        // second word is acceptable, as a word with prefix or/and suffix?
 2660|       |        // hungarian conventions: compounding is acceptable,
 2661|       |        // when compound forms consist 2 word, otherwise
 2662|       |        // the syllable number of root words is 6, or lesser.
 2663|      0|        if ((rv) &&
  ------------------
  |  Branch (2663:13): [True: 0, False: 0]
  ------------------
 2664|      0|            (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
  ------------------
  |  Branch (2664:15): [True: 0, False: 0]
  |  Branch (2664:37): [True: 0, False: 0]
  ------------------
 2665|      0|             ((cpdmaxsyllable != 0) && (numsyllable <= cpdmaxsyllable))) &&
  ------------------
  |  Branch (2665:15): [True: 0, False: 0]
  |  Branch (2665:40): [True: 0, False: 0]
  ------------------
 2666|      0|            ((!checkcompounddup || (rv != rv_first)))) {
  ------------------
  |  Branch (2666:15): [True: 0, False: 0]
  |  Branch (2666:36): [True: 0, False: 0]
  ------------------
 2667|      0|          std::string m;
 2668|      0|          if (compoundflag)
  ------------------
  |  Branch (2668:15): [True: 0, False: 0]
  ------------------
 2669|      0|            m = affix_check_morph(word, i, word.size() - i, scratch, compoundflag);
 2670|      0|          if (m.empty() && compoundend) {
  ------------------
  |  Branch (2670:15): [True: 0, False: 0]
  |  Branch (2670:28): [True: 0, False: 0]
  ------------------
 2671|      0|            m = affix_check_morph(word, i, word.size() - i, scratch, compoundend);
 2672|      0|          }
 2673|      0|          result.append(presult);
 2674|      0|          if (!m.empty()) {
  ------------------
  |  Branch (2674:15): [True: 0, False: 0]
  ------------------
 2675|      0|            result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2676|      0|            result.append(MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 2677|      0|            result.append(word, i, word.size());
 2678|      0|            line_uniq_app(m, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2679|      0|            result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2680|      0|            result.append(m);
 2681|      0|          }
 2682|      0|          result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2683|      0|          ok = 1;
 2684|      0|        }
 2685|       |
 2686|      0|        numsyllable = oldnumsyllable2;
 2687|      0|        wordnum = oldwordnum2;
 2688|       |
 2689|       |        // perhaps second word is a compound word (recursive call)
 2690|      0|        if ((wordnum + 2 < maxwordnum) && (wnum + 1 < maxwordnum) && (ok == 0)) {
  ------------------
  |  Branch (2690:13): [True: 0, False: 0]
  |  Branch (2690:43): [True: 0, False: 0]
  |  Branch (2690:70): [True: 0, False: 0]
  ------------------
 2691|      0|          compound_check_morph(word.substr(i), wordnum + 1,
 2692|      0|                               numsyllable, maxwordnum, wnum + 1, words, rwords, 0,
 2693|      0|                               result, &presult, scratch);
 2694|      0|        } else {
 2695|      0|          rv = nullptr;
 2696|      0|        }
 2697|      0|      }
 2698|  23.4k|      st[i] = ch;
 2699|  23.4k|      wordnum = oldwordnum;
 2700|  23.4k|      numsyllable = oldnumsyllable;
 2701|       |
 2702|  23.4k|    } while (!defcpdtable.empty() && oldwordnum == 0 &&
  ------------------
  |  Branch (2702:14): [True: 0, False: 23.4k]
  |  Branch (2702:38): [True: 0, False: 0]
  ------------------
 2703|      0|             onlycpdrule++ < 1);  // end of onlycpd loop
  ------------------
  |  Branch (2703:14): [True: 0, False: 0]
  ------------------
 2704|  23.5k|  }
 2705|  1.58k|  return 0;
 2706|  1.75k|}
_ZN8AffixMgr12suffix_checkERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiiP8PfxEntryR12AffixScratchttc:
 2729|   505M|                                      char in_compound) {
 2730|   505M|  struct hentry* rv = nullptr;
 2731|   505M|  PfxEntry* ep = ppfx;
 2732|       |
 2733|       |  // first handle the special case of 0 length suffixes
 2734|   505M|  SfxEntry* se = sStart[0];
 2735|       |
 2736|   505M|  while (se) {
  ------------------
  |  Branch (2736:10): [True: 0, False: 505M]
  ------------------
 2737|      0|    if (!cclass || se->getCont()) {
  ------------------
  |  Branch (2737:9): [True: 0, False: 0]
  |  Branch (2737:20): [True: 0, False: 0]
  ------------------
 2738|       |      // suffixes are not allowed in beginning of compounds
 2739|      0|      if ((((in_compound != IN_CPD_BEGIN)) ||  // && !cclass
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2739:12): [True: 0, False: 0]
  ------------------
 2740|       |           // except when signed with compoundpermitflag flag
 2741|      0|           (se->getCont() && compoundpermitflag &&
  ------------------
  |  Branch (2741:13): [True: 0, False: 0]
  |  Branch (2741:30): [True: 0, False: 0]
  ------------------
 2742|      0|            TESTAFF(se->getCont(), compoundpermitflag, se->getContLen()))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2743|      0|          (!circumfix ||
  ------------------
  |  Branch (2743:12): [True: 0, False: 0]
  ------------------
 2744|       |           // no circumfix flag in prefix and suffix
 2745|      0|           ((!ppfx || !(ep->getCont()) ||
  ------------------
  |  Branch (2745:14): [True: 0, False: 0]
  |  Branch (2745:23): [True: 0, False: 0]
  ------------------
 2746|      0|             !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2746:14): [True: 0, False: 0]
  ------------------
 2747|      0|            (!se->getCont() ||
  ------------------
  |  Branch (2747:14): [True: 0, False: 0]
  ------------------
 2748|      0|             !(TESTAFF(se->getCont(), circumfix, se->getContLen())))) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2748:14): [True: 0, False: 0]
  ------------------
 2749|       |           // circumfix flag in prefix AND suffix
 2750|      0|           ((ppfx && (ep->getCont()) &&
  ------------------
  |  Branch (2750:14): [True: 0, False: 0]
  |  Branch (2750:22): [True: 0, False: 0]
  ------------------
 2751|      0|             TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2752|      0|            (se->getCont() &&
  ------------------
  |  Branch (2752:14): [True: 0, False: 0]
  ------------------
 2753|      0|             (TESTAFF(se->getCont(), circumfix, se->getContLen()))))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2753:14): [True: 0, False: 0]
  ------------------
 2754|       |          // fogemorpheme
 2755|      0|          (in_compound ||
  ------------------
  |  Branch (2755:12): [True: 0, False: 0]
  ------------------
 2756|      0|           !(se->getCont() &&
  ------------------
  |  Branch (2756:14): [True: 0, False: 0]
  ------------------
 2757|      0|             (TESTAFF(se->getCont(), onlyincompound, se->getContLen())))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2757:14): [True: 0, False: 0]
  ------------------
 2758|       |          // needaffix on prefix or first suffix
 2759|      0|          (cclass ||
  ------------------
  |  Branch (2759:12): [True: 0, False: 0]
  ------------------
 2760|      0|           !(se->getCont() &&
  ------------------
  |  Branch (2760:14): [True: 0, False: 0]
  ------------------
 2761|      0|             TESTAFF(se->getCont(), needaffix, se->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2762|      0|           (ppfx &&
  ------------------
  |  Branch (2762:13): [True: 0, False: 0]
  ------------------
 2763|      0|            !((ep->getCont()) &&
  ------------------
  |  Branch (2763:15): [True: 0, False: 0]
  ------------------
 2764|      0|              TESTAFF(ep->getCont(), needaffix, ep->getContLen()))))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2765|      0|        rv = se->checkword(word, start, len, sfxopts, ppfx,
 2766|      0|                           (FLAG)cclass, needflag,
 2767|      0|                           (in_compound ? 0 : onlyincompound),
  ------------------
  |  Branch (2767:29): [True: 0, False: 0]
  ------------------
 2768|      0|                           scratch);
 2769|      0|        if (rv) {
  ------------------
  |  Branch (2769:13): [True: 0, False: 0]
  ------------------
 2770|      0|          sfx = se;  // BUG: sfx not stateless
 2771|      0|          return rv;
 2772|      0|        }
 2773|      0|      }
 2774|      0|    }
 2775|      0|    se = se->getNext();
 2776|      0|  }
 2777|       |
 2778|       |  // now handle the general case
 2779|   505M|  if (len == 0)
  ------------------
  |  Branch (2779:7): [True: 54.3k, False: 505M]
  ------------------
 2780|  54.3k|    return nullptr;  // FULLSTRIP
 2781|   505M|  unsigned char sp = word[start + len - 1];
 2782|   505M|  SfxEntry* sptr = sStart[sp];
 2783|       |
 2784|   506M|  while (sptr) {
  ------------------
  |  Branch (2784:10): [True: 318k, False: 505M]
  ------------------
 2785|   318k|    if (isRevSubset(sptr->getKey(), word.c_str() + start + len - 1, len)) {
  ------------------
  |  Branch (2785:9): [True: 289k, False: 29.5k]
  ------------------
 2786|       |      // suffixes are not allowed in beginning of compounds
 2787|   289k|      if ((((in_compound != IN_CPD_BEGIN)) ||  // && !cclass
  ------------------
  |  |   73|   289k|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2787:12): [True: 64.9k, False: 224k]
  ------------------
 2788|       |           // except when signed with compoundpermitflag flag
 2789|   224k|           (sptr->getCont() && compoundpermitflag &&
  ------------------
  |  Branch (2789:13): [True: 224k, False: 0]
  |  Branch (2789:32): [True: 0, False: 224k]
  ------------------
 2790|      0|            TESTAFF(sptr->getCont(), compoundpermitflag,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2791|   224k|                    sptr->getContLen()))) &&
 2792|  64.9k|          (!circumfix ||
  ------------------
  |  Branch (2792:12): [True: 64.9k, False: 0]
  ------------------
 2793|       |           // no circumfix flag in prefix and suffix
 2794|      0|           ((!ppfx || !(ep->getCont()) ||
  ------------------
  |  Branch (2794:14): [True: 0, False: 0]
  |  Branch (2794:23): [True: 0, False: 0]
  ------------------
 2795|      0|             !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2795:14): [True: 0, False: 0]
  ------------------
 2796|      0|            (!sptr->getCont() ||
  ------------------
  |  Branch (2796:14): [True: 0, False: 0]
  ------------------
 2797|      0|             !(TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())))) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2797:14): [True: 0, False: 0]
  ------------------
 2798|       |           // circumfix flag in prefix AND suffix
 2799|      0|           ((ppfx && (ep->getCont()) &&
  ------------------
  |  Branch (2799:14): [True: 0, False: 0]
  |  Branch (2799:22): [True: 0, False: 0]
  ------------------
 2800|      0|             TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2801|      0|            (sptr->getCont() &&
  ------------------
  |  Branch (2801:14): [True: 0, False: 0]
  ------------------
 2802|      0|             (TESTAFF(sptr->getCont(), circumfix, sptr->getContLen()))))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2802:14): [True: 0, False: 0]
  ------------------
 2803|       |          // fogemorpheme
 2804|  64.9k|          (in_compound ||
  ------------------
  |  Branch (2804:12): [True: 0, False: 64.9k]
  ------------------
 2805|  64.9k|           !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound,
  ------------------
  |  |   99|  19.7k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2805:15): [True: 19.7k, False: 45.1k]
  |  Branch (2805:34): [True: 0, False: 19.7k]
  ------------------
 2806|  19.7k|                                          sptr->getContLen()))))) &&
 2807|       |          // needaffix on prefix or first suffix
 2808|  64.9k|          (cclass ||
  ------------------
  |  Branch (2808:12): [True: 2.76k, False: 62.1k]
  ------------------
 2809|  62.1k|           !(sptr->getCont() &&
  ------------------
  |  Branch (2809:14): [True: 19.7k, False: 42.3k]
  ------------------
 2810|  19.7k|             TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())) ||
  ------------------
  |  |   99|  19.7k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 19.7k]
  |  |  ------------------
  ------------------
 2811|      0|           (ppfx &&
  ------------------
  |  Branch (2811:13): [True: 0, False: 0]
  ------------------
 2812|      0|            !((ep->getCont()) &&
  ------------------
  |  Branch (2812:15): [True: 0, False: 0]
  ------------------
 2813|      0|              TESTAFF(ep->getCont(), needaffix, ep->getContLen())))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2814|  64.9k|        if (in_compound != IN_CPD_END || ppfx ||
  ------------------
  |  |   74|   129k|#define IN_CPD_END 2
  ------------------
  |  Branch (2814:13): [True: 64.9k, False: 0]
  |  Branch (2814:42): [True: 0, False: 0]
  ------------------
 2815|      0|            !(sptr->getCont() &&
  ------------------
  |  Branch (2815:15): [True: 0, False: 0]
  ------------------
 2816|  64.9k|              TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2817|  64.9k|          rv = sptr->checkword(word, start, len, sfxopts, ppfx,
 2818|  64.9k|                               cclass, needflag,
 2819|  64.9k|                               (in_compound ? 0 : onlyincompound),
  ------------------
  |  Branch (2819:33): [True: 0, False: 64.9k]
  ------------------
 2820|  64.9k|                               scratch);
 2821|  64.9k|          if (rv) {
  ------------------
  |  Branch (2821:15): [True: 4, False: 64.8k]
  ------------------
 2822|      4|            sfx = sptr;                 // BUG: sfx not stateless
 2823|      4|            sfxflag = sptr->getFlag();  // BUG: sfxflag not stateless
 2824|      4|            if (!sptr->getCont())
  ------------------
  |  Branch (2824:17): [True: 2, False: 2]
  ------------------
 2825|      2|              sfxappnd = sptr->getKey();  // BUG: sfxappnd not stateless
 2826|       |            // LANG_hu section: spec. Hungarian rule
 2827|      2|            else if (langnum == LANG_hu && sptr->getKeyLen() &&
  ------------------
  |  Branch (2827:22): [True: 0, False: 2]
  |  Branch (2827:44): [True: 0, False: 0]
  ------------------
 2828|      0|                     sptr->getKey()[0] == 'i' && sptr->getKey()[1] != 'y' &&
  ------------------
  |  Branch (2828:22): [True: 0, False: 0]
  |  Branch (2828:50): [True: 0, False: 0]
  ------------------
 2829|      0|                     sptr->getKey()[1] != 't') {
  ------------------
  |  Branch (2829:22): [True: 0, False: 0]
  ------------------
 2830|      0|              sfxextra = 1;
 2831|      0|            }
 2832|       |            // END of LANG_hu section
 2833|      4|            return rv;
 2834|      4|          }
 2835|  64.9k|        }
 2836|   289k|      sptr = sptr->getNextEQ();
 2837|   289k|    } else {
 2838|  29.5k|      sptr = sptr->getNextNE();
 2839|  29.5k|    }
 2840|   318k|  }
 2841|       |
 2842|   505M|  return nullptr;
 2843|   505M|}
_ZN8AffixMgr19suffix_check_twosfxERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiiP8PfxEntryR12AffixScratcht:
 2852|  13.4M|                                             const FLAG needflag) {
 2853|  13.4M|  struct hentry* rv = nullptr;
 2854|       |
 2855|       |  // first handle the special case of 0 length suffixes
 2856|  13.4M|  SfxEntry* se = sStart[0];
 2857|  13.4M|  while (se) {
  ------------------
  |  Branch (2857:10): [True: 0, False: 13.4M]
  ------------------
 2858|      0|    if (contclasses[se->getFlag()]) {
  ------------------
  |  Branch (2858:9): [True: 0, False: 0]
  ------------------
 2859|      0|      rv = se->check_twosfx(word, start, len, sfxopts, ppfx, needflag, scratch);
 2860|      0|      if (rv)
  ------------------
  |  Branch (2860:11): [True: 0, False: 0]
  ------------------
 2861|      0|        return rv;
 2862|      0|    }
 2863|      0|    se = se->getNext();
 2864|      0|  }
 2865|       |
 2866|       |  // now handle the general case
 2867|  13.4M|  if (len == 0)
  ------------------
  |  Branch (2867:7): [True: 17.0k, False: 13.4M]
  ------------------
 2868|  17.0k|    return nullptr;  // FULLSTRIP
 2869|  13.4M|  unsigned char sp = word[start + len - 1];
 2870|  13.4M|  SfxEntry* sptr = sStart[sp];
 2871|       |
 2872|  13.5M|  while (sptr) {
  ------------------
  |  Branch (2872:10): [True: 78.9k, False: 13.4M]
  ------------------
 2873|  78.9k|    if (isRevSubset(sptr->getKey(), word.c_str() + start + len - 1, len)) {
  ------------------
  |  Branch (2873:9): [True: 56.4k, False: 22.5k]
  ------------------
 2874|  56.4k|      if (contclasses[sptr->getFlag()]) {
  ------------------
  |  Branch (2874:11): [True: 36.6k, False: 19.7k]
  ------------------
 2875|  36.6k|        rv = sptr->check_twosfx(word, start, len, sfxopts, ppfx, needflag, scratch);
 2876|  36.6k|        if (rv) {
  ------------------
  |  Branch (2876:13): [True: 0, False: 36.6k]
  ------------------
 2877|      0|          sfxflag = sptr->getFlag();  // BUG: sfxflag not stateless
 2878|      0|          if (!sptr->getCont())
  ------------------
  |  Branch (2878:15): [True: 0, False: 0]
  ------------------
 2879|      0|            sfxappnd = sptr->getKey();  // BUG: sfxappnd not stateless
 2880|      0|          return rv;
 2881|      0|        }
 2882|  36.6k|      }
 2883|  56.4k|      sptr = sptr->getNextEQ();
 2884|  56.4k|    } else {
 2885|  22.5k|      sptr = sptr->getNextNE();
 2886|  22.5k|    }
 2887|  78.9k|  }
 2888|       |
 2889|  13.4M|  return nullptr;
 2890|  13.4M|}
_ZN8AffixMgr25suffix_check_twosfx_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiiP8PfxEntryR12AffixScratcht:
 2899|  3.33k|                                                const FLAG needflag) {
 2900|  3.33k|  std::string result;
 2901|  3.33k|  std::string result2;
 2902|  3.33k|  std::string result3;
 2903|       |
 2904|       |  // first handle the special case of 0 length suffixes
 2905|  3.33k|  SfxEntry* se = sStart[0];
 2906|  3.33k|  while (se) {
  ------------------
  |  Branch (2906:10): [True: 0, False: 3.33k]
  ------------------
 2907|      0|    if (contclasses[se->getFlag()]) {
  ------------------
  |  Branch (2907:9): [True: 0, False: 0]
  ------------------
 2908|      0|      std::string st = se->check_twosfx_morph(word, start, len, sfxopts, ppfx, needflag, scratch);
 2909|      0|      if (!st.empty()) {
  ------------------
  |  Branch (2909:11): [True: 0, False: 0]
  ------------------
 2910|      0|        if (ppfx) {
  ------------------
  |  Branch (2910:13): [True: 0, False: 0]
  ------------------
 2911|      0|          if (ppfx->getMorph()) {
  ------------------
  |  Branch (2911:15): [True: 0, False: 0]
  ------------------
 2912|      0|            result.append(ppfx->getMorph());
 2913|      0|            result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2914|      0|          } else
 2915|      0|            debugflag(result, ppfx->getFlag());
 2916|      0|        }
 2917|      0|        result.append(st);
 2918|      0|        if (se->getMorph()) {
  ------------------
  |  Branch (2918:13): [True: 0, False: 0]
  ------------------
 2919|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2920|      0|          result.append(se->getMorph());
 2921|      0|        } else
 2922|      0|          debugflag(result, se->getFlag());
 2923|      0|        result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2924|      0|      }
 2925|      0|    }
 2926|      0|    se = se->getNext();
 2927|      0|  }
 2928|       |
 2929|       |  // now handle the general case
 2930|  3.33k|  if (len == 0)
  ------------------
  |  Branch (2930:7): [True: 0, False: 3.33k]
  ------------------
 2931|      0|    return { };  // FULLSTRIP
 2932|  3.33k|  unsigned char sp = word[start + len - 1];
 2933|  3.33k|  SfxEntry* sptr = sStart[sp];
 2934|       |
 2935|  3.34k|  while (sptr) {
  ------------------
  |  Branch (2935:10): [True: 4, False: 3.33k]
  ------------------
 2936|      4|    if (isRevSubset(sptr->getKey(), word.c_str() + start + len - 1, len)) {
  ------------------
  |  Branch (2936:9): [True: 0, False: 4]
  ------------------
 2937|      0|      if (contclasses[sptr->getFlag()]) {
  ------------------
  |  Branch (2937:11): [True: 0, False: 0]
  ------------------
 2938|      0|        std::string st = sptr->check_twosfx_morph(word, start, len, sfxopts, ppfx, needflag, scratch);
 2939|      0|        if (!st.empty()) {
  ------------------
  |  Branch (2939:13): [True: 0, False: 0]
  ------------------
 2940|      0|          sfxflag = sptr->getFlag();  // BUG: sfxflag not stateless
 2941|      0|          if (!sptr->getCont())
  ------------------
  |  Branch (2941:15): [True: 0, False: 0]
  ------------------
 2942|      0|            sfxappnd = sptr->getKey();  // BUG: sfxappnd not stateless
 2943|      0|          result2.assign(st);
 2944|       |
 2945|      0|          result3.clear();
 2946|       |
 2947|      0|          if (sptr->getMorph()) {
  ------------------
  |  Branch (2947:15): [True: 0, False: 0]
  ------------------
 2948|      0|            result3.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 2949|      0|            result3.append(sptr->getMorph());
 2950|      0|          } else
 2951|      0|            debugflag(result3, sptr->getFlag());
 2952|      0|          strlinecat(result2, result3);
 2953|      0|          result2.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2954|      0|          result.append(result2);
 2955|      0|        }
 2956|      0|      }
 2957|      0|      sptr = sptr->getNextEQ();
 2958|      4|    } else {
 2959|      4|      sptr = sptr->getNextNE();
 2960|      4|    }
 2961|      4|  }
 2962|       |
 2963|  3.33k|  return result;
 2964|  3.33k|}
_ZN8AffixMgr18suffix_check_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiiP8PfxEntryR12AffixScratchttc:
 2974|  10.6k|                                         char in_compound) {
 2975|  10.6k|  std::string result;
 2976|       |
 2977|  10.6k|  struct hentry* rv = nullptr;
 2978|       |
 2979|  10.6k|  PfxEntry* ep = ppfx;
 2980|       |
 2981|       |  // first handle the special case of 0 length suffixes
 2982|  10.6k|  SfxEntry* se = sStart[0];
 2983|  10.6k|  while (se) {
  ------------------
  |  Branch (2983:10): [True: 0, False: 10.6k]
  ------------------
 2984|      0|    if (!cclass || se->getCont()) {
  ------------------
  |  Branch (2984:9): [True: 0, False: 0]
  |  Branch (2984:20): [True: 0, False: 0]
  ------------------
 2985|       |      // suffixes are not allowed in beginning of compounds
 2986|      0|      if (((((in_compound != IN_CPD_BEGIN)) ||  // && !cclass
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (2986:13): [True: 0, False: 0]
  ------------------
 2987|       |            // except when signed with compoundpermitflag flag
 2988|      0|            (se->getCont() && compoundpermitflag &&
  ------------------
  |  Branch (2988:14): [True: 0, False: 0]
  |  Branch (2988:31): [True: 0, False: 0]
  ------------------
 2989|      0|             TESTAFF(se->getCont(), compoundpermitflag, se->getContLen()))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2990|      0|           (!circumfix ||
  ------------------
  |  Branch (2990:13): [True: 0, False: 0]
  ------------------
 2991|       |            // no circumfix flag in prefix and suffix
 2992|      0|            ((!ppfx || !(ep->getCont()) ||
  ------------------
  |  Branch (2992:15): [True: 0, False: 0]
  |  Branch (2992:24): [True: 0, False: 0]
  ------------------
 2993|      0|              !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2993:15): [True: 0, False: 0]
  ------------------
 2994|      0|             (!se->getCont() ||
  ------------------
  |  Branch (2994:15): [True: 0, False: 0]
  ------------------
 2995|      0|              !(TESTAFF(se->getCont(), circumfix, se->getContLen())))) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (2995:15): [True: 0, False: 0]
  ------------------
 2996|       |            // circumfix flag in prefix AND suffix
 2997|      0|            ((ppfx && (ep->getCont()) &&
  ------------------
  |  Branch (2997:15): [True: 0, False: 0]
  |  Branch (2997:23): [True: 0, False: 0]
  ------------------
 2998|      0|              TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2999|      0|             (se->getCont() &&
  ------------------
  |  Branch (2999:15): [True: 0, False: 0]
  ------------------
 3000|      0|              (TESTAFF(se->getCont(), circumfix, se->getContLen()))))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (3000:15): [True: 0, False: 0]
  ------------------
 3001|       |           // fogemorpheme
 3002|      0|           (in_compound ||
  ------------------
  |  Branch (3002:13): [True: 0, False: 0]
  ------------------
 3003|      0|            !((se->getCont() &&
  ------------------
  |  Branch (3003:16): [True: 0, False: 0]
  ------------------
 3004|      0|               (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (3004:16): [True: 0, False: 0]
  ------------------
 3005|       |           // needaffix on prefix or first suffix
 3006|      0|           (cclass ||
  ------------------
  |  Branch (3006:13): [True: 0, False: 0]
  ------------------
 3007|      0|            !(se->getCont() &&
  ------------------
  |  Branch (3007:15): [True: 0, False: 0]
  ------------------
 3008|      0|              TESTAFF(se->getCont(), needaffix, se->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3009|      0|            (ppfx &&
  ------------------
  |  Branch (3009:14): [True: 0, False: 0]
  ------------------
 3010|      0|             !((ep->getCont()) &&
  ------------------
  |  Branch (3010:16): [True: 0, False: 0]
  ------------------
 3011|      0|               TESTAFF(ep->getCont(), needaffix, ep->getContLen()))))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3012|      0|        rv = se->checkword(word, start, len, sfxopts, ppfx, cclass,
 3013|      0|                           needflag, FLAG_NULL, scratch);
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
 3014|      0|      while (rv) {
  ------------------
  |  Branch (3014:14): [True: 0, False: 0]
  ------------------
 3015|      0|        if (ppfx) {
  ------------------
  |  Branch (3015:13): [True: 0, False: 0]
  ------------------
 3016|      0|          if (ppfx->getMorph()) {
  ------------------
  |  Branch (3016:15): [True: 0, False: 0]
  ------------------
 3017|      0|            result.append(ppfx->getMorph());
 3018|      0|            result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3019|      0|          } else
 3020|      0|            debugflag(result, ppfx->getFlag());
 3021|      0|        }
 3022|      0|        if (complexprefixes && HENTRY_DATA(rv))
  ------------------
  |  Branch (3022:13): [True: 0, False: 0]
  |  Branch (3022:32): [True: 0, False: 0]
  ------------------
 3023|      0|          result.append(HENTRY_DATA2(rv));
 3024|      0|        if (!HENTRY_FIND(rv, MORPH_STEM)) {
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
  |  Branch (3024:13): [True: 0, False: 0]
  ------------------
 3025|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3026|      0|          result.append(MORPH_STEM);
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
 3027|      0|          result.append(HENTRY_WORD(rv));
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 3028|      0|        }
 3029|       |
 3030|      0|        if (!complexprefixes && HENTRY_DATA(rv)) {
  ------------------
  |  Branch (3030:13): [True: 0, False: 0]
  |  Branch (3030:33): [True: 0, False: 0]
  ------------------
 3031|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3032|      0|          result.append(HENTRY_DATA2(rv));
 3033|      0|        }
 3034|      0|        if (se->getMorph()) {
  ------------------
  |  Branch (3034:13): [True: 0, False: 0]
  ------------------
 3035|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3036|      0|          result.append(se->getMorph());
 3037|      0|        } else
 3038|      0|          debugflag(result, se->getFlag());
 3039|      0|        result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 3040|      0|        rv = se->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag);
 3041|      0|      }
 3042|      0|    }
 3043|      0|    se = se->getNext();
 3044|      0|  }
 3045|       |
 3046|       |  // now handle the general case
 3047|  10.6k|  if (len == 0)
  ------------------
  |  Branch (3047:7): [True: 0, False: 10.6k]
  ------------------
 3048|      0|    return { };  // FULLSTRIP
 3049|  10.6k|  unsigned char sp = word[start + len - 1];
 3050|  10.6k|  SfxEntry* sptr = sStart[sp];
 3051|       |
 3052|  10.7k|  while (sptr) {
  ------------------
  |  Branch (3052:10): [True: 4, False: 10.6k]
  ------------------
 3053|      4|    if (isRevSubset(sptr->getKey(), word.c_str() + start + len - 1, len)) {
  ------------------
  |  Branch (3053:9): [True: 0, False: 4]
  ------------------
 3054|       |      // suffixes are not allowed in beginning of compounds
 3055|      0|      if (((((in_compound != IN_CPD_BEGIN)) ||  // && !cclass
  ------------------
  |  |   73|      0|#define IN_CPD_BEGIN 1
  ------------------
  |  Branch (3055:13): [True: 0, False: 0]
  ------------------
 3056|       |            // except when signed with compoundpermitflag flag
 3057|      0|            (sptr->getCont() && compoundpermitflag &&
  ------------------
  |  Branch (3057:14): [True: 0, False: 0]
  |  Branch (3057:33): [True: 0, False: 0]
  ------------------
 3058|      0|             TESTAFF(sptr->getCont(), compoundpermitflag,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3059|      0|                     sptr->getContLen()))) &&
 3060|      0|           (!circumfix ||
  ------------------
  |  Branch (3060:13): [True: 0, False: 0]
  ------------------
 3061|       |            // no circumfix flag in prefix and suffix
 3062|      0|            ((!ppfx || !(ep->getCont()) ||
  ------------------
  |  Branch (3062:15): [True: 0, False: 0]
  |  Branch (3062:24): [True: 0, False: 0]
  ------------------
 3063|      0|              !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (3063:15): [True: 0, False: 0]
  ------------------
 3064|      0|             (!sptr->getCont() ||
  ------------------
  |  Branch (3064:15): [True: 0, False: 0]
  ------------------
 3065|      0|              !(TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())))) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (3065:15): [True: 0, False: 0]
  ------------------
 3066|       |            // circumfix flag in prefix AND suffix
 3067|      0|            ((ppfx && (ep->getCont()) &&
  ------------------
  |  Branch (3067:15): [True: 0, False: 0]
  |  Branch (3067:23): [True: 0, False: 0]
  ------------------
 3068|      0|              TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3069|      0|             (sptr->getCont() &&
  ------------------
  |  Branch (3069:15): [True: 0, False: 0]
  ------------------
 3070|      0|              (TESTAFF(sptr->getCont(), circumfix, sptr->getContLen()))))) &&
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (3070:15): [True: 0, False: 0]
  ------------------
 3071|       |           // fogemorpheme
 3072|      0|           (in_compound ||
  ------------------
  |  Branch (3072:13): [True: 0, False: 0]
  ------------------
 3073|      0|            !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound,
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  ------------------
  |  Branch (3073:16): [True: 0, False: 0]
  |  Branch (3073:35): [True: 0, False: 0]
  ------------------
 3074|      0|                                           sptr->getContLen()))))) &&
 3075|       |           // needaffix on first suffix
 3076|      0|           (cclass ||
  ------------------
  |  Branch (3076:13): [True: 0, False: 0]
  ------------------
 3077|      0|            !(sptr->getCont() &&
  ------------------
  |  Branch (3077:15): [True: 0, False: 0]
  ------------------
 3078|      0|              TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3079|      0|        rv = sptr->checkword(word, start, len, sfxopts, ppfx, cclass,
 3080|      0|                             needflag, FLAG_NULL, scratch);
  ------------------
  |  |   96|      0|#define FLAG_NULL 0x00
  ------------------
 3081|      0|      while (rv) {
  ------------------
  |  Branch (3081:14): [True: 0, False: 0]
  ------------------
 3082|      0|        if (ppfx) {
  ------------------
  |  Branch (3082:13): [True: 0, False: 0]
  ------------------
 3083|      0|          if (ppfx->getMorph()) {
  ------------------
  |  Branch (3083:15): [True: 0, False: 0]
  ------------------
 3084|      0|            result.append(ppfx->getMorph());
 3085|      0|            result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3086|      0|          } else
 3087|      0|            debugflag(result, ppfx->getFlag());
 3088|      0|        }
 3089|      0|        if (complexprefixes && HENTRY_DATA(rv))
  ------------------
  |  Branch (3089:13): [True: 0, False: 0]
  |  Branch (3089:32): [True: 0, False: 0]
  ------------------
 3090|      0|          result.append(HENTRY_DATA2(rv));
 3091|      0|        if (!HENTRY_FIND(rv, MORPH_STEM)) {
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
  |  Branch (3091:13): [True: 0, False: 0]
  ------------------
 3092|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3093|      0|          result.append(MORPH_STEM);
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
 3094|      0|          result.append(HENTRY_WORD(rv));
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 3095|      0|        }
 3096|       |
 3097|      0|        if (!complexprefixes && HENTRY_DATA(rv)) {
  ------------------
  |  Branch (3097:13): [True: 0, False: 0]
  |  Branch (3097:33): [True: 0, False: 0]
  ------------------
 3098|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3099|      0|          result.append(HENTRY_DATA2(rv));
 3100|      0|        }
 3101|       |
 3102|      0|        if (sptr->getMorph()) {
  ------------------
  |  Branch (3102:13): [True: 0, False: 0]
  ------------------
 3103|      0|          result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 3104|      0|          result.append(sptr->getMorph());
 3105|      0|        } else
 3106|      0|          debugflag(result, sptr->getFlag());
 3107|      0|        result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 3108|      0|        rv = sptr->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag);
 3109|      0|      }
 3110|      0|      sptr = sptr->getNextEQ();
 3111|      4|    } else {
 3112|      4|      sptr = sptr->getNextNE();
 3113|      4|    }
 3114|      4|  }
 3115|       |
 3116|  10.6k|  return result;
 3117|  10.6k|}
_ZN8AffixMgr11affix_checkERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiR12AffixScratchtc:
 3125|  8.54M|                                     char in_compound) {
 3126|       |
 3127|       |  // check all prefixes (also crossed with suffixes if allowed)
 3128|  8.54M|  struct hentry* rv = prefix_check(word, start, len, in_compound, scratch, needflag);
 3129|  8.54M|  if (rv)
  ------------------
  |  Branch (3129:7): [True: 0, False: 8.54M]
  ------------------
 3130|      0|    return rv;
 3131|       |
 3132|       |  // if still not found check all suffixes
 3133|  8.54M|  rv = suffix_check(word, start, len, 0, nullptr, scratch, FLAG_NULL, needflag, in_compound);
  ------------------
  |  |   96|  8.54M|#define FLAG_NULL 0x00
  ------------------
 3134|       |
 3135|  8.54M|  if (havecontclass) {
  ------------------
  |  Branch (3135:7): [True: 2.92M, False: 5.61M]
  ------------------
 3136|  2.92M|    sfx = nullptr;
 3137|  2.92M|    pfx = nullptr;
 3138|       |
 3139|  2.92M|    if (rv)
  ------------------
  |  Branch (3139:9): [True: 1, False: 2.92M]
  ------------------
 3140|      1|      return rv;
 3141|       |    // if still not found check all two-level suffixes
 3142|  2.92M|    rv = suffix_check_twosfx(word, start, len, 0, nullptr, scratch, needflag);
 3143|       |
 3144|  2.92M|    if (rv)
  ------------------
  |  Branch (3144:9): [True: 0, False: 2.92M]
  ------------------
 3145|      0|      return rv;
 3146|       |    // if still not found check all two-level suffixes
 3147|  2.92M|    rv = prefix_check_twosfx(word, start, len, IN_CPD_NOT, scratch, needflag);
  ------------------
  |  |   72|  2.92M|#define IN_CPD_NOT 0
  ------------------
 3148|  2.92M|  }
 3149|       |
 3150|  8.54M|  return rv;
 3151|  8.54M|}
_ZN8AffixMgr17affix_check_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiiR12AffixScratchtc:
 3159|  10.6k|                                  char in_compound) {
 3160|  10.6k|  std::string result;
 3161|       |
 3162|       |  // check all prefixes (also crossed with suffixes if allowed)
 3163|  10.6k|  std::string st = prefix_check_morph(word, start, len, in_compound, scratch);
 3164|  10.6k|  if (!st.empty()) {
  ------------------
  |  Branch (3164:7): [True: 0, False: 10.6k]
  ------------------
 3165|      0|    result.append(st);
 3166|      0|  }
 3167|       |
 3168|       |  // if still not found check all suffixes
 3169|  10.6k|  st = suffix_check_morph(word, start, len, 0, nullptr, scratch, '\0', needflag, in_compound);
 3170|  10.6k|  if (!st.empty()) {
  ------------------
  |  Branch (3170:7): [True: 0, False: 10.6k]
  ------------------
 3171|      0|    result.append(st);
 3172|      0|  }
 3173|       |
 3174|  10.6k|  if (havecontclass) {
  ------------------
  |  Branch (3174:7): [True: 3.33k, False: 7.36k]
  ------------------
 3175|  3.33k|    sfx = nullptr;
 3176|  3.33k|    pfx = nullptr;
 3177|       |    // if still not found check all two-level suffixes
 3178|  3.33k|    st = suffix_check_twosfx_morph(word, start, len, 0, nullptr, scratch, needflag);
 3179|  3.33k|    if (!st.empty()) {
  ------------------
  |  Branch (3179:9): [True: 0, False: 3.33k]
  ------------------
 3180|      0|      result.append(st);
 3181|      0|    }
 3182|       |
 3183|       |    // if still not found check all two-level suffixes
 3184|  3.33k|    st = prefix_check_twosfx_morph(word, start, len, IN_CPD_NOT, scratch, needflag);
  ------------------
  |  |   72|  3.33k|#define IN_CPD_NOT 0
  ------------------
 3185|  3.33k|    if (!st.empty()) {
  ------------------
  |  Branch (3185:9): [True: 0, False: 3.33k]
  ------------------
 3186|      0|      result.append(st);
 3187|      0|    }
 3188|  3.33k|  }
 3189|       |
 3190|  10.6k|  return result;
 3191|  10.6k|}
_ZN8AffixMgr15expand_rootwordEP9guesswordiPKciPKttS3_iS3_:
 3379|   584k|                              const char* phon) {
 3380|   584k|  int nh = 0;
 3381|       |  // first add root word to list
 3382|   584k|  if ((nh < maxn) &&
  ------------------
  |  Branch (3382:7): [True: 584k, False: 0]
  ------------------
 3383|   584k|      !(al && ((needaffix && TESTAFF(ap, needaffix, al)) ||
  ------------------
  |  |   99|  4.46k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 2.23k, False: 2.23k]
  |  |  ------------------
  ------------------
  |  Branch (3383:9): [True: 94.8k, False: 489k]
  |  Branch (3383:17): [True: 4.46k, False: 90.3k]
  ------------------
 3384|   581k|               (onlyincompound && TESTAFF(ap, onlyincompound, al))))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (3384:17): [True: 0, False: 92.5k]
  ------------------
 3385|   581k|    wlst[nh].word = mystrdup(ts);
 3386|   581k|    wlst[nh].allow = false;
 3387|   581k|    wlst[nh].orig = nullptr;
 3388|   581k|    nh++;
 3389|       |    // add special phonetic version
 3390|   581k|    if (phon && (nh < maxn)) {
  ------------------
  |  Branch (3390:9): [True: 754, False: 581k]
  |  Branch (3390:17): [True: 754, False: 0]
  ------------------
 3391|    754|      wlst[nh].word = mystrdup(phon);
 3392|    754|      wlst[nh].allow = false;
 3393|    754|      wlst[nh].orig = mystrdup(ts);
 3394|    754|      nh++;
 3395|    754|    }
 3396|   581k|  }
 3397|       |
 3398|       |  // handle suffixes
 3399|   690k|  for (int i = 0; i < al; i++) {
  ------------------
  |  Branch (3399:19): [True: 106k, False: 584k]
  ------------------
 3400|   106k|    const auto c = (unsigned char)(ap[i] & 0x00FF);
 3401|   106k|    SfxEntry* sptr = sFlag[c];
 3402|   169k|    while (sptr) {
  ------------------
  |  Branch (3402:12): [True: 62.8k, False: 106k]
  ------------------
 3403|  62.8k|      if ((sptr->getFlag() == ap[i]) &&
  ------------------
  |  Branch (3403:11): [True: 62.8k, False: 0]
  ------------------
 3404|  62.8k|          (!sptr->getKeyLen() ||
  ------------------
  |  Branch (3404:12): [True: 0, False: 62.8k]
  ------------------
 3405|  62.8k|           ((badl > sptr->getKeyLen()) &&
  ------------------
  |  Branch (3405:13): [True: 36.3k, False: 26.5k]
  ------------------
 3406|  36.3k|            (strcmp(sptr->getAffix(), bad + badl - sptr->getKeyLen()) == 0))) &&
  ------------------
  |  Branch (3406:13): [True: 35, False: 36.3k]
  ------------------
 3407|       |          // check needaffix flag
 3408|     35|          !(sptr->getCont() &&
  ------------------
  |  Branch (3408:13): [True: 19, False: 16]
  ------------------
 3409|     19|            ((needaffix &&
  ------------------
  |  Branch (3409:15): [True: 11, False: 8]
  ------------------
 3410|     11|              TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())) ||
  ------------------
  |  |   99|     11|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 11]
  |  |  ------------------
  ------------------
 3411|     19|             (circumfix &&
  ------------------
  |  Branch (3411:15): [True: 0, False: 19]
  ------------------
 3412|      0|              TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3413|     19|             (onlyincompound &&
  ------------------
  |  Branch (3413:15): [True: 0, False: 19]
  ------------------
 3414|     35|              TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3415|     35|        std::string newword = sptr->add(ts, wl);
 3416|     35|        if (!newword.empty()) {
  ------------------
  |  Branch (3416:13): [True: 35, False: 0]
  ------------------
 3417|     35|          if (nh < maxn) {
  ------------------
  |  Branch (3417:15): [True: 35, False: 0]
  ------------------
 3418|     35|            wlst[nh].word = mystrdup(newword.c_str());
 3419|     35|            wlst[nh].allow = sptr->allowCross();
 3420|     35|            wlst[nh].orig = nullptr;
 3421|     35|            nh++;
 3422|       |            // add special phonetic version
 3423|     35|            if (phon && (nh < maxn)) {
  ------------------
  |  Branch (3423:17): [True: 0, False: 35]
  |  Branch (3423:25): [True: 0, False: 0]
  ------------------
 3424|      0|              std::string prefix(phon);
 3425|      0|              std::string key(sptr->getKey());
 3426|      0|              reverseword(key);
 3427|      0|              prefix.append(key);
 3428|      0|              wlst[nh].word = mystrdup(prefix.c_str());
 3429|      0|              wlst[nh].allow = false;
 3430|      0|              wlst[nh].orig = mystrdup(newword.c_str());
 3431|      0|              nh++;
 3432|      0|            }
 3433|     35|          }
 3434|     35|        }
 3435|     35|      }
 3436|  62.8k|      sptr = sptr->getFlgNxt();
 3437|  62.8k|    }
 3438|   106k|  }
 3439|       |
 3440|   584k|  int n = nh;
 3441|       |
 3442|       |  // handle cross products of prefixes and suffixes
 3443|   584k|  for (int j = 1; j < n; j++)
  ------------------
  |  Branch (3443:19): [True: 778, False: 584k]
  ------------------
 3444|    778|    if (wlst[j].allow) {
  ------------------
  |  Branch (3444:9): [True: 24, False: 754]
  ------------------
 3445|     72|      for (int k = 0; k < al; k++) {
  ------------------
  |  Branch (3445:23): [True: 48, False: 24]
  ------------------
 3446|     48|        const auto c = (unsigned char)(ap[k] & 0x00FF);
 3447|     48|        PfxEntry* cptr = pFlag[c];
 3448|     48|        while (cptr) {
  ------------------
  |  Branch (3448:16): [True: 0, False: 48]
  ------------------
 3449|      0|          if ((cptr->getFlag() == ap[k]) && cptr->allowCross() &&
  ------------------
  |  Branch (3449:15): [True: 0, False: 0]
  |  Branch (3449:45): [True: 0, False: 0]
  ------------------
 3450|      0|              (!cptr->getKeyLen() ||
  ------------------
  |  Branch (3450:16): [True: 0, False: 0]
  ------------------
 3451|      0|               ((badl > cptr->getKeyLen()) &&
  ------------------
  |  Branch (3451:17): [True: 0, False: 0]
  ------------------
 3452|      0|                (strncmp(cptr->getKey(), bad, cptr->getKeyLen()) == 0)))) {
  ------------------
  |  Branch (3452:17): [True: 0, False: 0]
  ------------------
 3453|      0|            int l1 = strlen(wlst[j].word);
 3454|      0|            std::string newword = cptr->add(wlst[j].word, l1);
 3455|      0|            if (!newword.empty()) {
  ------------------
  |  Branch (3455:17): [True: 0, False: 0]
  ------------------
 3456|      0|              if (nh < maxn) {
  ------------------
  |  Branch (3456:19): [True: 0, False: 0]
  ------------------
 3457|      0|                wlst[nh].word = mystrdup(newword.c_str());
 3458|      0|                wlst[nh].allow = cptr->allowCross();
 3459|      0|                wlst[nh].orig = nullptr;
 3460|      0|                nh++;
 3461|      0|              }
 3462|      0|            }
 3463|      0|          }
 3464|      0|          cptr = cptr->getFlgNxt();
 3465|      0|        }
 3466|     48|      }
 3467|     24|    }
 3468|       |
 3469|       |  // now handle pure prefixes
 3470|   690k|  for (int m = 0; m < al; m++) {
  ------------------
  |  Branch (3470:19): [True: 106k, False: 584k]
  ------------------
 3471|   106k|    const auto c = (unsigned char)(ap[m] & 0x00FF);
 3472|   106k|    PfxEntry* ptr = pFlag[c];
 3473|   107k|    while (ptr) {
  ------------------
  |  Branch (3473:12): [True: 774, False: 106k]
  ------------------
 3474|    774|      if ((ptr->getFlag() == ap[m]) &&
  ------------------
  |  Branch (3474:11): [True: 774, False: 0]
  ------------------
 3475|    774|          (!ptr->getKeyLen() ||
  ------------------
  |  Branch (3475:12): [True: 0, False: 774]
  ------------------
 3476|    774|           ((badl > ptr->getKeyLen()) &&
  ------------------
  |  Branch (3476:13): [True: 774, False: 0]
  ------------------
 3477|    774|            (strncmp(ptr->getKey(), bad, ptr->getKeyLen()) == 0))) &&
  ------------------
  |  Branch (3477:13): [True: 3, False: 771]
  ------------------
 3478|       |          // check needaffix flag
 3479|      3|          !(ptr->getCont() &&
  ------------------
  |  Branch (3479:13): [True: 0, False: 3]
  ------------------
 3480|      0|            ((needaffix &&
  ------------------
  |  Branch (3480:15): [True: 0, False: 0]
  ------------------
 3481|      0|              TESTAFF(ptr->getCont(), needaffix, ptr->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3482|      0|             (circumfix &&
  ------------------
  |  Branch (3482:15): [True: 0, False: 0]
  ------------------
 3483|      0|              TESTAFF(ptr->getCont(), circumfix, ptr->getContLen())) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3484|      0|             (onlyincompound &&
  ------------------
  |  Branch (3484:15): [True: 0, False: 0]
  ------------------
 3485|      3|              TESTAFF(ptr->getCont(), onlyincompound, ptr->getContLen()))))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3486|      3|        std::string newword = ptr->add(ts, wl);
 3487|      3|        if (!newword.empty()) {
  ------------------
  |  Branch (3487:13): [True: 3, False: 0]
  ------------------
 3488|      3|          if (nh < maxn) {
  ------------------
  |  Branch (3488:15): [True: 3, False: 0]
  ------------------
 3489|      3|            wlst[nh].word = mystrdup(newword.c_str());
 3490|      3|            wlst[nh].allow = ptr->allowCross();
 3491|      3|            wlst[nh].orig = nullptr;
 3492|      3|            nh++;
 3493|      3|          }
 3494|      3|        }
 3495|      3|      }
 3496|    774|      ptr = ptr->getFlgNxt();
 3497|    774|    }
 3498|   106k|  }
 3499|       |
 3500|   584k|  return nh;
 3501|   584k|}
_ZNK8AffixMgr12get_reptableEv:
 3504|   359k|const std::vector<replentry>& AffixMgr::get_reptable() const {
 3505|   359k|  return pHMgr->get_reptable();
 3506|   359k|}
_ZNK8AffixMgr14get_iconvtableEv:
 3509|  7.54M|RepList* AffixMgr::get_iconvtable() const {
 3510|  7.54M|  if (!iconvtable)
  ------------------
  |  Branch (3510:7): [True: 7.28M, False: 254k]
  ------------------
 3511|  7.28M|    return nullptr;
 3512|   254k|  return iconvtable;
 3513|  7.54M|}
_ZNK8AffixMgr14get_oconvtableEv:
 3516|  95.0k|RepList* AffixMgr::get_oconvtable() const {
 3517|  95.0k|  if (!oconvtable)
  ------------------
  |  Branch (3517:7): [True: 89.9k, False: 5.07k]
  ------------------
 3518|  89.9k|    return nullptr;
 3519|  5.07k|  return oconvtable;
 3520|  95.0k|}
_ZNK8AffixMgr14get_phonetableEv:
 3523|  59.6k|struct phonetable* AffixMgr::get_phonetable() const {
 3524|  59.6k|  if (!phone)
  ------------------
  |  Branch (3524:7): [True: 56.2k, False: 3.40k]
  ------------------
 3525|  56.2k|    return nullptr;
 3526|  3.40k|  return phone;
 3527|  59.6k|}
_ZNK8AffixMgr12get_maptableEv:
 3530|   359k|const std::vector<mapentry>& AffixMgr::get_maptable() const {
 3531|   359k|  return maptable;
 3532|   359k|}
_ZNK8AffixMgr14get_breaktableEv:
 3535|     38|const std::vector<std::string>& AffixMgr::get_breaktable() const {
 3536|     38|  return breaktable;
 3537|     38|}
_ZN8AffixMgr12get_encodingEv:
 3540|     78|const std::string& AffixMgr::get_encoding() {
 3541|     78|  if (encoding.empty())
  ------------------
  |  Branch (3541:7): [True: 20, False: 58]
  ------------------
 3542|     20|    encoding = SPELL_ENCODING;
  ------------------
  |  |   99|     20|#define SPELL_ENCODING "ISO8859-1"
  ------------------
 3543|     78|  return encoding;
 3544|     78|}
_ZNK8AffixMgr11get_langnumEv:
 3547|     76|int AffixMgr::get_langnum() const {
 3548|     76|  return langnum;
 3549|     76|}
_ZNK8AffixMgr19get_complexprefixesEv:
 3552|     76|int AffixMgr::get_complexprefixes() const {
 3553|     76|  return complexprefixes;
 3554|     76|}
_ZNK8AffixMgr13get_fullstripEv:
 3557|  6.24k|int AffixMgr::get_fullstrip() const {
 3558|  6.24k|  return fullstrip;
 3559|  6.24k|}
_ZNK8AffixMgr12get_keepcaseEv:
 3561|  98.3k|FLAG AffixMgr::get_keepcase() const {
 3562|  98.3k|  return keepcase;
 3563|  98.3k|}
_ZNK8AffixMgr14get_forceucaseEv:
 3565|  20.3k|FLAG AffixMgr::get_forceucase() const {
 3566|  20.3k|  return forceucase;
 3567|  20.3k|}
_ZNK8AffixMgr8get_warnEv:
 3569|  25.0k|FLAG AffixMgr::get_warn() const {
 3570|  25.0k|  return warn;
 3571|  25.0k|}
_ZNK8AffixMgr14get_forbidwarnEv:
 3573|      4|int AffixMgr::get_forbidwarn() const {
 3574|      4|  return forbidwarn;
 3575|      4|}
_ZNK8AffixMgr15get_checksharpsEv:
 3577|   168k|int AffixMgr::get_checksharps() const {
 3578|   168k|  return checksharps;
 3579|   168k|}
_ZNK8AffixMgr10get_ignoreEv:
 3586|  16.0M|const char* AffixMgr::get_ignore() const {
 3587|  16.0M|  if (ignorechars.empty())
  ------------------
  |  Branch (3587:7): [True: 14.4M, False: 1.60M]
  ------------------
 3588|  14.4M|    return nullptr;
 3589|  1.60M|  return ignorechars.c_str();
 3590|  16.0M|}
_ZNK8AffixMgr16get_ignore_utf16Ev:
 3593|   362k|const std::vector<w_char>& AffixMgr::get_ignore_utf16() const {
 3594|   362k|  return ignorechars_utf16;
 3595|   362k|}
_ZN8AffixMgr14get_key_stringEv:
 3598|     38|const std::string& AffixMgr::get_key_string() {
 3599|     38|  if (keystring.empty())
  ------------------
  |  Branch (3599:7): [True: 38, False: 0]
  ------------------
 3600|     38|    keystring = SPELL_KEYSTRING;
  ------------------
  |  |  100|     38|#define SPELL_KEYSTRING "qwertyuiop|asdfghjkl|zxcvbnm"
  ------------------
 3601|     38|  return keystring;
 3602|     38|}
_ZNK8AffixMgr14get_try_stringEv:
 3605|     38|const std::string& AffixMgr::get_try_string() const {
 3606|     38|  return trystring;
 3607|     38|}
_ZNK8AffixMgr12get_compoundEv:
 3619|  64.0M|int AffixMgr::get_compound() const {
 3620|  64.0M|  return compoundflag || compoundbegin || !defcpdtable.empty();
  ------------------
  |  Branch (3620:10): [True: 16.0M, False: 48.0M]
  |  Branch (3620:26): [True: 0, False: 48.0M]
  |  Branch (3620:43): [True: 0, False: 48.0M]
  ------------------
 3621|  64.0M|}
_ZNK8AffixMgr16get_compoundflagEv:
 3624|  42.0k|FLAG AffixMgr::get_compoundflag() const {
 3625|  42.0k|  return compoundflag;
 3626|  42.0k|}
_ZNK8AffixMgr17get_forbiddenwordEv:
 3629|   155k|FLAG AffixMgr::get_forbiddenword() const {
 3630|   155k|  return forbiddenword;
 3631|   155k|}
_ZNK8AffixMgr13get_nosuggestEv:
 3634|  60.0k|FLAG AffixMgr::get_nosuggest() const {
 3635|  60.0k|  return nosuggest;
 3636|  60.0k|}
_ZNK8AffixMgr18get_nongramsuggestEv:
 3639|  59.6k|FLAG AffixMgr::get_nongramsuggest() const {
 3640|  59.6k|  return nongramsuggest;
 3641|  59.6k|}
_ZNK8AffixMgr15get_substandardEv:
 3644|    381|FLAG AffixMgr::get_substandard() const {
 3645|    381|  return substandard;
 3646|    381|}
_ZNK8AffixMgr13get_needaffixEv:
 3649|  1.58k|FLAG AffixMgr::get_needaffix() const {
 3650|  1.58k|  return needaffix;
 3651|  1.58k|}
_ZNK8AffixMgr18get_onlyincompoundEv:
 3654|  60.8k|FLAG AffixMgr::get_onlyincompound() const {
 3655|  60.8k|  return onlyincompound;
 3656|  60.8k|}
_ZN8AffixMgr6lookupEPKcm:
 3664|   497M|struct hentry* AffixMgr::lookup(const char* word, size_t len) {
 3665|   497M|  struct hentry* he = nullptr;
 3666|   994M|  for (size_t i = 0; i < alldic.size() && !he; ++i) {
  ------------------
  |  Branch (3666:22): [True: 497M, False: 497M]
  |  Branch (3666:43): [True: 497M, False: 0]
  ------------------
 3667|   497M|    he = alldic[i]->lookup(word, len);
 3668|   497M|  }
 3669|   497M|  return he;
 3670|   497M|}
_ZNK8AffixMgr14have_contclassEv:
 3673|  29.3M|int AffixMgr::have_contclass() const {
 3674|  29.3M|  return havecontclass;
 3675|  29.3M|}
_ZNK8AffixMgr8get_utf8Ev:
 3678|     76|int AffixMgr::get_utf8() const {
 3679|     76|  return utf8;
 3680|     76|}
_ZNK8AffixMgr16get_maxngramsugsEv:
 3682|  66.9k|int AffixMgr::get_maxngramsugs() const {
 3683|  66.9k|  return maxngramsugs;
 3684|  66.9k|}
_ZNK8AffixMgr14get_maxcpdsugsEv:
 3686|     38|int AffixMgr::get_maxcpdsugs() const {
 3687|     38|  return maxcpdsugs;
 3688|     38|}
_ZNK8AffixMgr11get_maxdiffEv:
 3690|  46.1k|int AffixMgr::get_maxdiff() const {
 3691|  46.1k|  return maxdiff;
 3692|  46.1k|}
_ZNK8AffixMgr15get_onlymaxdiffEv:
 3694|  7.21k|int AffixMgr::get_onlymaxdiff() const {
 3695|  7.21k|  return onlymaxdiff;
 3696|  7.21k|}
_ZNK8AffixMgr15get_nosplitsugsEv:
 3699|     38|int AffixMgr::get_nosplitsugs() const {
 3700|     38|  return nosplitsugs;
 3701|     38|}
_ZNK8AffixMgr16get_sugswithdotsEv:
 3704|  3.16k|int AffixMgr::get_sugswithdots() const {
 3705|  3.16k|  return sugswithdots;
 3706|  3.16k|}
_ZN8AffixMgr10parse_flagERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPtP7FileMgr:
 3709|     22|bool AffixMgr::parse_flag(const std::string& line, unsigned short* out, FileMgr* af) {
 3710|     22|  if (*out != FLAG_NULL && !(*out >= DEFAULTFLAGS)) {
  ------------------
  |  |   96|     44|#define FLAG_NULL 0x00
  ------------------
                if (*out != FLAG_NULL && !(*out >= DEFAULTFLAGS)) {
  ------------------
  |  |  126|      2|#define DEFAULTFLAGS 65510
  ------------------
  |  Branch (3710:7): [True: 2, False: 20]
  |  Branch (3710:28): [True: 0, False: 2]
  ------------------
 3711|      0|    HUNSPELL_WARNING(
 3712|      0|        stderr,
 3713|      0|        "error: line %d: multiple definitions of an affix file parameter\n",
 3714|      0|        af->getlinenum());
 3715|      0|    return false;
 3716|      0|  }
 3717|     22|  std::string s;
 3718|     22|  if (!parse_string(line, s, af->getlinenum()))
  ------------------
  |  Branch (3718:7): [True: 0, False: 22]
  ------------------
 3719|      0|    return false;
 3720|     22|  *out = pHMgr->decode_flag(s);
 3721|     22|  return true;
 3722|     22|}
_ZN8AffixMgr9parse_numERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPiP7FileMgr:
 3725|     10|bool AffixMgr::parse_num(const std::string& line, int* out, FileMgr* af) {
 3726|     10|  if (*out != -1) {
  ------------------
  |  Branch (3726:7): [True: 0, False: 10]
  ------------------
 3727|      0|    HUNSPELL_WARNING(
 3728|      0|        stderr,
 3729|      0|        "error: line %d: multiple definitions of an affix file parameter\n",
 3730|      0|        af->getlinenum());
 3731|      0|    return false;
 3732|      0|  }
 3733|     10|  std::string s;
 3734|     10|  if (!parse_string(line, s, af->getlinenum()))
  ------------------
  |  Branch (3734:7): [True: 0, False: 10]
  ------------------
 3735|      0|    return false;
 3736|     10|  *out = atoi(s.c_str());
 3737|     10|  return true;
 3738|     10|}
_ZN8AffixMgr17parse_cpdsyllableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgr:
 3741|      2|bool AffixMgr::parse_cpdsyllable(const std::string& line, FileMgr* af) {
 3742|      2|  int i = 0;
 3743|      2|  int np = 0;
 3744|      2|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 3745|      8|  while (start_piece != line.end()) {
  ------------------
  |  Branch (3745:10): [True: 6, False: 2]
  ------------------
 3746|      6|    switch (i) {
 3747|      2|      case 0: {
  ------------------
  |  Branch (3747:7): [True: 2, False: 4]
  ------------------
 3748|      2|        np++;
 3749|      2|        break;
 3750|      0|      }
 3751|      2|      case 1: {
  ------------------
  |  Branch (3751:7): [True: 2, False: 4]
  ------------------
 3752|      2|        cpdmaxsyllable = atoi(std::string(start_piece, iter).c_str());
 3753|      2|        np++;
 3754|      2|        break;
 3755|      0|      }
 3756|      2|      case 2: {
  ------------------
  |  Branch (3756:7): [True: 2, False: 4]
  ------------------
 3757|      2|        if (!utf8) {
  ------------------
  |  Branch (3757:13): [True: 0, False: 2]
  ------------------
 3758|      0|          cpdvowels.assign(start_piece, iter);
 3759|      0|          std::sort(cpdvowels.begin(), cpdvowels.end());
 3760|      2|        } else {
 3761|      2|          std::string piece(start_piece, iter);
 3762|      2|          u8_u16(cpdvowels_utf16, piece);
 3763|      2|          std::sort(cpdvowels_utf16.begin(), cpdvowels_utf16.end());
 3764|      2|        }
 3765|      2|        np++;
 3766|      2|        break;
 3767|      0|      }
 3768|      0|      default:
  ------------------
  |  Branch (3768:7): [True: 0, False: 6]
  ------------------
 3769|      0|        break;
 3770|      6|    }
 3771|      6|    ++i;
 3772|      6|    start_piece = mystrsep(line, iter);
 3773|      6|  }
 3774|      2|  if (np < 2) {
  ------------------
  |  Branch (3774:7): [True: 0, False: 2]
  ------------------
 3775|      0|    HUNSPELL_WARNING(stderr,
 3776|      0|                     "error: line %d: missing compoundsyllable information\n",
 3777|      0|                     af->getlinenum());
 3778|      0|    return false;
 3779|      0|  }
 3780|      2|  if (np == 2)
  ------------------
  |  Branch (3780:7): [True: 0, False: 2]
  ------------------
 3781|      0|    cpdvowels = "AEIOUaeiou";
 3782|      2|  return true;
 3783|      2|}
_ZN8AffixMgr15parse_convtableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgrPP7RepListS8_:
 3788|      4|                              const std::string& keyword) {
 3789|      4|  if (*rl) {
  ------------------
  |  Branch (3789:7): [True: 0, False: 4]
  ------------------
 3790|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
 3791|      0|                     af->getlinenum());
 3792|      0|    return false;
 3793|      0|  }
 3794|      4|  int i = 0;
 3795|      4|  int np = 0;
 3796|      4|  int numrl = 0;
 3797|      4|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 3798|     18|  while (start_piece != line.end()) {
  ------------------
  |  Branch (3798:10): [True: 14, False: 4]
  ------------------
 3799|     14|    switch (i) {
 3800|      4|      case 0: {
  ------------------
  |  Branch (3800:7): [True: 4, False: 10]
  ------------------
 3801|      4|        np++;
 3802|      4|        break;
 3803|      0|      }
 3804|      4|      case 1: {
  ------------------
  |  Branch (3804:7): [True: 4, False: 10]
  ------------------
 3805|      4|        numrl = atoi(std::string(start_piece, iter).c_str());
 3806|      4|        if (numrl < 1) {
  ------------------
  |  Branch (3806:13): [True: 0, False: 4]
  ------------------
 3807|      0|          HUNSPELL_WARNING(stderr, "error: line %d: incorrect entry number\n",
 3808|      0|                           af->getlinenum());
 3809|      0|          return false;
 3810|      0|        }
 3811|      4|        *rl = new RepList(numrl);
 3812|      4|        if (!*rl)
  ------------------
  |  Branch (3812:13): [True: 0, False: 4]
  ------------------
 3813|      0|          return false;
 3814|      4|        np++;
 3815|      4|        break;
 3816|      4|      }
 3817|      6|      default:
  ------------------
  |  Branch (3817:7): [True: 6, False: 8]
  ------------------
 3818|      6|        break;
 3819|     14|    }
 3820|     14|    ++i;
 3821|     14|    start_piece = mystrsep(line, iter);
 3822|     14|  }
 3823|      4|  if (np != 2) {
  ------------------
  |  Branch (3823:7): [True: 0, False: 4]
  ------------------
 3824|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
 3825|      0|                     af->getlinenum());
 3826|      0|    return false;
 3827|      0|  }
 3828|       |
 3829|       |  /* now parse the num lines to read in the remainder of the table */
 3830|     26|  for (int j = 0; j < numrl; j++) {
  ------------------
  |  Branch (3830:19): [True: 22, False: 4]
  ------------------
 3831|     22|    std::string nl;
 3832|     22|    if (!af->getline(nl))
  ------------------
  |  Branch (3832:9): [True: 0, False: 22]
  ------------------
 3833|      0|      return false;
 3834|     22|    mychomp(nl);
 3835|     22|    i = 0;
 3836|     22|    std::string pattern;
 3837|     22|    std::string pattern2;
 3838|     22|    iter = nl.begin();
 3839|     22|    start_piece = mystrsep(nl, iter);
 3840|    130|    while (start_piece != nl.end()) {
  ------------------
  |  Branch (3840:12): [True: 108, False: 22]
  ------------------
 3841|    108|      {
 3842|    108|        switch (i) {
 3843|     22|          case 0: {
  ------------------
  |  Branch (3843:11): [True: 22, False: 86]
  ------------------
 3844|     22|            if (nl.compare(start_piece - nl.begin(), keyword.size(), keyword, 0, keyword.size()) != 0) {
  ------------------
  |  Branch (3844:17): [True: 0, False: 22]
  ------------------
 3845|      0|              HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 3846|      0|                               af->getlinenum());
 3847|      0|              delete *rl;
 3848|      0|              *rl = nullptr;
 3849|      0|              return false;
 3850|      0|            }
 3851|     22|            break;
 3852|     22|          }
 3853|     22|          case 1: {
  ------------------
  |  Branch (3853:11): [True: 22, False: 86]
  ------------------
 3854|     22|            pattern.assign(start_piece, iter);
 3855|     22|            break;
 3856|     22|          }
 3857|     22|          case 2: {
  ------------------
  |  Branch (3857:11): [True: 22, False: 86]
  ------------------
 3858|     22|            pattern2.assign(start_piece, iter);
 3859|     22|            break;
 3860|     22|          }
 3861|     42|          default:
  ------------------
  |  Branch (3861:11): [True: 42, False: 66]
  ------------------
 3862|     42|            break;
 3863|    108|        }
 3864|    108|        ++i;
 3865|    108|      }
 3866|      0|      start_piece = mystrsep(nl, iter);
 3867|    108|    }
 3868|     22|    if (pattern.empty() || pattern2.empty()) {
  ------------------
  |  Branch (3868:9): [True: 0, False: 22]
  |  Branch (3868:28): [True: 0, False: 22]
  ------------------
 3869|      0|      HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 3870|      0|                       af->getlinenum());
 3871|      0|      return false;
 3872|      0|    }
 3873|       |
 3874|     22|    (*rl)->add(pattern, pattern2);
 3875|     22|  }
 3876|      4|  return true;
 3877|      4|}
_ZN8AffixMgr16parse_phonetableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgr:
 3880|      2|bool AffixMgr::parse_phonetable(const std::string& line, FileMgr* af) {
 3881|      2|  if (phone) {
  ------------------
  |  Branch (3881:7): [True: 0, False: 2]
  ------------------
 3882|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
 3883|      0|                     af->getlinenum());
 3884|      0|    return false;
 3885|      0|  }
 3886|      2|  std::unique_ptr<phonetable> new_phone;
 3887|      2|  int num = -1;
 3888|      2|  int i = 0;
 3889|      2|  int np = 0;
 3890|      2|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 3891|      6|  while (start_piece != line.end()) {
  ------------------
  |  Branch (3891:10): [True: 4, False: 2]
  ------------------
 3892|      4|    switch (i) {
 3893|      2|      case 0: {
  ------------------
  |  Branch (3893:7): [True: 2, False: 2]
  ------------------
 3894|      2|        np++;
 3895|      2|        break;
 3896|      0|      }
 3897|      2|      case 1: {
  ------------------
  |  Branch (3897:7): [True: 2, False: 2]
  ------------------
 3898|      2|        num = atoi(std::string(start_piece, iter).c_str());
 3899|      2|        if (num < 1) {
  ------------------
  |  Branch (3899:13): [True: 0, False: 2]
  ------------------
 3900|      0|          HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
 3901|      0|                           af->getlinenum());
 3902|      0|          return false;
 3903|      0|        }
 3904|      2|        new_phone = std::make_unique<phonetable>();
 3905|      2|        new_phone->utf8 = (char)utf8;
 3906|      2|        np++;
 3907|      2|        break;
 3908|      2|      }
 3909|      0|      default:
  ------------------
  |  Branch (3909:7): [True: 0, False: 4]
  ------------------
 3910|      0|        break;
 3911|      4|    }
 3912|      4|    ++i;
 3913|      4|    start_piece = mystrsep(line, iter);
 3914|      4|  }
 3915|      2|  if (np != 2) {
  ------------------
  |  Branch (3915:7): [True: 0, False: 2]
  ------------------
 3916|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
 3917|      0|                     af->getlinenum());
 3918|      0|    return false;
 3919|      0|  }
 3920|       |
 3921|       |  /* now parse the phone->num lines to read in the remainder of the table */
 3922|    212|  for (int j = 0; j < num; ++j) {
  ------------------
  |  Branch (3922:19): [True: 210, False: 2]
  ------------------
 3923|    210|    std::string nl;
 3924|    210|    if (!af->getline(nl))
  ------------------
  |  Branch (3924:9): [True: 0, False: 210]
  ------------------
 3925|      0|      return false;
 3926|    210|    mychomp(nl);
 3927|    210|    i = 0;
 3928|    210|    const size_t old_size = new_phone->rules.size();
 3929|    210|    iter = nl.begin();
 3930|    210|    start_piece = mystrsep(nl, iter);
 3931|    840|    while (start_piece != nl.end()) {
  ------------------
  |  Branch (3931:12): [True: 630, False: 210]
  ------------------
 3932|    630|      {
 3933|    630|        switch (i) {
 3934|    210|          case 0: {
  ------------------
  |  Branch (3934:11): [True: 210, False: 420]
  ------------------
 3935|    210|            if (nl.compare(start_piece - nl.begin(), 5, "PHONE", 5) != 0) {
  ------------------
  |  Branch (3935:17): [True: 0, False: 210]
  ------------------
 3936|      0|              HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 3937|      0|                               af->getlinenum());
 3938|      0|              return false;
 3939|      0|            }
 3940|    210|            break;
 3941|    210|          }
 3942|    210|          case 1: {
  ------------------
  |  Branch (3942:11): [True: 210, False: 420]
  ------------------
 3943|    210|            new_phone->rules.emplace_back(start_piece, iter);
 3944|    210|            break;
 3945|    210|          }
 3946|    210|          case 2: {
  ------------------
  |  Branch (3946:11): [True: 210, False: 420]
  ------------------
 3947|    210|            new_phone->rules.emplace_back(start_piece, iter);
 3948|    210|            mystrrep(new_phone->rules.back(), "_", "");
 3949|    210|            break;
 3950|    210|          }
 3951|      0|          default:
  ------------------
  |  Branch (3951:11): [True: 0, False: 630]
  ------------------
 3952|      0|            break;
 3953|    630|        }
 3954|    630|        ++i;
 3955|    630|      }
 3956|      0|      start_piece = mystrsep(nl, iter);
 3957|    630|    }
 3958|    210|    if (new_phone->rules.size() != old_size + 2) {
  ------------------
  |  Branch (3958:9): [True: 0, False: 210]
  ------------------
 3959|      0|      HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 3960|      0|                       af->getlinenum());
 3961|      0|      return false;
 3962|      0|    }
 3963|    210|  }
 3964|      2|  new_phone->rules.emplace_back("");
 3965|      2|  new_phone->rules.emplace_back("");
 3966|      2|  init_phonet_hash(*new_phone);
 3967|      2|  phone = new_phone.release();
 3968|      2|  return true;
 3969|      2|}
_ZN8AffixMgr19parse_checkcpdtableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgr:
 3972|      2|bool AffixMgr::parse_checkcpdtable(const std::string& line, FileMgr* af) {
 3973|      2|  if (parsedcheckcpd) {
  ------------------
  |  Branch (3973:7): [True: 0, False: 2]
  ------------------
 3974|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
 3975|      0|                     af->getlinenum());
 3976|      0|    return false;
 3977|      0|  }
 3978|      2|  parsedcheckcpd = true;
 3979|      2|  int numcheckcpd = -1;
 3980|      2|  int i = 0;
 3981|      2|  int np = 0;
 3982|      2|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 3983|      6|  while (start_piece != line.end()) {
  ------------------
  |  Branch (3983:10): [True: 4, False: 2]
  ------------------
 3984|      4|    switch (i) {
 3985|      2|      case 0: {
  ------------------
  |  Branch (3985:7): [True: 2, False: 2]
  ------------------
 3986|      2|        np++;
 3987|      2|        break;
 3988|      0|      }
 3989|      2|      case 1: {
  ------------------
  |  Branch (3989:7): [True: 2, False: 2]
  ------------------
 3990|      2|        numcheckcpd = atoi(std::string(start_piece, iter).c_str());
 3991|      2|        if (numcheckcpd < 1) {
  ------------------
  |  Branch (3991:13): [True: 0, False: 2]
  ------------------
 3992|      0|          HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
 3993|      0|                           af->getlinenum());
 3994|      0|          return false;
 3995|      0|        }
 3996|      2|        checkcpdtable.reserve(std::min(numcheckcpd, 16384));
 3997|      2|        np++;
 3998|      2|        break;
 3999|      2|      }
 4000|      0|      default:
  ------------------
  |  Branch (4000:7): [True: 0, False: 4]
  ------------------
 4001|      0|        break;
 4002|      4|    }
 4003|      4|    ++i;
 4004|      4|    start_piece = mystrsep(line, iter);
 4005|      4|  }
 4006|      2|  if (np != 2) {
  ------------------
  |  Branch (4006:7): [True: 0, False: 2]
  ------------------
 4007|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
 4008|      0|                     af->getlinenum());
 4009|      0|    return false;
 4010|      0|  }
 4011|       |
 4012|       |  /* now parse the numcheckcpd lines to read in the remainder of the table */
 4013|      6|  for (int j = 0; j < numcheckcpd; ++j) {
  ------------------
  |  Branch (4013:19): [True: 4, False: 2]
  ------------------
 4014|      4|    std::string nl;
 4015|      4|    if (!af->getline(nl))
  ------------------
  |  Branch (4015:9): [True: 0, False: 4]
  ------------------
 4016|      0|      return false;
 4017|      4|    mychomp(nl);
 4018|      4|    i = 0;
 4019|      4|    checkcpdtable.emplace_back();
 4020|      4|    iter = nl.begin();
 4021|      4|    start_piece = mystrsep(nl, iter);
 4022|     16|    while (start_piece != nl.end()) {
  ------------------
  |  Branch (4022:12): [True: 12, False: 4]
  ------------------
 4023|     12|      switch (i) {
 4024|      4|        case 0: {
  ------------------
  |  Branch (4024:9): [True: 4, False: 8]
  ------------------
 4025|      4|          if (nl.compare(start_piece - nl.begin(), 20, "CHECKCOMPOUNDPATTERN", 20) != 0) {
  ------------------
  |  Branch (4025:15): [True: 0, False: 4]
  ------------------
 4026|      0|            HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 4027|      0|                             af->getlinenum());
 4028|      0|            checkcpdtable.clear();
 4029|      0|            return false;
 4030|      0|          }
 4031|      4|          break;
 4032|      4|        }
 4033|      4|        case 1: {
  ------------------
  |  Branch (4033:9): [True: 4, False: 8]
  ------------------
 4034|      4|          checkcpdtable.back().pattern.assign(start_piece, iter);
 4035|      4|          size_t slash_pos = checkcpdtable.back().pattern.find('/');
 4036|      4|          if (slash_pos != std::string::npos) {
  ------------------
  |  Branch (4036:15): [True: 0, False: 4]
  ------------------
 4037|      0|            std::string chunk(checkcpdtable.back().pattern, slash_pos + 1);
 4038|      0|            checkcpdtable.back().pattern.resize(slash_pos);
 4039|      0|            checkcpdtable.back().cond = pHMgr->decode_flag(chunk);
 4040|      0|          }
 4041|      4|          break;
 4042|      4|        }
 4043|      4|        case 2: {
  ------------------
  |  Branch (4043:9): [True: 4, False: 8]
  ------------------
 4044|      4|          checkcpdtable.back().pattern2.assign(start_piece, iter);
 4045|      4|          size_t slash_pos = checkcpdtable.back().pattern2.find('/');
 4046|      4|          if (slash_pos != std::string::npos) {
  ------------------
  |  Branch (4046:15): [True: 0, False: 4]
  ------------------
 4047|      0|            std::string chunk(checkcpdtable.back().pattern2, slash_pos + 1);
 4048|      0|            checkcpdtable.back().pattern2.resize(slash_pos);
 4049|      0|            checkcpdtable.back().cond2 = pHMgr->decode_flag(chunk);
 4050|      0|          }
 4051|      4|          break;
 4052|      4|        }
 4053|      0|        case 3: {
  ------------------
  |  Branch (4053:9): [True: 0, False: 12]
  ------------------
 4054|      0|          checkcpdtable.back().pattern3.assign(start_piece, iter);
 4055|      0|          simplifiedcpd = 1;
 4056|      0|          break;
 4057|      4|        }
 4058|      0|        default:
  ------------------
  |  Branch (4058:9): [True: 0, False: 12]
  ------------------
 4059|      0|          break;
 4060|     12|      }
 4061|     12|      i++;
 4062|     12|      start_piece = mystrsep(nl, iter);
 4063|     12|    }
 4064|      4|  }
 4065|      2|  return true;
 4066|      2|}
_ZN8AffixMgr14parse_maptableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgr:
 4170|      2|bool AffixMgr::parse_maptable(const std::string& line, FileMgr* af) {
 4171|      2|  if (parsedmaptable) {
  ------------------
  |  Branch (4171:7): [True: 0, False: 2]
  ------------------
 4172|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
 4173|      0|                     af->getlinenum());
 4174|      0|    return false;
 4175|      0|  }
 4176|      2|  parsedmaptable = true;
 4177|      2|  int nummap = -1;
 4178|      2|  int i = 0;
 4179|      2|  int np = 0;
 4180|      2|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 4181|      6|  while (start_piece != line.end()) {
  ------------------
  |  Branch (4181:10): [True: 4, False: 2]
  ------------------
 4182|      4|    switch (i) {
 4183|      2|      case 0: {
  ------------------
  |  Branch (4183:7): [True: 2, False: 2]
  ------------------
 4184|      2|        np++;
 4185|      2|        break;
 4186|      0|      }
 4187|      2|      case 1: {
  ------------------
  |  Branch (4187:7): [True: 2, False: 2]
  ------------------
 4188|      2|        nummap = atoi(std::string(start_piece, iter).c_str());
 4189|      2|        if (nummap < 1) {
  ------------------
  |  Branch (4189:13): [True: 0, False: 2]
  ------------------
 4190|      0|          HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
 4191|      0|                           af->getlinenum());
 4192|      0|          return false;
 4193|      0|        }
 4194|      2|        maptable.reserve(std::min(nummap, 16384));
 4195|      2|        np++;
 4196|      2|        break;
 4197|      2|      }
 4198|      0|      default:
  ------------------
  |  Branch (4198:7): [True: 0, False: 4]
  ------------------
 4199|      0|        break;
 4200|      4|    }
 4201|      4|    ++i;
 4202|      4|    start_piece = mystrsep(line, iter);
 4203|      4|  }
 4204|      2|  if (np != 2) {
  ------------------
  |  Branch (4204:7): [True: 0, False: 2]
  ------------------
 4205|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
 4206|      0|                     af->getlinenum());
 4207|      0|    return false;
 4208|      0|  }
 4209|       |
 4210|       |  /* now parse the nummap lines to read in the remainder of the table */
 4211|      8|  for (int j = 0; j < nummap; ++j) {
  ------------------
  |  Branch (4211:19): [True: 6, False: 2]
  ------------------
 4212|      6|    std::string nl;
 4213|      6|    if (!af->getline(nl))
  ------------------
  |  Branch (4213:9): [True: 0, False: 6]
  ------------------
 4214|      0|      return false;
 4215|      6|    mychomp(nl);
 4216|      6|    i = 0;
 4217|      6|    maptable.emplace_back();
 4218|      6|    iter = nl.begin();
 4219|      6|    start_piece = mystrsep(nl, iter);
 4220|     18|    while (start_piece != nl.end()) {
  ------------------
  |  Branch (4220:12): [True: 12, False: 6]
  ------------------
 4221|     12|      switch (i) {
 4222|      6|        case 0: {
  ------------------
  |  Branch (4222:9): [True: 6, False: 6]
  ------------------
 4223|      6|          if (nl.compare(start_piece - nl.begin(), 3, "MAP", 3) != 0) {
  ------------------
  |  Branch (4223:15): [True: 0, False: 6]
  ------------------
 4224|      0|            HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 4225|      0|                             af->getlinenum());
 4226|      0|            nummap = 0;
 4227|      0|            return false;
 4228|      0|          }
 4229|      6|          break;
 4230|      6|        }
 4231|      6|        case 1: {
  ------------------
  |  Branch (4231:9): [True: 6, False: 6]
  ------------------
 4232|     22|          for (auto k = start_piece; k != iter; ++k) {
  ------------------
  |  Branch (4232:38): [True: 16, False: 6]
  ------------------
 4233|     16|            auto chb = k, che = k + 1;
 4234|     16|            if (*k == '(') {
  ------------------
  |  Branch (4234:17): [True: 2, False: 14]
  ------------------
 4235|      2|              auto parpos = std::find(k, iter, ')');
 4236|      2|              if (parpos != iter) {
  ------------------
  |  Branch (4236:19): [True: 2, False: 0]
  ------------------
 4237|      2|                chb = k + 1;
 4238|      2|                che = parpos;
 4239|      2|                k = parpos;
 4240|      2|              }
 4241|     14|            } else {
 4242|     14|              if (utf8 && (*k & 0xc0) == 0xc0) {
  ------------------
  |  Branch (4242:19): [True: 14, False: 0]
  |  Branch (4242:27): [True: 10, False: 4]
  ------------------
 4243|     10|                ++k;
 4244|     20|                while (k != iter && is_utf8_cont(*k))
  ------------------
  |  Branch (4244:24): [True: 18, False: 2]
  |  Branch (4244:37): [True: 10, False: 8]
  ------------------
 4245|     10|                    ++k;
 4246|     10|                che = k;
 4247|     10|                --k;
 4248|     10|              }
 4249|     14|            }
 4250|     16|            if (chb == che) {
  ------------------
  |  Branch (4250:17): [True: 0, False: 16]
  ------------------
 4251|      0|              HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 4252|      0|                              af->getlinenum());
 4253|      0|            }
 4254|       |
 4255|     16|            maptable.back().emplace_back(chb, che);
 4256|     16|          }
 4257|      6|          break;
 4258|      6|        }
 4259|      0|        default:
  ------------------
  |  Branch (4259:9): [True: 0, False: 12]
  ------------------
 4260|      0|          break;
 4261|     12|      }
 4262|     12|      ++i;
 4263|     12|      start_piece = mystrsep(nl, iter);
 4264|     12|    }
 4265|      6|    if (maptable.back().empty()) {
  ------------------
  |  Branch (4265:9): [True: 0, False: 6]
  ------------------
 4266|      0|      HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 4267|      0|                       af->getlinenum());
 4268|      0|      return false;
 4269|      0|    }
 4270|      6|  }
 4271|      2|  return true;
 4272|      2|}
_ZN8AffixMgr16parse_breaktableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgr:
 4275|      4|bool AffixMgr::parse_breaktable(const std::string& line, FileMgr* af) {
 4276|      4|  if (parsedbreaktable) {
  ------------------
  |  Branch (4276:7): [True: 0, False: 4]
  ------------------
 4277|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
 4278|      0|                     af->getlinenum());
 4279|      0|    return false;
 4280|      0|  }
 4281|      4|  parsedbreaktable = true;
 4282|      4|  int numbreak = -1;
 4283|      4|  int i = 0;
 4284|      4|  int np = 0;
 4285|      4|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 4286|     12|  while (start_piece != line.end()) {
  ------------------
  |  Branch (4286:10): [True: 8, False: 4]
  ------------------
 4287|      8|    switch (i) {
 4288|      4|      case 0: {
  ------------------
  |  Branch (4288:7): [True: 4, False: 4]
  ------------------
 4289|      4|        np++;
 4290|      4|        break;
 4291|      0|      }
 4292|      4|      case 1: {
  ------------------
  |  Branch (4292:7): [True: 4, False: 4]
  ------------------
 4293|      4|        numbreak = atoi(std::string(start_piece, iter).c_str());
 4294|      4|        if (numbreak < 0) {
  ------------------
  |  Branch (4294:13): [True: 0, False: 4]
  ------------------
 4295|      0|          HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
 4296|      0|                           af->getlinenum());
 4297|      0|          return false;
 4298|      0|        }
 4299|      4|        if (numbreak == 0)
  ------------------
  |  Branch (4299:13): [True: 0, False: 4]
  ------------------
 4300|      0|          return true;
 4301|      4|        breaktable.reserve(std::min(numbreak, 16384));
 4302|      4|        np++;
 4303|      4|        break;
 4304|      4|      }
 4305|      0|      default:
  ------------------
  |  Branch (4305:7): [True: 0, False: 8]
  ------------------
 4306|      0|        break;
 4307|      8|    }
 4308|      8|    ++i;
 4309|      8|    start_piece = mystrsep(line, iter);
 4310|      8|  }
 4311|      4|  if (np != 2) {
  ------------------
  |  Branch (4311:7): [True: 0, False: 4]
  ------------------
 4312|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
 4313|      0|                     af->getlinenum());
 4314|      0|    return false;
 4315|      0|  }
 4316|       |
 4317|       |  /* now parse the numbreak lines to read in the remainder of the table */
 4318|     10|  for (int j = 0; j < numbreak; ++j) {
  ------------------
  |  Branch (4318:19): [True: 6, False: 4]
  ------------------
 4319|      6|    std::string nl;
 4320|      6|    if (!af->getline(nl))
  ------------------
  |  Branch (4320:9): [True: 0, False: 6]
  ------------------
 4321|      0|      return false;
 4322|      6|    mychomp(nl);
 4323|      6|    i = 0;
 4324|      6|    iter = nl.begin();
 4325|      6|    start_piece = mystrsep(nl, iter);
 4326|     18|    while (start_piece != nl.end()) {
  ------------------
  |  Branch (4326:12): [True: 12, False: 6]
  ------------------
 4327|     12|      switch (i) {
 4328|      6|        case 0: {
  ------------------
  |  Branch (4328:9): [True: 6, False: 6]
  ------------------
 4329|      6|          if (nl.compare(start_piece - nl.begin(), 5, "BREAK", 5) != 0) {
  ------------------
  |  Branch (4329:15): [True: 0, False: 6]
  ------------------
 4330|      0|            HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 4331|      0|                             af->getlinenum());
 4332|      0|            numbreak = 0;
 4333|      0|            return false;
 4334|      0|          }
 4335|      6|          break;
 4336|      6|        }
 4337|      6|        case 1: {
  ------------------
  |  Branch (4337:9): [True: 6, False: 6]
  ------------------
 4338|      6|          breaktable.emplace_back(start_piece, iter);
 4339|      6|          break;
 4340|      6|        }
 4341|      0|        default:
  ------------------
  |  Branch (4341:9): [True: 0, False: 12]
  ------------------
 4342|      0|          break;
 4343|     12|      }
 4344|     12|      ++i;
 4345|     12|      start_piece = mystrsep(nl, iter);
 4346|     12|    }
 4347|      6|  }
 4348|       |
 4349|      4|  if (breaktable.size() != static_cast<size_t>(numbreak)) {
  ------------------
  |  Branch (4349:7): [True: 0, False: 4]
  ------------------
 4350|      0|    HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 4351|      0|                     af->getlinenum());
 4352|      0|    return false;
 4353|      0|  }
 4354|       |
 4355|      4|  return true;
 4356|      4|}
_ZN8AffixMgr17reverse_conditionERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 4358|     38|void AffixMgr::reverse_condition(std::string& piece) {
 4359|     38|  if (piece.empty())
  ------------------
  |  Branch (4359:7): [True: 0, False: 38]
  ------------------
 4360|      0|      return;
 4361|       |
 4362|     38|  int neg = 0;
 4363|       |  // iterate backwards; k wraps to npos (SIZE_MAX) when decremented past 0
 4364|     92|  for (size_t k = piece.size() - 1; k != std::string::npos; --k) {
  ------------------
  |  Branch (4364:37): [True: 54, False: 38]
  ------------------
 4365|     54|    switch (piece[k]) {
 4366|      2|      case '[': {
  ------------------
  |  Branch (4366:7): [True: 2, False: 52]
  ------------------
 4367|      2|        if (neg)
  ------------------
  |  Branch (4367:13): [True: 0, False: 2]
  ------------------
 4368|      0|          piece[k + 1] = '[';
 4369|      2|        else
 4370|      2|          piece[k] = ']';
 4371|      2|        break;
 4372|      0|      }
 4373|      2|      case ']': {
  ------------------
  |  Branch (4373:7): [True: 2, False: 52]
  ------------------
 4374|      2|        piece[k] = '[';
 4375|      2|        if (neg)
  ------------------
  |  Branch (4375:13): [True: 0, False: 2]
  ------------------
 4376|      0|          piece[k + 1] = '^';
 4377|      2|        neg = 0;
 4378|      2|        break;
 4379|      0|      }
 4380|      0|      case '^': {
  ------------------
  |  Branch (4380:7): [True: 0, False: 54]
  ------------------
 4381|      0|        if (piece[k + 1] == ']')
  ------------------
  |  Branch (4381:13): [True: 0, False: 0]
  ------------------
 4382|      0|          neg = 1;
 4383|      0|        else if (neg)
  ------------------
  |  Branch (4383:18): [True: 0, False: 0]
  ------------------
 4384|      0|          piece[k + 1] = piece[k];
 4385|      0|        break;
 4386|      0|      }
 4387|     50|      default: {
  ------------------
  |  Branch (4387:7): [True: 50, False: 4]
  ------------------
 4388|     50|        if (neg)
  ------------------
  |  Branch (4388:13): [True: 0, False: 50]
  ------------------
 4389|      0|          piece[k + 1] = piece[k];
 4390|     50|      }
 4391|     54|    }
 4392|     54|  }
 4393|     38|}
_ZN8AffixMgr11parse_affixERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEcP7FileMgrPc:
 4447|     26|                          char* dupflags) {
 4448|     26|  int numents = 0;  // number of AffEntry structures to parse
 4449|       |
 4450|     26|  unsigned short aflag = 0;  // affix char identifier
 4451|       |
 4452|     26|  char ff = 0;
 4453|     26|  entries_container affentries(at, this);
 4454|       |
 4455|     26|  int i = 0;
 4456|       |
 4457|       |// checking lines with bad syntax
 4458|       |#ifdef DEBUG
 4459|       |  int basefieldnum = 0;
 4460|       |#endif
 4461|       |
 4462|       |  // split affix header line into pieces
 4463|       |
 4464|     26|  int np = 0;
 4465|     26|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 4466|    130|  while (start_piece != line.end()) {
  ------------------
  |  Branch (4466:10): [True: 104, False: 26]
  ------------------
 4467|    104|    switch (i) {
 4468|       |      // piece 1 - is type of affix
 4469|     26|      case 0: {
  ------------------
  |  Branch (4469:7): [True: 26, False: 78]
  ------------------
 4470|     26|        np++;
 4471|     26|        break;
 4472|      0|      }
 4473|       |
 4474|       |      // piece 2 - is affix char
 4475|     26|      case 1: {
  ------------------
  |  Branch (4475:7): [True: 26, False: 78]
  ------------------
 4476|     26|        np++;
 4477|     26|        aflag = pHMgr->decode_flag(std::string(start_piece, iter));
 4478|     26|        if (((at == 'S') && (dupflags[aflag] & dupSFX)) ||
  ------------------
  |  |   88|     18|#define dupSFX (1 << 0)
  ------------------
  |  Branch (4478:14): [True: 18, False: 8]
  |  Branch (4478:29): [True: 0, False: 18]
  ------------------
 4479|     26|            ((at == 'P') && (dupflags[aflag] & dupPFX))) {
  ------------------
  |  |   89|      8|#define dupPFX (1 << 1)
  ------------------
  |  Branch (4479:14): [True: 8, False: 18]
  |  Branch (4479:29): [True: 0, False: 8]
  ------------------
 4480|      0|          HUNSPELL_WARNING(
 4481|      0|              stderr,
 4482|      0|              "error: line %d: multiple definitions of an affix flag\n",
 4483|      0|              af->getlinenum());
 4484|      0|        }
 4485|     26|        dupflags[aflag] += (char)((at == 'S') ? dupSFX : dupPFX);
  ------------------
  |  |   88|     18|#define dupSFX (1 << 0)
  ------------------
                      dupflags[aflag] += (char)((at == 'S') ? dupSFX : dupPFX);
  ------------------
  |  |   89|      8|#define dupPFX (1 << 1)
  ------------------
  |  Branch (4485:35): [True: 18, False: 8]
  ------------------
 4486|     26|        break;
 4487|      0|      }
 4488|       |      // piece 3 - is cross product indicator
 4489|     26|      case 2: {
  ------------------
  |  Branch (4489:7): [True: 26, False: 78]
  ------------------
 4490|     26|        np++;
 4491|     26|        if (*start_piece == 'Y')
  ------------------
  |  Branch (4491:13): [True: 26, False: 0]
  ------------------
 4492|     26|          ff = aeXPRODUCT;
  ------------------
  |  |   65|     26|#define aeXPRODUCT (1 << 0)
  ------------------
 4493|     26|        break;
 4494|      0|      }
 4495|       |
 4496|       |      // piece 4 - is number of affentries
 4497|     26|      case 3: {
  ------------------
  |  Branch (4497:7): [True: 26, False: 78]
  ------------------
 4498|     26|        np++;
 4499|     26|        numents = atoi(std::string(start_piece, iter).c_str());
 4500|     26|        if ((numents <= 0) || ((std::numeric_limits<size_t>::max() /
  ------------------
  |  Branch (4500:13): [True: 0, False: 26]
  |  Branch (4500:31): [True: 0, False: 26]
  ------------------
 4501|     26|                                sizeof(AffEntry)) < static_cast<size_t>(numents))) {
 4502|      0|          std::string err = pHMgr->encode_flag(aflag);
 4503|      0|          HUNSPELL_WARNING(stderr, "error: line %d: affix %s: bad entry number\n",
 4504|      0|                           af->getlinenum(), err.c_str());
 4505|      0|          return false;
 4506|      0|        }
 4507|       |
 4508|     26|        char opts = ff;
 4509|     26|        if (utf8)
  ------------------
  |  Branch (4509:13): [True: 6, False: 20]
  ------------------
 4510|      6|          opts |= aeUTF8;
  ------------------
  |  |   66|      6|#define aeUTF8 (1 << 1)
  ------------------
 4511|     26|        if (pHMgr->is_aliasf())
  ------------------
  |  Branch (4511:13): [True: 4, False: 22]
  ------------------
 4512|      4|          opts |= aeALIASF;
  ------------------
  |  |   67|      4|#define aeALIASF (1 << 2)
  ------------------
 4513|     26|        if (pHMgr->is_aliasm())
  ------------------
  |  Branch (4513:13): [True: 0, False: 26]
  ------------------
 4514|      0|          opts |= aeALIASM;
  ------------------
  |  |   68|      0|#define aeALIASM (1 << 3)
  ------------------
 4515|     26|        affentries.initialize(numents, opts, aflag);
 4516|     26|      }
 4517|       |
 4518|     26|      default:
  ------------------
  |  Branch (4518:7): [True: 0, False: 104]
  ------------------
 4519|     26|        break;
 4520|    104|    }
 4521|    104|    ++i;
 4522|    104|    start_piece = mystrsep(line, iter);
 4523|    104|  }
 4524|       |  // check to make sure we parsed enough pieces
 4525|     26|  if (np != 4) {
  ------------------
  |  Branch (4525:7): [True: 0, False: 26]
  ------------------
 4526|      0|    std::string err = pHMgr->encode_flag(aflag);
 4527|      0|    HUNSPELL_WARNING(stderr, "error: line %d: affix %s: missing data\n",
 4528|      0|                     af->getlinenum(), err.c_str());
 4529|      0|    return false;
 4530|      0|  }
 4531|       |
 4532|       |  // now parse numents affentries for this affix
 4533|     26|  AffEntry* entry = affentries.first_entry();
 4534|     68|  for (int ent = 0; ent < numents; ++ent) {
  ------------------
  |  Branch (4534:21): [True: 42, False: 26]
  ------------------
 4535|     42|    std::string nl;
 4536|     42|    if (!af->getline(nl))
  ------------------
  |  Branch (4536:9): [True: 0, False: 42]
  ------------------
 4537|      0|      return false;
 4538|     42|    mychomp(nl);
 4539|       |
 4540|     42|    iter = nl.begin();
 4541|     42|    i = 0;
 4542|     42|    np = 0;
 4543|       |
 4544|       |    // split line into pieces
 4545|     42|    start_piece = mystrsep(nl, iter);
 4546|    258|    while (start_piece != nl.end()) {
  ------------------
  |  Branch (4546:12): [True: 216, False: 42]
  ------------------
 4547|    216|      switch (i) {
 4548|       |        // piece 1 - is type
 4549|     42|        case 0: {
  ------------------
  |  Branch (4549:9): [True: 42, False: 174]
  ------------------
 4550|     42|          np++;
 4551|     42|          if (ent != 0)
  ------------------
  |  Branch (4551:15): [True: 16, False: 26]
  ------------------
 4552|     16|            entry = affentries.add_entry((char)(aeXPRODUCT | aeUTF8 | aeALIASF | aeALIASM));
  ------------------
  |  |   65|     16|#define aeXPRODUCT (1 << 0)
  ------------------
                          entry = affentries.add_entry((char)(aeXPRODUCT | aeUTF8 | aeALIASF | aeALIASM));
  ------------------
  |  |   66|     16|#define aeUTF8 (1 << 1)
  ------------------
                          entry = affentries.add_entry((char)(aeXPRODUCT | aeUTF8 | aeALIASF | aeALIASM));
  ------------------
  |  |   67|     16|#define aeALIASF (1 << 2)
  ------------------
                          entry = affentries.add_entry((char)(aeXPRODUCT | aeUTF8 | aeALIASF | aeALIASM));
  ------------------
  |  |   68|     16|#define aeALIASM (1 << 3)
  ------------------
 4553|     42|          break;
 4554|      0|        }
 4555|       |
 4556|       |        // piece 2 - is affix char
 4557|     42|        case 1: {
  ------------------
  |  Branch (4557:9): [True: 42, False: 174]
  ------------------
 4558|     42|          np++;
 4559|     42|          std::string chunk(start_piece, iter);
 4560|     42|          if (pHMgr->decode_flag(chunk) != aflag) {
  ------------------
  |  Branch (4560:15): [True: 0, False: 42]
  ------------------
 4561|      0|            std::string err = pHMgr->encode_flag(aflag);
 4562|      0|            HUNSPELL_WARNING(stderr,
 4563|      0|                             "error: line %d: affix %s is corrupt\n",
 4564|      0|                             af->getlinenum(), err.c_str());
 4565|      0|            return false;
 4566|      0|          }
 4567|       |
 4568|     42|          if (ent != 0) {
  ------------------
  |  Branch (4568:15): [True: 16, False: 26]
  ------------------
 4569|     16|            AffEntry* start_entry = affentries.first_entry();
 4570|     16|            entry->aflag = start_entry->aflag;
 4571|     16|          }
 4572|     42|          break;
 4573|     42|        }
 4574|       |
 4575|       |        // piece 3 - is string to strip or 0 for null
 4576|     42|        case 2: {
  ------------------
  |  Branch (4576:9): [True: 42, False: 174]
  ------------------
 4577|     42|          np++;
 4578|     42|          entry->strip = std::string(start_piece, iter);
 4579|     42|          if (complexprefixes) {
  ------------------
  |  Branch (4579:15): [True: 4, False: 38]
  ------------------
 4580|      4|            if (utf8)
  ------------------
  |  Branch (4580:17): [True: 0, False: 4]
  ------------------
 4581|      0|              reverseword_utf(entry->strip);
 4582|      4|            else
 4583|      4|              reverseword(entry->strip);
 4584|      4|          }
 4585|     42|          if (entry->strip.compare("0") == 0) {
  ------------------
  |  Branch (4585:15): [True: 36, False: 6]
  ------------------
 4586|     36|            entry->strip.clear();
 4587|     36|          }
 4588|     42|          break;
 4589|     42|        }
 4590|       |
 4591|       |        // piece 4 - is affix string or 0 for null
 4592|     42|        case 3: {
  ------------------
  |  Branch (4592:9): [True: 42, False: 174]
  ------------------
 4593|     42|          entry->morphcode = nullptr;
 4594|     42|          entry->contclass = nullptr;
 4595|     42|          entry->contclasslen = 0;
 4596|     42|          np++;
 4597|     42|          std::string::const_iterator dash = std::find(start_piece, iter, '/');
 4598|     42|          if (dash != iter) {
  ------------------
  |  Branch (4598:15): [True: 18, False: 24]
  ------------------
 4599|     18|            entry->appnd = std::string(start_piece, dash);
 4600|     18|            std::string dash_str(dash + 1, iter);
 4601|       |
 4602|     18|            if (!ignorechars.empty() && !has_no_ignored_chars(entry->appnd, ignorechars)) {
  ------------------
  |  Branch (4602:17): [True: 2, False: 16]
  |  Branch (4602:41): [True: 0, False: 2]
  ------------------
 4603|      0|              if (utf8) {
  ------------------
  |  Branch (4603:19): [True: 0, False: 0]
  ------------------
 4604|      0|                remove_ignored_chars_utf(entry->appnd, ignorechars_utf16);
 4605|      0|              } else {
 4606|      0|                remove_ignored_chars(entry->appnd, ignorechars);
 4607|      0|              }
 4608|      0|            }
 4609|       |
 4610|     18|            if (complexprefixes) {
  ------------------
  |  Branch (4610:17): [True: 2, False: 16]
  ------------------
 4611|      2|              if (utf8)
  ------------------
  |  Branch (4611:19): [True: 0, False: 2]
  ------------------
 4612|      0|                reverseword_utf(entry->appnd);
 4613|      2|              else
 4614|      2|                reverseword(entry->appnd);
 4615|      2|            }
 4616|       |
 4617|     18|            if (pHMgr->is_aliasf()) {
  ------------------
  |  Branch (4617:17): [True: 2, False: 16]
  ------------------
 4618|      2|              int index = atoi(dash_str.c_str());
 4619|      2|              entry->contclasslen = (unsigned short)pHMgr->get_aliasf(
 4620|      2|                  index, &(entry->contclass), af);
 4621|      2|              if (!entry->contclasslen)
  ------------------
  |  Branch (4621:19): [True: 0, False: 2]
  ------------------
 4622|      0|                HUNSPELL_WARNING(stderr,
 4623|      0|                                 "error: bad affix flag alias: \"%s\"\n",
 4624|      0|                                 dash_str.c_str());
 4625|     16|            } else {
 4626|     16|              entry->contclasslen = (unsigned short)pHMgr->decode_flags(
 4627|     16|                  &(entry->contclass), dash_str, af);
 4628|     16|              std::sort(entry->contclass, entry->contclass + entry->contclasslen);
 4629|     16|            }
 4630|       |
 4631|     18|            havecontclass = 1;
 4632|     44|            for (unsigned short _i = 0; _i < entry->contclasslen; _i++) {
  ------------------
  |  Branch (4632:41): [True: 26, False: 18]
  ------------------
 4633|     26|              contclasses[(entry->contclass)[_i]] = 1;
 4634|     26|            }
 4635|     24|          } else {
 4636|     24|            entry->appnd = std::string(start_piece, iter);
 4637|       |
 4638|     24|            if (!ignorechars.empty() && !has_no_ignored_chars(entry->appnd, ignorechars)) {
  ------------------
  |  Branch (4638:17): [True: 2, False: 22]
  |  Branch (4638:41): [True: 2, False: 0]
  ------------------
 4639|      2|              if (utf8) {
  ------------------
  |  Branch (4639:19): [True: 0, False: 2]
  ------------------
 4640|      0|                remove_ignored_chars_utf(entry->appnd, ignorechars_utf16);
 4641|      2|              } else {
 4642|      2|                remove_ignored_chars(entry->appnd, ignorechars);
 4643|      2|              }
 4644|      2|            }
 4645|       |
 4646|     24|            if (complexprefixes) {
  ------------------
  |  Branch (4646:17): [True: 2, False: 22]
  ------------------
 4647|      2|              if (utf8)
  ------------------
  |  Branch (4647:19): [True: 0, False: 2]
  ------------------
 4648|      0|                reverseword_utf(entry->appnd);
 4649|      2|              else
 4650|      2|                reverseword(entry->appnd);
 4651|      2|            }
 4652|     24|          }
 4653|       |
 4654|     42|          if (entry->appnd.compare("0") == 0) {
  ------------------
  |  Branch (4654:15): [True: 2, False: 40]
  ------------------
 4655|      2|            entry->appnd.clear();
 4656|      2|          }
 4657|     42|          break;
 4658|     42|        }
 4659|       |
 4660|       |        // piece 5 - is the conditions descriptions
 4661|     42|        case 4: {
  ------------------
  |  Branch (4661:9): [True: 42, False: 174]
  ------------------
 4662|     42|          std::string chunk(start_piece, iter);
 4663|     42|          np++;
 4664|     42|          if (complexprefixes) {
  ------------------
  |  Branch (4664:15): [True: 4, False: 38]
  ------------------
 4665|      4|            if (utf8)
  ------------------
  |  Branch (4665:17): [True: 0, False: 4]
  ------------------
 4666|      0|              reverseword_utf(chunk);
 4667|      4|            else
 4668|      4|              reverseword(chunk);
 4669|      4|            reverse_condition(chunk);
 4670|      4|          }
 4671|     42|          if (!entry->strip.empty() && chunk != "." &&
  ------------------
  |  Branch (4671:15): [True: 6, False: 36]
  |  Branch (4671:40): [True: 6, False: 0]
  ------------------
 4672|      6|              redundant_condition(at, entry->strip, chunk,
  ------------------
  |  Branch (4672:15): [True: 6, False: 0]
  ------------------
 4673|      6|                                  af->getlinenum()))
 4674|      6|            chunk = ".";
 4675|     42|          if (at == 'S') {
  ------------------
  |  Branch (4675:15): [True: 34, False: 8]
  ------------------
 4676|     34|            reverseword(chunk);
 4677|     34|            reverse_condition(chunk);
 4678|     34|          }
 4679|     42|          if (encodeit(*entry, chunk))
  ------------------
  |  Branch (4679:15): [True: 0, False: 42]
  ------------------
 4680|      0|            return false;
 4681|     42|          break;
 4682|     42|        }
 4683|       |
 4684|     42|        case 5: {
  ------------------
  |  Branch (4684:9): [True: 6, False: 210]
  ------------------
 4685|      6|          std::string chunk(start_piece, iter);
 4686|      6|          np++;
 4687|      6|          if (pHMgr->is_aliasm()) {
  ------------------
  |  Branch (4687:15): [True: 0, False: 6]
  ------------------
 4688|      0|            int index = atoi(chunk.c_str());
 4689|      0|            entry->morphcode = pHMgr->get_aliasm(index);
 4690|      6|          } else {
 4691|      6|            if (complexprefixes) {  // XXX - fix me for morph. gen.
  ------------------
  |  Branch (4691:17): [True: 0, False: 6]
  ------------------
 4692|      0|              if (utf8)
  ------------------
  |  Branch (4692:19): [True: 0, False: 0]
  ------------------
 4693|      0|                reverseword_utf(chunk);
 4694|      0|              else
 4695|      0|                reverseword(chunk);
 4696|      0|            }
 4697|       |            // add the remaining of the line
 4698|      6|            std::string::const_iterator end = nl.end();
 4699|      6|            if (iter != end) {
  ------------------
  |  Branch (4699:17): [True: 0, False: 6]
  ------------------
 4700|      0|              chunk.append(iter, end);
 4701|      0|            }
 4702|      6|            entry->morphcode = mystrdup(chunk.c_str());
 4703|      6|          }
 4704|      6|          break;
 4705|     42|        }
 4706|      0|        default:
  ------------------
  |  Branch (4706:9): [True: 0, False: 216]
  ------------------
 4707|      0|          break;
 4708|    216|      }
 4709|    216|      i++;
 4710|    216|      start_piece = mystrsep(nl, iter);
 4711|    216|    }
 4712|       |    // check to make sure we parsed enough pieces
 4713|     42|    if (np < 4) {
  ------------------
  |  Branch (4713:9): [True: 0, False: 42]
  ------------------
 4714|      0|      std::string err = pHMgr->encode_flag(aflag);
 4715|      0|      HUNSPELL_WARNING(stderr, "error: line %d: affix %s is corrupt\n",
 4716|      0|                       af->getlinenum(), err.c_str());
 4717|      0|      return false;
 4718|      0|    }
 4719|       |
 4720|       |#ifdef DEBUG
 4721|       |    // detect unnecessary fields, excepting comments
 4722|       |    if (basefieldnum) {
 4723|       |      int fieldnum =
 4724|       |          !(entry->morphcode) ? 5 : ((*(entry->morphcode) == '#') ? 5 : 6);
 4725|       |      if (fieldnum != basefieldnum)
 4726|       |        HUNSPELL_WARNING(stderr, "warning: line %d: bad field number\n",
 4727|       |                         af->getlinenum());
 4728|       |    } else {
 4729|       |      basefieldnum =
 4730|       |          !(entry->morphcode) ? 5 : ((*(entry->morphcode) == '#') ? 5 : 6);
 4731|       |    }
 4732|       |#endif
 4733|     42|  }
 4734|       |
 4735|       |  // now create SfxEntry or PfxEntry objects and use links to
 4736|       |  // build an ordered (sorted by affix string) list
 4737|     26|  auto start = affentries.begin(), end = affentries.end();
 4738|     68|  for (auto affentry = start; affentry != end; ++affentry) {
  ------------------
  |  Branch (4738:31): [True: 42, False: 26]
  ------------------
 4739|     42|    if (at == 'P') {
  ------------------
  |  Branch (4739:9): [True: 8, False: 34]
  ------------------
 4740|      8|      build_pfxtree(dynamic_cast<PfxEntry*>(*affentry));
 4741|     34|    } else {
 4742|     34|      build_sfxtree(dynamic_cast<SfxEntry*>(*affentry));
 4743|     34|    }
 4744|     42|  }
 4745|       |
 4746|       |  //contents belong to AffixMgr now
 4747|     26|  affentries.release();
 4748|       |
 4749|     26|  return true;
 4750|     26|}
_ZN8AffixMgr19redundant_conditionEcRKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_i:
 4755|      6|                                  int linenum) {
 4756|      6|  int stripl = strip.size(), condl = cond.size(), i, j, neg, in;
 4757|      6|  if (ft == 'P') {  // prefix
  ------------------
  |  Branch (4757:7): [True: 0, False: 6]
  ------------------
 4758|      0|    if (strip.compare(0, condl, cond) == 0)
  ------------------
  |  Branch (4758:9): [True: 0, False: 0]
  ------------------
 4759|      0|      return 1;
 4760|      0|    if (utf8) {
  ------------------
  |  Branch (4760:9): [True: 0, False: 0]
  ------------------
 4761|      0|    } else {
 4762|      0|      for (i = 0, j = 0; (i < stripl) && (j < condl); i++, j++) {
  ------------------
  |  Branch (4762:26): [True: 0, False: 0]
  |  Branch (4762:42): [True: 0, False: 0]
  ------------------
 4763|      0|        if (cond[j] != '[') {
  ------------------
  |  Branch (4763:13): [True: 0, False: 0]
  ------------------
 4764|      0|          if (cond[j] != strip[i]) {
  ------------------
  |  Branch (4764:15): [True: 0, False: 0]
  ------------------
 4765|      0|            HUNSPELL_WARNING(stderr,
 4766|      0|                             "warning: line %d: incompatible stripping "
 4767|      0|                             "characters and condition\n",
 4768|      0|                             linenum);
 4769|      0|            return 0;
 4770|      0|          }
 4771|      0|        } else {
 4772|      0|          neg = (cond[j + 1] == '^') ? 1 : 0;
  ------------------
  |  Branch (4772:17): [True: 0, False: 0]
  ------------------
 4773|      0|          in = 0;
 4774|      0|          do {
 4775|      0|            j++;
 4776|      0|            if (strip[i] == cond[j])
  ------------------
  |  Branch (4776:17): [True: 0, False: 0]
  ------------------
 4777|      0|              in = 1;
 4778|      0|          } while ((j < (condl - 1)) && (cond[j] != ']'));
  ------------------
  |  Branch (4778:20): [True: 0, False: 0]
  |  Branch (4778:41): [True: 0, False: 0]
  ------------------
 4779|      0|          if (j == (condl - 1) && (cond[j] != ']')) {
  ------------------
  |  Branch (4779:15): [True: 0, False: 0]
  |  Branch (4779:35): [True: 0, False: 0]
  ------------------
 4780|      0|            HUNSPELL_WARNING(stderr,
 4781|      0|                             "error: line %d: missing ] in condition:\n%s\n",
 4782|      0|                             linenum, cond.c_str());
 4783|      0|            return 0;
 4784|      0|          }
 4785|      0|          if ((!neg && !in) || (neg && in)) {
  ------------------
  |  Branch (4785:16): [True: 0, False: 0]
  |  Branch (4785:24): [True: 0, False: 0]
  |  Branch (4785:33): [True: 0, False: 0]
  |  Branch (4785:40): [True: 0, False: 0]
  ------------------
 4786|      0|            HUNSPELL_WARNING(stderr,
 4787|      0|                             "warning: line %d: incompatible stripping "
 4788|      0|                             "characters and condition\n",
 4789|      0|                             linenum);
 4790|      0|            return 0;
 4791|      0|          }
 4792|      0|        }
 4793|      0|      }
 4794|      0|      if (j >= condl)
  ------------------
  |  Branch (4794:11): [True: 0, False: 0]
  ------------------
 4795|      0|        return 1;
 4796|      0|    }
 4797|      6|  } else {  // suffix
 4798|      6|    if ((stripl >= condl) && strip.compare(stripl - condl, std::string::npos, cond) == 0)
  ------------------
  |  Branch (4798:9): [True: 6, False: 0]
  |  Branch (4798:30): [True: 6, False: 0]
  ------------------
 4799|      6|      return 1;
 4800|      0|    if (utf8) {
  ------------------
  |  Branch (4800:9): [True: 0, False: 0]
  ------------------
 4801|      0|    } else {
 4802|      0|      for (i = stripl - 1, j = condl - 1; (i >= 0) && (j >= 0); i--, j--) {
  ------------------
  |  Branch (4802:43): [True: 0, False: 0]
  |  Branch (4802:55): [True: 0, False: 0]
  ------------------
 4803|      0|        if (cond[j] != ']') {
  ------------------
  |  Branch (4803:13): [True: 0, False: 0]
  ------------------
 4804|      0|          if (cond[j] != strip[i]) {
  ------------------
  |  Branch (4804:15): [True: 0, False: 0]
  ------------------
 4805|      0|            HUNSPELL_WARNING(stderr,
 4806|      0|                             "warning: line %d: incompatible stripping "
 4807|      0|                             "characters and condition\n",
 4808|      0|                             linenum);
 4809|      0|            return 0;
 4810|      0|          }
 4811|      0|        } else if (j > 0) {
  ------------------
  |  Branch (4811:20): [True: 0, False: 0]
  ------------------
 4812|      0|          in = 0;
 4813|      0|          do {
 4814|      0|            j--;
 4815|      0|            if (strip[i] == cond[j])
  ------------------
  |  Branch (4815:17): [True: 0, False: 0]
  ------------------
 4816|      0|              in = 1;
 4817|      0|          } while ((j > 0) && (cond[j] != '['));
  ------------------
  |  Branch (4817:20): [True: 0, False: 0]
  |  Branch (4817:31): [True: 0, False: 0]
  ------------------
 4818|      0|          if ((j == 0) && (cond[j] != '[')) {
  ------------------
  |  Branch (4818:15): [True: 0, False: 0]
  |  Branch (4818:27): [True: 0, False: 0]
  ------------------
 4819|      0|            HUNSPELL_WARNING(stderr,
 4820|      0|                             "error: line: %d: missing ] in condition:\n%s\n",
 4821|      0|                             linenum, cond.c_str());
 4822|      0|            return 0;
 4823|      0|          }
 4824|      0|          neg = (cond[j + 1] == '^') ? 1 : 0;
  ------------------
  |  Branch (4824:17): [True: 0, False: 0]
  ------------------
 4825|      0|          if ((!neg && !in) || (neg && in)) {
  ------------------
  |  Branch (4825:16): [True: 0, False: 0]
  |  Branch (4825:24): [True: 0, False: 0]
  |  Branch (4825:33): [True: 0, False: 0]
  |  Branch (4825:40): [True: 0, False: 0]
  ------------------
 4826|      0|            HUNSPELL_WARNING(stderr,
 4827|      0|                             "warning: line %d: incompatible stripping "
 4828|      0|                             "characters and condition\n",
 4829|      0|                             linenum);
 4830|      0|            return 0;
 4831|      0|          }
 4832|      0|        }
 4833|      0|      }
 4834|      0|      if (j < 0)
  ------------------
  |  Branch (4834:11): [True: 0, False: 0]
  ------------------
 4835|      0|        return 1;
 4836|      0|    }
 4837|      0|  }
 4838|      0|  return 0;
 4839|      6|}
_ZN8AffixMgr8isSubsetEPKcS1_:
 1069|  75.8k|inline int AffixMgr::isSubset(const char* s1, const char* s2) {
 1070|   102k|  while (((*s1 == *s2) || (*s1 == '.')) && (*s1 != '\0') && (*s2 != '\0')) {
  ------------------
  |  Branch (1070:11): [True: 76.0k, False: 26.1k]
  |  Branch (1070:27): [True: 0, False: 26.1k]
  |  Branch (1070:44): [True: 26.2k, False: 49.7k]
  |  Branch (1070:61): [True: 26.2k, False: 0]
  ------------------
 1071|  26.2k|    s1++;
 1072|  26.2k|    s2++;
 1073|  26.2k|  }
 1074|  75.8k|  return (*s1 == '\0');
 1075|  75.8k|}
_ZN8AffixMgr11isRevSubsetEPKcS1_i:
 2711|   397k|                                 int len) {
 2712|   796k|  while ((len > 0) && (*s1 != '\0') && ((*s1 == *end_of_s2) || (*s1 == '.'))) {
  ------------------
  |  Branch (2712:10): [True: 793k, False: 2.64k]
  |  Branch (2712:23): [True: 449k, False: 344k]
  |  Branch (2712:41): [True: 398k, False: 50.6k]
  |  Branch (2712:64): [True: 0, False: 50.6k]
  ------------------
 2713|   398k|    s1++;
 2714|   398k|    end_of_s2--;
 2715|   398k|    len--;
 2716|   398k|  }
 2717|   397k|  return (*s1 == '\0');
 2718|   397k|}
affixmgr.cxx:_ZN12_GLOBAL__N_18mystrdupEPKc:
 3360|   583k|  char* mystrdup(const char* s) {
 3361|   583k|    char* d = nullptr;
 3362|   583k|    if (s) {
  ------------------
  |  Branch (3362:9): [True: 583k, False: 0]
  ------------------
 3363|   583k|      size_t sl = strlen(s) + 1;
 3364|   583k|      d = new char[sl];
 3365|   583k|      memcpy(d, s, sl);
 3366|   583k|    }
 3367|   583k|    return d;
 3368|   583k|  }
_ZN17entries_containerC2EcP8AffixMgr:
 4401|     26|    : m_mgr(mgr)
 4402|     26|    , m_at(at) {
 4403|     26|  }
_ZN17entries_container10initializeEict:
 4408|     26|                  char opts, unsigned short aflag) {
 4409|     26|    entries.reserve(std::min(numents, 16384));
 4410|       |
 4411|     26|    if (m_at == 'P') {
  ------------------
  |  Branch (4411:9): [True: 8, False: 18]
  ------------------
 4412|      8|      entries.push_back(new PfxEntry(m_mgr));
 4413|     18|    } else {
 4414|     18|      entries.push_back(new SfxEntry(m_mgr));
 4415|     18|    }
 4416|       |
 4417|     26|    entries.back()->opts = opts;
 4418|     26|    entries.back()->aflag = aflag;
 4419|     26|  }
_ZN17entries_container11first_entryEv:
 4432|     42|  AffEntry* first_entry() { return entries.empty() ? nullptr : entries[0]; }
  ------------------
  |  Branch (4432:36): [True: 0, False: 42]
  ------------------
_ZN17entries_container9add_entryEc:
 4421|     16|  AffEntry* add_entry(char opts) {
 4422|     16|    if (m_at == 'P') {
  ------------------
  |  Branch (4422:9): [True: 0, False: 16]
  ------------------
 4423|      0|      entries.push_back(new PfxEntry(m_mgr));
 4424|     16|    } else {
 4425|     16|      entries.push_back(new SfxEntry(m_mgr));
 4426|     16|    }
 4427|     16|    AffEntry* ret = entries.back();
 4428|     16|    ret->opts = entries[0]->opts & opts;
 4429|     16|    return ret;
 4430|     16|  }
_ZN17entries_container5beginEv:
 4440|     26|  std::vector<AffEntry*>::iterator begin() { return entries.begin(); }
_ZN17entries_container3endEv:
 4441|     26|  std::vector<AffEntry*>::iterator end() { return entries.end(); }
_ZN17entries_container7releaseEv:
 4404|     26|  void release() {
 4405|     26|    entries.clear();
 4406|     26|  }
_ZN17entries_containerD2Ev:
 4434|     26|  ~entries_container() {
 4435|     26|    for (auto& entry : entries) {
  ------------------
  |  Branch (4435:22): [True: 0, False: 26]
  ------------------
 4436|      0|      delete entry;
 4437|      0|    }
 4438|     26|  }
affixmgr.cxx:_ZZN8AffixMgr12get_syllableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEENK3$_1clE6w_char:
 1568|  1.77k|          [&](w_char wc) {
 1569|  1.77k|            return std::binary_search(cpdvowels_utf16.begin(), cpdvowels_utf16.end(), wc);
 1570|  1.77k|          });

_ZN9guesswordC2Ev:
  115|  4.61M|    : word(nullptr)
  116|  4.61M|    , allow(false)
  117|  4.61M|    , orig(nullptr)
  118|  4.61M|  {
  119|  4.61M|  }
_ZN8patentryC2Ev:
  132|      4|    : cond(FLAG_NULL)
  ------------------
  |  |   96|      4|#define FLAG_NULL 0x00
  ------------------
  133|      4|    , cond2(FLAG_NULL) {
  ------------------
  |  |   96|      4|#define FLAG_NULL 0x00
  ------------------
  134|      4|  }
csutil.cxx:_ZL16HUNSPELL_WARNINGP8_IO_FILEPKcz:
   48|  1.66M|static inline void HUNSPELL_WARNING(FILE*, const char*, ...) {}
hashmgr.cxx:_ZL16HUNSPELL_WARNINGP8_IO_FILEPKcz:
   48|    250|static inline void HUNSPELL_WARNING(FILE*, const char*, ...) {}

_ZN8AffEntryC2Ev:
   46|     42|      : morphcode(nullptr)
   47|     42|      , contclass(nullptr)
   48|     42|      , aflag(0)
   49|     42|      , contclasslen(0)
   50|     42|      , numconds(0)
   51|     42|      , opts(0) {}

_Z6myopenRNSt3__114basic_ifstreamIcNS_11char_traitsIcEEEEPKcj:
  110|    114|{
  111|       |#if defined(_WIN32) && defined(_MSC_VER)
  112|       |#define WIN32_LONG_PATH_PREFIX "\\\\?\\"
  113|       |  if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) {
  114|       |    int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
  115|       |    wchar_t* buff = new wchar_t[len];
  116|       |    wchar_t* buff2 = new wchar_t[len];
  117|       |    MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len);
  118|       |    if (_wfullpath(buff2, buff, len) != NULL) {
  119|       |      stream.open(buff2, mode);
  120|       |    }
  121|       |    delete [] buff;
  122|       |    delete [] buff2;
  123|       |  }
  124|       |  else
  125|       |#endif
  126|    114|  stream.open(path, mode);
  127|    114|}
_Z6u16_u8RNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERKNS_6vectorI6w_charNS3_IS8_EEEE:
  134|  20.1M|std::string& u16_u8(std::string& dest, const std::vector<w_char>& src) {
  135|  20.1M|  dest.clear();
  136|  20.1M|  dest.reserve(src.size());
  137|   576M|  for (const w_char& wc : src) {
  ------------------
  |  Branch (137:25): [True: 576M, False: 20.1M]
  ------------------
  138|   576M|    uint16_t cp = (static_cast<uint16_t>(wc.h) << 8) | wc.l;
  139|   576M|    if (cp < 0x80) {
  ------------------
  |  Branch (139:9): [True: 502M, False: 74.6M]
  ------------------
  140|   502M|      dest.push_back(static_cast<char>(cp));
  141|   502M|    } else if (cp < 0x800) {
  ------------------
  |  Branch (141:16): [True: 2.75M, False: 71.8M]
  ------------------
  142|  2.75M|      dest.push_back(static_cast<char>(0xc0 | (cp >> 6)));
  143|  2.75M|      dest.push_back(static_cast<char>(0x80 | (cp & 0x3f)));
  144|  71.8M|    } else {
  145|  71.8M|      dest.push_back(static_cast<char>(0xe0 | (cp >> 12)));
  146|  71.8M|      dest.push_back(static_cast<char>(0x80 | ((cp >> 6) & 0x3f)));
  147|  71.8M|      dest.push_back(static_cast<char>(0x80 | (cp & 0x3f)));
  148|  71.8M|    }
  149|   576M|  }
  150|  20.1M|  return dest;
  151|  20.1M|}
_Z6u8_u16RNSt3__16vectorI6w_charNS_9allocatorIS1_EEEERKNS_12basic_stringIcNS_11char_traitsIcEENS2_IcEEEEb:
  169|  2.80M|int u8_u16(std::vector<w_char>& dest, const std::string& src, bool only_convert_first_letter) {
  170|       |  // faster to oversize initially, assign to elements and resize to what's used
  171|       |  // than to reserve and push_back
  172|  2.80M|  dest.resize(only_convert_first_letter ? 1 : src.size());
  ------------------
  |  Branch (172:15): [True: 0, False: 2.80M]
  ------------------
  173|  2.80M|  auto out = dest.begin();
  174|  2.80M|  auto p = src.begin(), end = src.end();
  175|       |
  176|  22.4M|  while (p < end) {
  ------------------
  |  Branch (176:10): [True: 19.8M, False: 2.62M]
  ------------------
  177|  19.8M|    uint8_t b0 = static_cast<uint8_t>(*p);
  178|  19.8M|    uint16_t cp;
  179|       |
  180|  19.8M|    if (b0 < 0x80) {
  ------------------
  |  Branch (180:9): [True: 16.8M, False: 3.00M]
  ------------------
  181|       |      // 1-byte ASCII
  182|  16.8M|      cp = b0;
  183|  16.8M|    } else if (b0 < 0xc0) {
  ------------------
  |  Branch (183:16): [True: 365k, False: 2.64M]
  ------------------
  184|       |      // continuation byte at lead position
  185|   365k|      HUNSPELL_WARNING(stderr,
  186|   365k|                       "UTF-8 encoding error. Unexpected continuation bytes "
  187|   365k|                       "in %ld. character position\n%s\n",
  188|   365k|                       static_cast<long>(std::distance(src.begin(), p)),
  189|   365k|                       src.c_str());
  190|   365k|      cp = 0xfffd;
  191|  2.64M|    } else if (b0 < 0xe0) {
  ------------------
  |  Branch (191:16): [True: 1.23M, False: 1.40M]
  ------------------
  192|       |      // 2-byte sequence: 110xxxxx 10yyyyyy
  193|  1.23M|      if (p + 1 < end && is_utf8_cont(p[1])) {
  ------------------
  |  Branch (193:11): [True: 1.12M, False: 106k]
  |  Branch (193:11): [True: 198k, False: 1.03M]
  |  Branch (193:26): [True: 198k, False: 930k]
  ------------------
  194|   198k|        cp = ((b0 & 0x1f) << 6) | (static_cast<uint8_t>(p[1]) & 0x3f);
  195|   198k|        ++p;  // step past lead; loop bottom steps past cont
  196|  1.03M|      } else {
  197|  1.03M|        warn_missing_cont(src, p);
  198|  1.03M|        cp = 0xfffd;
  199|  1.03M|      }
  200|  1.40M|    } else if (b0 < 0xf0) {
  ------------------
  |  Branch (200:16): [True: 1.22M, False: 186k]
  ------------------
  201|       |      // 3-byte sequence: 1110xxxx 10yyyyyy 10zzzzzz
  202|  1.22M|      if (p + 1 < end && is_utf8_cont(p[1])) {
  ------------------
  |  Branch (202:11): [True: 1.20M, False: 12.7k]
  |  Branch (202:11): [True: 1.15M, False: 68.3k]
  |  Branch (202:26): [True: 1.15M, False: 55.5k]
  ------------------
  203|  1.15M|        uint8_t b1 = static_cast<uint8_t>(p[1]);
  204|  1.15M|        ++p;  // step past lead
  205|  1.15M|        if (p + 1 < end && is_utf8_cont(p[1])) {
  ------------------
  |  Branch (205:13): [True: 1.15M, False: 738]
  |  Branch (205:13): [True: 1.14M, False: 8.02k]
  |  Branch (205:28): [True: 1.14M, False: 7.28k]
  ------------------
  206|  1.14M|          cp = ((b0 & 0x0f) << 12) | ((b1 & 0x3f) << 6) | (static_cast<uint8_t>(p[1]) & 0x3f);
  207|  1.14M|          ++p;  // step past first cont; loop bottom steps past second cont
  208|  1.14M|        } else {
  209|  8.02k|          warn_missing_cont(src, p);
  210|  8.02k|          cp = 0xfffd;
  211|  8.02k|        }
  212|  1.15M|      } else {
  213|  68.3k|        warn_missing_cont(src, p);
  214|  68.3k|        cp = 0xfffd;
  215|  68.3k|      }
  216|  1.22M|    } else {
  217|       |      // 4+ byte lead: codepoint >= U+10000, can't fit in w_char
  218|   186k|      HUNSPELL_WARNING(stderr,
  219|   186k|                       "This UTF-8 encoding can't convert to UTF-16:\n%s\n",
  220|   186k|                       src.c_str());
  221|   186k|      out->h = 0xff;
  222|   186k|      out->l = 0xfd;
  223|   186k|      ++out;
  224|   186k|      dest.resize(out - dest.begin());
  225|   186k|      return -1;
  226|   186k|    }
  227|       |
  228|  19.6M|    out->h = static_cast<unsigned char>(cp >> 8);
  229|  19.6M|    out->l = static_cast<unsigned char>(cp);
  230|  19.6M|    ++out;
  231|  19.6M|    if (only_convert_first_letter)
  ------------------
  |  Branch (231:9): [True: 0, False: 19.6M]
  ------------------
  232|      0|      break;
  233|  19.6M|    ++p;  // consume lead byte
  234|  19.6M|  }
  235|       |
  236|  2.62M|  int size = static_cast<int>(out - dest.begin());
  237|  2.62M|  dest.resize(size);
  238|  2.62M|  return size;
  239|  2.80M|}
_Z8mystrsepRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERNS_11__wrap_iterIPKcEE:
  254|  1.80k|                                     std::string::const_iterator& start) {
  255|  1.80k|  auto end = str.end();
  256|       |
  257|  1.80k|  is_any_of op(" \t");
  258|       |  // don't use isspace() here, the string can be in some random charset
  259|       |  // that's way different than the locale's
  260|  1.80k|  auto sp = start;
  261|  5.87k|  while (sp != end && op(*sp))
  ------------------
  |  Branch (261:10): [True: 5.43k, False: 442]
  |  Branch (261:23): [True: 4.07k, False: 1.35k]
  ------------------
  262|  4.07k|      ++sp;
  263|       |
  264|  1.80k|  auto dp = sp;
  265|  6.69k|  while (dp != end && !op(*dp))
  ------------------
  |  Branch (265:10): [True: 5.81k, False: 882]
  |  Branch (265:23): [True: 4.89k, False: 918]
  ------------------
  266|  4.89k|      ++dp;
  267|       |
  268|  1.80k|  start = dp;
  269|  1.80k|  return sp;
  270|  1.80k|}
_Z7mychompRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
  273|  1.99k|void mychomp(std::string& s) {
  274|  1.99k|  size_t k = s.size();
  275|  1.99k|  size_t newsize = k;
  276|  1.99k|  if ((k > 0) && ((s[k - 1] == '\r') || (s[k - 1] == '\n')))
  ------------------
  |  Branch (276:7): [True: 1.80k, False: 190]
  |  Branch (276:19): [True: 0, False: 1.80k]
  |  Branch (276:41): [True: 0, False: 1.80k]
  ------------------
  277|      0|    --newsize;
  278|  1.99k|  if ((k > 1) && (s[k - 2] == '\r'))
  ------------------
  |  Branch (278:7): [True: 1.60k, False: 384]
  |  Branch (278:18): [True: 0, False: 1.60k]
  ------------------
  279|      0|    --newsize;
  280|  1.99k|  s.resize(newsize);
  281|  1.99k|}
_Z8line_tokRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEc:
  284|   191k|std::vector<std::string> line_tok(const std::string& text, char breakchar) {
  285|   191k|  std::vector<std::string> ret;
  286|   191k|  if (text.empty()) {
  ------------------
  |  Branch (286:7): [True: 8.82k, False: 182k]
  ------------------
  287|  8.82k|    return ret;
  288|  8.82k|  }
  289|       |
  290|   182k|  std::stringstream ss(text);
  291|   182k|  std::string tok;
  292|   365k|  while(std::getline(ss, tok, breakchar)) {
  ------------------
  |  Branch (292:9): [True: 182k, False: 182k]
  ------------------
  293|   182k|    if (!tok.empty()) {
  ------------------
  |  Branch (293:9): [True: 182k, False: 195]
  ------------------
  294|   182k|      ret.push_back(tok);
  295|   182k|    }
  296|   182k|  }
  297|       |
  298|   182k|  return ret;
  299|   191k|}
_Z9line_uniqRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEc:
  303|  10.6k|{
  304|  10.6k|  std::vector<std::string> lines = line_tok(text, breakchar);
  305|  10.6k|  text.clear();
  306|  10.6k|  if (lines.empty()) {
  ------------------
  |  Branch (306:7): [True: 8.81k, False: 1.88k]
  ------------------
  307|  8.81k|    return;
  308|  8.81k|  }
  309|  1.88k|  text = lines[0];
  310|  1.88k|  for (size_t i = 1; i < lines.size(); ++i) {
  ------------------
  |  Branch (310:22): [True: 0, False: 1.88k]
  ------------------
  311|      0|    bool dup = false;
  312|      0|    for (size_t j = 0; j < i; ++j) {
  ------------------
  |  Branch (312:24): [True: 0, False: 0]
  ------------------
  313|      0|      if (lines[i] == lines[j]) {
  ------------------
  |  Branch (313:11): [True: 0, False: 0]
  ------------------
  314|      0|        dup = true;
  315|      0|        break;
  316|      0|      }
  317|      0|    }
  318|      0|    if (!dup) {
  ------------------
  |  Branch (318:9): [True: 0, False: 0]
  ------------------
  319|      0|      if (!text.empty())
  ------------------
  |  Branch (319:11): [True: 0, False: 0]
  ------------------
  320|      0|        text.push_back(breakchar);
  321|      0|      text.append(lines[i]);
  322|      0|    }
  323|      0|  }
  324|  1.88k|}
_Z10copy_fieldRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERKS5_S8_:
  388|   171k|                const std::string& var) {
  389|   171k|  if (morph.empty())
  ------------------
  |  Branch (389:7): [True: 0, False: 171k]
  ------------------
  390|      0|    return false;
  391|   171k|  size_t pos = morph.find(var);
  392|   171k|  if (pos == std::string::npos)
  ------------------
  |  Branch (392:7): [True: 12, False: 171k]
  ------------------
  393|     12|    return false;
  394|   171k|  dest.clear();
  395|   171k|  std::string beg(morph.substr(pos + MORPH_TAG_LEN, std::string::npos));
  ------------------
  |  |  119|   171k|#define MORPH_TAG_LEN strlen(MORPH_STEM)
  |  |  ------------------
  |  |  |  |  103|   171k|#define MORPH_STEM "st:"
  |  |  ------------------
  ------------------
  396|       |
  397|   483k|  for (const char c : beg) {
  ------------------
  |  Branch (397:21): [True: 483k, False: 171k]
  ------------------
  398|   483k|    if (c == ' ' || c == '\t' || c == '\n')
  ------------------
  |  Branch (398:9): [True: 0, False: 483k]
  |  Branch (398:21): [True: 0, False: 483k]
  |  Branch (398:34): [True: 0, False: 483k]
  ------------------
  399|      0|      break;
  400|   483k|    dest.push_back(c);
  401|   483k|  }
  402|       |
  403|   171k|  return true;
  404|   171k|}
_Z8mystrrepRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERKS5_S8_:
  408|  15.7M|                      const std::string& replace) {
  409|  15.7M|  size_t pos = 0;
  410|  18.6M|  while ((pos = str.find(search, pos)) != std::string::npos) {
  ------------------
  |  Branch (410:10): [True: 2.91M, False: 15.7M]
  ------------------
  411|  2.91M|    str.replace(pos, search.length(), replace);
  412|  2.91M|    pos += replace.length();
  413|  2.91M|  }
  414|  15.7M|  return str;
  415|  15.7M|}
_Z11reversewordRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
  418|   683k|size_t reverseword(std::string& word) {
  419|   683k|  std::reverse(word.begin(), word.end());
  420|   683k|  return word.size();
  421|   683k|}
_Z8uniqlistRNSt3__16vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE:
  498|  5.85k|void uniqlist(std::vector<std::string>& list) {
  499|  5.85k|  if (list.size() < 2)
  ------------------
  |  Branch (499:7): [True: 5.85k, False: 0]
  ------------------
  500|  5.85k|    return;
  501|       |
  502|      0|  std::vector<std::string> ret;
  503|      0|  ret.push_back(list[0]);
  504|       |
  505|      0|  for (size_t i = 1; i < list.size(); ++i) {
  ------------------
  |  Branch (505:22): [True: 0, False: 0]
  ------------------
  506|      0|    if (std::find(ret.begin(), ret.end(), list[i]) == ret.end())
  ------------------
  |  Branch (506:9): [True: 0, False: 0]
  ------------------
  507|      0|        ret.push_back(list[i]);
  508|      0|  }
  509|       |
  510|      0|  list.swap(ret);
  511|      0|}
_Z9upper_utf6w_chari:
  530|  3.77M|w_char upper_utf(w_char u, int langnum) {
  531|       |
  532|  3.77M|#if defined(_WIN32) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__))  || defined(__LITTLE_ENDIAN__)
  533|       |
  534|       |//with these optimizations, msvc can optimize this function to one jmp instruction
  535|       |//but g++ remains in five instructions
  536|       |//maybe use inline asm for g++?
  537|       |
  538|       |#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
  539|       |  return std::bit_cast<w_char>(unicodetoupper((unsigned short)u, langnum));
  540|       |#else
  541|  3.77M|  const auto us = unicodetoupper((unsigned short)u, langnum);
  542|  3.77M|  memcpy(&u, &us, sizeof(unsigned short));
  543|  3.77M|  return u;
  544|  3.77M|#endif
  545|       |
  546|       |#else
  547|       |  const auto us = unicodetoupper((unsigned short)u, langnum);
  548|       |  u.h = (unsigned char)(us >> 8);
  549|       |  u.l = (unsigned char)(us & 0xff);
  550|       |  return u;
  551|       |#endif
  552|  3.77M|}
_Z9lower_utf6w_chari:
  554|  4.65M|w_char lower_utf(w_char u, int langnum) {
  555|       |
  556|  4.65M|#if defined(_WIN32) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__))  || defined(__LITTLE_ENDIAN__)
  557|       |
  558|       |//with these optimizations, msvc can optimize this function to one jmp instruction
  559|       |//but g++ remains in five instructions
  560|       |//maybe use inline asm for g++?
  561|       |
  562|       |#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
  563|       |  return std::bit_cast<w_char>(unicodetolower((unsigned short)u, langnum));
  564|       |#else
  565|  4.65M|  const auto us = unicodetolower((unsigned short)u, langnum);
  566|  4.65M|  memcpy(&u, &us, sizeof(unsigned short));
  567|  4.65M|  return u;
  568|  4.65M|#endif
  569|       |
  570|       |#else
  571|       |  const auto us = unicodetolower((unsigned short)u, langnum);
  572|       |  u.h = (unsigned char)(us >> 8);
  573|       |  u.l = (unsigned char)(us & 0xff);
  574|       |  return u;
  575|       |#endif
  576|  4.65M|}
_Z8mkallcapRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPK7cs_info:
  579|   257k|std::string& mkallcap(std::string& s, const struct cs_info* csconv) {
  580|  5.16M|  for (char& aI : s) {
  ------------------
  |  Branch (580:17): [True: 5.16M, False: 257k]
  ------------------
  581|  5.16M|    aI = cupper(csconv, static_cast<unsigned char>(aI));
  582|  5.16M|  }
  583|   257k|  return s;
  584|   257k|}
_Z10mkallsmallRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPK7cs_info:
  587|  1.46M|std::string& mkallsmall(std::string& s, const struct cs_info* csconv) {
  588|  30.3M|  for (char& aI : s) {
  ------------------
  |  Branch (588:17): [True: 30.3M, False: 1.46M]
  ------------------
  589|  30.3M|    aI = clower(csconv, static_cast<unsigned char>(aI));
  590|  30.3M|  }
  591|  1.46M|  return s;
  592|  1.46M|}
_Z14mkallsmall_utfRNSt3__16vectorI6w_charNS_9allocatorIS1_EEEEi:
  594|   811k|std::vector<w_char>& mkallsmall_utf(std::vector<w_char>& u, int langnum) {
  595|  4.63M|  for (auto& i : u) {
  ------------------
  |  Branch (595:16): [True: 4.63M, False: 811k]
  ------------------
  596|  4.63M|    i = lower_utf(i, langnum);
  597|  4.63M|  }
  598|   811k|  return u;
  599|   811k|}
_Z12mkallcap_utfRNSt3__16vectorI6w_charNS_9allocatorIS1_EEEEi:
  601|   146k|std::vector<w_char>& mkallcap_utf(std::vector<w_char>& u, int langnum) {
  602|  1.78M|  for (auto& i : u) {
  ------------------
  |  Branch (602:16): [True: 1.78M, False: 146k]
  ------------------
  603|  1.78M|    i = upper_utf(i, langnum);
  604|  1.78M|  }
  605|   146k|  return u;
  606|   146k|}
_Z9mkinitcapRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPK7cs_info:
  608|   604k|std::string& mkinitcap(std::string& s, const struct cs_info* csconv) {
  609|   604k|  if (!s.empty()) {
  ------------------
  |  Branch (609:7): [True: 604k, False: 101]
  ------------------
  610|   604k|    s[0] = cupper(csconv, static_cast<unsigned char>(s[0]));
  611|   604k|  }
  612|   604k|  return s;
  613|   604k|}
_Z13mkinitcap_utfRNSt3__16vectorI6w_charNS_9allocatorIS1_EEEEi:
  615|   201k|std::vector<w_char>& mkinitcap_utf(std::vector<w_char>& u, int langnum) {
  616|   201k|  if (!u.empty()) {
  ------------------
  |  Branch (616:7): [True: 201k, False: 0]
  ------------------
  617|   201k|    u[0] = upper_utf(u[0], langnum);
  618|   201k|  }
  619|   201k|  return u;
  620|   201k|}
_Z11mkinitsmallRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPK7cs_info:
  622|  9.53k|std::string& mkinitsmall(std::string& s, const struct cs_info* csconv) {
  623|  9.53k|  if (!s.empty()) {
  ------------------
  |  Branch (623:7): [True: 9.53k, False: 0]
  ------------------
  624|  9.53k|    s[0] = clower(csconv, static_cast<unsigned char>(s[0]));
  625|  9.53k|  }
  626|  9.53k|  return s;
  627|  9.53k|}
_Z15mkinitsmall_utfRNSt3__16vectorI6w_charNS_9allocatorIS1_EEEEi:
  629|  2.60k|std::vector<w_char>& mkinitsmall_utf(std::vector<w_char>& u, int langnum) {
  630|  2.60k|  if (!u.empty()) {
  ------------------
  |  Branch (630:7): [True: 2.60k, False: 0]
  ------------------
  631|  2.60k|    u[0] = lower_utf(u[0], langnum);
  632|  2.60k|  }
  633|  2.60k|  return u;
  634|  2.60k|}
_Z14get_current_csRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
 2292|  2.06k|const struct cs_info* get_current_cs(const std::string& es) {
 2293|  2.06k|  char* normalized_encoding = new char[es.size() + 1];
 2294|  2.06k|  toAsciiLowerAndRemoveNonAlphanumeric(es.c_str(), normalized_encoding);
 2295|       |
 2296|  2.06k|  const struct cs_info* ccs = nullptr;
 2297|  2.06k|  for (const auto& encd : encds) {
  ------------------
  |  Branch (2297:25): [True: 2.06k, False: 0]
  ------------------
 2298|  2.06k|    if (strcmp(normalized_encoding, encd.enc_name) == 0) {
  ------------------
  |  Branch (2298:9): [True: 2.06k, False: 0]
  ------------------
 2299|  2.06k|      ccs = encd.cs_table;
 2300|  2.06k|      break;
 2301|  2.06k|    }
 2302|  2.06k|  }
 2303|       |
 2304|  2.06k|  delete[] normalized_encoding;
 2305|       |
 2306|  2.06k|  if (!ccs) {
  ------------------
  |  Branch (2306:7): [True: 0, False: 2.06k]
  ------------------
 2307|      0|    HUNSPELL_WARNING(stderr,
 2308|      0|                     "error: unknown encoding %s: using %s as fallback\n", es.c_str(),
 2309|      0|                     encds[0].enc_name);
 2310|      0|    ccs = encds[0].cs_table;
 2311|      0|  }
 2312|       |
 2313|  2.06k|  return ccs;
 2314|  2.06k|}
_Z12get_lang_numRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
 2444|      4|int get_lang_num(const std::string& lang) {
 2445|     72|  for (const auto& i : lang2enc) {
  ------------------
  |  Branch (2445:22): [True: 72, False: 0]
  ------------------
 2446|     72|    if (strcmp(lang.c_str(), i.lang) == 0) {
  ------------------
  |  Branch (2446:9): [True: 4, False: 68]
  ------------------
 2447|      4|      return i.num;
 2448|      4|    }
 2449|     72|  }
 2450|      0|  return LANG_xx;
 2451|      4|}
_Z14unicodetoupperti:
 2453|  17.4M|unsigned short unicodetoupper(unsigned short c, int langnum) {
 2454|       |  // In Azeri and Turkish, I and i dictinct letters:
 2455|       |  // There are a dotless lower case i pair of upper `I',
 2456|       |  // and an upper I with dot pair of lower `i'.
 2457|  17.4M|  if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh)))
  ------------------
  |  Branch (2457:7): [True: 21.6k, False: 17.4M]
  |  Branch (2457:23): [True: 0, False: 21.6k]
  |  Branch (2457:47): [True: 0, False: 21.6k]
  |  Branch (2457:71): [True: 0, False: 21.6k]
  ------------------
 2458|      0|    return 0x0130;
 2459|       |#ifdef OPENOFFICEORG
 2460|       |  return static_cast<unsigned short>(u_toupper(c));
 2461|       |#else
 2462|       |#ifdef MOZILLA_CLIENT
 2463|       |  return ToUpperCase((char16_t)c);
 2464|       |#else
 2465|  17.4M|  unsigned short up = utf_pages[utf_page_index[c >> 8]][c & 0xFF].cupper;
 2466|  17.4M|  return up ? up : c;
  ------------------
  |  Branch (2466:10): [True: 2.62M, False: 14.7M]
  ------------------
 2467|  17.4M|#endif
 2468|  17.4M|#endif
 2469|  17.4M|}
_Z14unicodetolowerti:
 2471|  19.0M|unsigned short unicodetolower(unsigned short c, int langnum) {
 2472|       |  // In Azeri and Turkish, I and i dictinct letters:
 2473|       |  // There are a dotless lower case i pair of upper `I',
 2474|       |  // and an upper I with dot pair of lower `i'.
 2475|  19.0M|  if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh)))
  ------------------
  |  Branch (2475:7): [True: 3.04k, False: 19.0M]
  |  Branch (2475:23): [True: 0, False: 3.04k]
  |  Branch (2475:47): [True: 0, False: 3.04k]
  |  Branch (2475:71): [True: 0, False: 3.04k]
  ------------------
 2476|      0|    return 0x0131;
 2477|       |#ifdef OPENOFFICEORG
 2478|       |  return static_cast<unsigned short>(u_tolower(c));
 2479|       |#else
 2480|       |#ifdef MOZILLA_CLIENT
 2481|       |  return ToLowerCase((char16_t)c);
 2482|       |#else
 2483|  19.0M|  unsigned short lo = utf_pages[utf_page_index[c >> 8]][c & 0xFF].clower;
 2484|  19.0M|  return lo ? lo : c;
  ------------------
  |  Branch (2484:10): [True: 3.59M, False: 15.4M]
  ------------------
 2485|  19.0M|#endif
 2486|  19.0M|#endif
 2487|  19.0M|}
_Z11get_captypeRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPK7cs_info:
 2498|  5.52M|int get_captype(const std::string& word, const cs_info* csconv) {
 2499|       |  // now determine the capitalization type of the first nl letters
 2500|  5.52M|  size_t ncap = 0;
 2501|  5.52M|  size_t nneutral = 0;
 2502|  5.52M|  size_t firstcap = 0;
 2503|  5.52M|  if (csconv == nullptr)
  ------------------
  |  Branch (2503:7): [True: 0, False: 5.52M]
  ------------------
 2504|      0|    return NOCAP;
  ------------------
  |  |   92|      0|#define NOCAP 0
  ------------------
 2505|   102M|  for (char q : word) {
  ------------------
  |  Branch (2505:15): [True: 102M, False: 5.52M]
  ------------------
 2506|   102M|    const auto nIndex = static_cast<unsigned char>(q);
 2507|   102M|    if (ccase(csconv, nIndex))
  ------------------
  |  Branch (2507:9): [True: 5.96M, False: 96.3M]
  ------------------
 2508|  5.96M|      ncap++;
 2509|   102M|    if (cupper(csconv, nIndex) == clower(csconv, nIndex))
  ------------------
  |  Branch (2509:9): [True: 75.2M, False: 26.9M]
  ------------------
 2510|  75.2M|      nneutral++;
 2511|   102M|  }
 2512|  5.52M|  if (ncap) {
  ------------------
  |  Branch (2512:7): [True: 988k, False: 4.53M]
  ------------------
 2513|   988k|    const auto nIndex = static_cast<unsigned char>(word[0]);
 2514|   988k|    firstcap = csconv[nIndex].ccase;
 2515|   988k|  }
 2516|       |
 2517|       |  // now finally set the captype
 2518|  5.52M|  if (ncap == 0) {
  ------------------
  |  Branch (2518:7): [True: 4.53M, False: 988k]
  ------------------
 2519|  4.53M|    return NOCAP;
  ------------------
  |  |   92|  4.53M|#define NOCAP 0
  ------------------
 2520|  4.53M|  } else if ((ncap == 1) && firstcap) {
  ------------------
  |  Branch (2520:14): [True: 533k, False: 455k]
  |  Branch (2520:29): [True: 264k, False: 268k]
  ------------------
 2521|   264k|    return INITCAP;
  ------------------
  |  |   93|   264k|#define INITCAP 1
  ------------------
 2522|   724k|  } else if ((ncap == word.size()) || ((ncap + nneutral) == word.size())) {
  ------------------
  |  Branch (2522:14): [True: 11.6k, False: 712k]
  |  Branch (2522:39): [True: 112k, False: 599k]
  ------------------
 2523|   124k|    return ALLCAP;
  ------------------
  |  |   94|   124k|#define ALLCAP 2
  ------------------
 2524|   599k|  } else if ((ncap > 1) && firstcap) {
  ------------------
  |  Branch (2524:14): [True: 379k, False: 220k]
  |  Branch (2524:28): [True: 176k, False: 203k]
  ------------------
 2525|   176k|    return HUHINITCAP;
  ------------------
  |  |   96|   176k|#define HUHINITCAP 4
  ------------------
 2526|   176k|  }
 2527|   423k|  return HUHCAP;
  ------------------
  |  |   95|   423k|#define HUHCAP 3
  ------------------
 2528|  5.52M|}
_Z16get_captype_utf8RKNSt3__16vectorI6w_charNS_9allocatorIS1_EEEEi:
 2530|  1.65M|int get_captype_utf8(const std::vector<w_char>& word, int langnum) {
 2531|       |  // now determine the capitalization type of the first nl letters
 2532|  1.65M|  size_t ncap = 0;
 2533|  1.65M|  size_t nneutral = 0;
 2534|  1.65M|  size_t firstcap = 0;
 2535|       |
 2536|  1.65M|  auto it = word.begin(), it_end = word.end();
 2537|  13.2M|  while (it != it_end) {
  ------------------
  |  Branch (2537:10): [True: 11.5M, False: 1.65M]
  ------------------
 2538|  11.5M|    const auto idx = (unsigned short)*it;
 2539|  11.5M|    const auto lwridx = unicodetolower(idx, langnum);
 2540|  11.5M|    if (idx != lwridx)
  ------------------
  |  Branch (2540:9): [True: 791k, False: 10.7M]
  ------------------
 2541|   791k|      ncap++;
 2542|  11.5M|    if (unicodetoupper(idx, langnum) == lwridx)
  ------------------
  |  Branch (2542:9): [True: 9.00M, False: 2.53M]
  ------------------
 2543|  9.00M|      nneutral++;
 2544|  11.5M|    ++it;
 2545|  11.5M|  }
 2546|  1.65M|  if (ncap) {
  ------------------
  |  Branch (2546:7): [True: 275k, False: 1.38M]
  ------------------
 2547|   275k|    const auto idx = (unsigned short)word[0];
 2548|   275k|    firstcap = (idx != unicodetolower(idx, langnum));
 2549|   275k|  }
 2550|       |
 2551|       |  // now finally set the captype
 2552|  1.65M|  if (ncap == 0) {
  ------------------
  |  Branch (2552:7): [True: 1.38M, False: 275k]
  ------------------
 2553|  1.38M|    return NOCAP;
  ------------------
  |  |   92|  1.38M|#define NOCAP 0
  ------------------
 2554|  1.38M|  } else if ((ncap == 1) && firstcap) {
  ------------------
  |  Branch (2554:14): [True: 160k, False: 114k]
  |  Branch (2554:29): [True: 80.1k, False: 80.7k]
  ------------------
 2555|  80.1k|    return INITCAP;
  ------------------
  |  |   93|  80.1k|#define INITCAP 1
  ------------------
 2556|   194k|  } else if ((ncap == word.size()) || ((ncap + nneutral) == word.size())) {
  ------------------
  |  Branch (2556:14): [True: 2.66k, False: 192k]
  |  Branch (2556:39): [True: 52.3k, False: 139k]
  ------------------
 2557|  55.0k|    return ALLCAP;
  ------------------
  |  |   94|  55.0k|#define ALLCAP 2
  ------------------
 2558|   139k|  } else if ((ncap > 1) && firstcap) {
  ------------------
  |  Branch (2558:14): [True: 77.8k, False: 61.9k]
  |  Branch (2558:28): [True: 41.9k, False: 35.9k]
  ------------------
 2559|  41.9k|    return HUHINITCAP;
  ------------------
  |  |   96|  41.9k|#define HUHINITCAP 4
  ------------------
 2560|  41.9k|  }
 2561|  97.8k|  return HUHCAP;
  ------------------
  |  |   95|  97.8k|#define HUHCAP 3
  ------------------
 2562|  1.65M|}
_Z24remove_ignored_chars_utfRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERKNS_6vectorI6w_charNS3_IS8_EEEE:
 2566|   362k|                                const std::vector<w_char>& ignored_chars) {
 2567|   362k|  std::vector<w_char> w;
 2568|   362k|  std::vector<w_char> w2;
 2569|   362k|  u8_u16(w, word);
 2570|       |
 2571|   362k|  std::copy_if(w.begin(), w.end(), std::back_inserter(w2),
 2572|   362k|  [&ignored_chars](w_char wc) {
 2573|   362k|    return !std::binary_search(ignored_chars.begin(), ignored_chars.end(), wc);
 2574|   362k|  });
 2575|       |
 2576|   362k|  u16_u8(word, w2);
 2577|   362k|  return w2.size();
 2578|   362k|}
_Z20remove_ignored_charsRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERKS5_:
 2582|  1.24M|                            const std::string& ignored_chars) {
 2583|  1.24M|  word.erase(
 2584|  1.24M|      std::remove_if(word.begin(), word.end(), is_any_of(ignored_chars)),
 2585|  1.24M|      word.end());
 2586|  1.24M|  return word.size();
 2587|  1.24M|}
_Z12parse_stringRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERS5_i:
 2589|     90|bool parse_string(const std::string& line, std::string& out, int ln) {
 2590|     90|  if (!out.empty()) {
  ------------------
  |  Branch (2590:7): [True: 0, False: 90]
  ------------------
 2591|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple definitions\n", ln);
 2592|      0|    return false;
 2593|      0|  }
 2594|     90|  int i = 0;
 2595|     90|  int np = 0;
 2596|     90|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 2597|    270|  while (start_piece != line.end()) {
  ------------------
  |  Branch (2597:10): [True: 180, False: 90]
  ------------------
 2598|    180|    switch (i) {
 2599|     90|      case 0: {
  ------------------
  |  Branch (2599:7): [True: 90, False: 90]
  ------------------
 2600|     90|        np++;
 2601|     90|        break;
 2602|      0|      }
 2603|     90|      case 1: {
  ------------------
  |  Branch (2603:7): [True: 90, False: 90]
  ------------------
 2604|     90|        out.assign(start_piece, iter);
 2605|     90|        np++;
 2606|     90|        break;
 2607|      0|      }
 2608|      0|      default:
  ------------------
  |  Branch (2608:7): [True: 0, False: 180]
  ------------------
 2609|      0|        break;
 2610|    180|    }
 2611|    180|    ++i;
 2612|    180|     start_piece = mystrsep(line, iter);
 2613|    180|  }
 2614|     90|  if (np != 2) {
  ------------------
  |  Branch (2614:7): [True: 0, False: 90]
  ------------------
 2615|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", ln);
 2616|      0|    return false;
 2617|      0|  }
 2618|     90|  return true;
 2619|     90|}
_Z11parse_arrayRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERS5_RNS_6vectorI6w_charNS3_ISA_EEEEii:
 2625|     14|                 int ln) {
 2626|     14|  if (!parse_string(line, out, ln))
  ------------------
  |  Branch (2626:7): [True: 0, False: 14]
  ------------------
 2627|      0|    return false;
 2628|     14|  if (utf8) {
  ------------------
  |  Branch (2628:7): [True: 8, False: 6]
  ------------------
 2629|      8|    u8_u16(out_utf16, out);
 2630|      8|    std::sort(out_utf16.begin(), out_utf16.end());
 2631|      8|  }
 2632|     14|  return true;
 2633|     14|}
csutil.cxx:_ZL17warn_missing_contRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_11__wrap_iterIPKcEE:
  153|  1.11M|static void warn_missing_cont(const std::string& src, std::string::const_iterator p) {
  154|       |  HUNSPELL_WARNING(stderr,
  155|  1.11M|                   "UTF-8 encoding error. Missing continuation byte in "
  156|  1.11M|                   "%ld. character position:\n%s\n",
  157|  1.11M|                   static_cast<long>(std::distance(src.begin(), p)),
  158|  1.11M|                   src.c_str());
  159|  1.11M|}
csutil.cxx:_ZN12_GLOBAL__N_19is_any_ofC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  244|  1.24M|  explicit is_any_of(const std::string& in) : chars(in) {}
csutil.cxx:_ZNK12_GLOBAL__N_19is_any_ofclEc:
  246|  20.8M|  bool operator()(char c) const { return chars.find(c) != std::string::npos; }
csutil.cxx:_ZN12_GLOBAL__N_16cupperEPK7cs_infoi:
  514|   108M|unsigned char cupper(const struct cs_info* csconv, int nIndex) {
  515|   108M|  assert(nIndex >= 0 && nIndex <= 255);
  ------------------
  |  Branch (515:3): [True: 108M, False: 0]
  |  Branch (515:3): [True: 108M, False: 0]
  |  Branch (515:3): [True: 108M, False: 0]
  ------------------
  516|   108M|  return csconv[nIndex].cupper;
  517|   108M|}
csutil.cxx:_ZN12_GLOBAL__N_16clowerEPK7cs_infoi:
  519|   132M|unsigned char clower(const struct cs_info* csconv, int nIndex) {
  520|   132M|  assert(nIndex >= 0 && nIndex <= 255);
  ------------------
  |  Branch (520:3): [True: 132M, False: 0]
  |  Branch (520:3): [True: 132M, False: 0]
  |  Branch (520:3): [True: 132M, False: 0]
  ------------------
  521|   132M|  return csconv[nIndex].clower;
  522|   132M|}
csutil.cxx:_ZL36toAsciiLowerAndRemoveNonAlphanumericPKcPc:
 2272|  2.06k|                                                 char* pBuf) {
 2273|  18.6k|  while (*pName) {
  ------------------
  |  Branch (2273:10): [True: 16.5k, False: 2.06k]
  ------------------
 2274|       |    /* A-Z */
 2275|  16.5k|    if ((*pName >= 0x41) && (*pName <= 0x5A)) {
  ------------------
  |  Branch (2275:9): [True: 6.18k, False: 10.3k]
  |  Branch (2275:29): [True: 294, False: 5.88k]
  ------------------
 2276|    294|      *pBuf = (*pName) + 0x20; /* toAsciiLower */
 2277|    294|      pBuf++;
 2278|    294|    }
 2279|       |    /* a-z, 0-9 */
 2280|  16.2k|    else if (((*pName >= 0x61) && (*pName <= 0x7A)) ||
  ------------------
  |  Branch (2280:15): [True: 5.88k, False: 10.3k]
  |  Branch (2280:35): [True: 5.88k, False: 0]
  ------------------
 2281|  16.1k|             ((*pName >= 0x30) && (*pName <= 0x39))) {
  ------------------
  |  Branch (2281:15): [True: 10.3k, False: 98]
  |  Branch (2281:35): [True: 10.3k, False: 0]
  ------------------
 2282|  16.1k|      *pBuf = *pName;
 2283|  16.1k|      pBuf++;
 2284|  16.1k|    }
 2285|       |
 2286|  16.5k|    pName++;
 2287|  16.5k|  }
 2288|       |
 2289|  2.06k|  *pBuf = '\0';
 2290|  2.06k|}
csutil.cxx:_ZN12_GLOBAL__N_15ccaseEPK7cs_infoi:
  524|   102M|unsigned char ccase(const struct cs_info* csconv, int nIndex) {
  525|   102M|  assert(nIndex >= 0 && nIndex <= 255);
  ------------------
  |  Branch (525:3): [True: 102M, False: 0]
  |  Branch (525:3): [True: 102M, False: 0]
  |  Branch (525:3): [True: 102M, False: 0]
  ------------------
  526|   102M|  return csconv[nIndex].ccase;
  527|   102M|}
csutil.cxx:_ZZ24remove_ignored_chars_utfRNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEERKNS_6vectorI6w_charNS3_IS8_EEEEENK3$_0clES8_:
 2572|  2.49M|  [&ignored_chars](w_char wc) {
 2573|  2.49M|    return !std::binary_search(ignored_chars.begin(), ignored_chars.end(), wc);
 2574|  2.49M|  });

_Z12is_utf8_contc:
  143|  58.6M|inline bool is_utf8_cont(char c) {
  144|  58.6M|  return (static_cast<unsigned char>(c) & 0xc0) == 0x80;
  145|  58.6M|}
_Z9utf8_nextRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEm:
  148|  22.0k|inline size_t utf8_next(const std::string& s, size_t pos) {
  149|  22.0k|  if (pos < s.size()) {
  ------------------
  |  Branch (149:7): [True: 22.0k, False: 0]
  ------------------
  150|  22.0k|    ++pos;
  151|  26.0k|    while (pos < s.size() && is_utf8_cont(s[pos]))
  ------------------
  |  Branch (151:12): [True: 23.9k, False: 2.09k]
  |  Branch (151:30): [True: 3.96k, False: 19.9k]
  ------------------
  152|  3.96k|      ++pos;
  153|  22.0k|  }
  154|  22.0k|  return pos;
  155|  22.0k|}
_Z20has_no_ignored_charsRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES7_:
  290|    771|                            const std::string& ignored_chars) {
  291|    771|  return std::all_of(ignored_chars.begin(), ignored_chars.end(),
  292|    771|    [&word](char ic) { return word.find(ic) == std::string::npos; });
  293|    771|}
_Z11HENTRY_DATAP6hentry:
  296|  1.02M|inline char* HENTRY_DATA(struct hentry* h) {
  297|  1.02M|  char* ret;
  298|  1.02M|  if (!(h->var & H_OPT))
  ------------------
  |  |   47|  1.02M|#define H_OPT (1 << 0)          // is there optional morphological data?
  ------------------
  |  Branch (298:7): [True: 1.02M, False: 1.51k]
  ------------------
  299|  1.02M|    ret = nullptr;
  300|  1.51k|  else if (h->var & H_OPT_ALIASM)
  ------------------
  |  |   48|  1.51k|#define H_OPT_ALIASM (1 << 1)   // using alias compression?
  ------------------
  |  Branch (300:12): [True: 0, False: 1.51k]
  ------------------
  301|      0|    ret = get_stored_pointer(HENTRY_WORD(h) + h->blen + 1);
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
  302|  1.51k|  else
  303|  1.51k|    ret = HENTRY_WORD(h) + h->blen + 1;
  ------------------
  |  |   54|  1.51k|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
  304|  1.02M|  return ret;
  305|  1.02M|}
_Z11HENTRY_FINDP6hentryPKc:
  332|  1.88k|inline char* HENTRY_FIND(struct hentry* h, const char* p) {
  333|  1.88k|  char* data = HENTRY_DATA(h);
  334|  1.88k|  return data ? strstr(data, p) : nullptr;
  ------------------
  |  Branch (334:10): [True: 4, False: 1.88k]
  ------------------
  335|  1.88k|}
_ZZ20has_no_ignored_charsRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES7_ENKUlcE_clEc:
  292|  5.49k|    [&word](char ic) { return word.find(ic) == std::string::npos; });

_ZN7FileMgrC2EPKcS1_:
   84|    114|    : hin(nullptr)
   85|    114|    , linenum(0) {
   86|    114|  in[0] = '\0';
   87|       |
   88|    114|  if (!file || !strlen(file))
  ------------------
  |  Branch (88:7): [True: 0, False: 114]
  |  Branch (88:16): [True: 0, False: 114]
  ------------------
   89|      0|    return;
   90|    114|  myopen(fin, file, std::ios_base::in);
   91|    114|  if (!fin.is_open()) {
  ------------------
  |  Branch (91:7): [True: 0, False: 114]
  ------------------
   92|       |    // check hzipped file
   93|      0|    std::string st(file);
   94|      0|    st.append(HZIP_EXTENSION);
  ------------------
  |  |   51|      0|#define HZIP_EXTENSION ".hz"
  ------------------
   95|      0|    hin = new Hunzip(st.c_str(), key);
   96|      0|  }
   97|    114|  if (!fin.is_open() && !hin->is_open())
  ------------------
  |  Branch (97:7): [True: 0, False: 114]
  |  Branch (97:25): [True: 0, False: 0]
  ------------------
   98|      0|    fail(MSG_OPEN, file);
  ------------------
  |  |   53|      0|#define MSG_OPEN "error: %s: cannot open\n"
  ------------------
   99|    114|}
_ZN7FileMgrD2Ev:
  101|    114|FileMgr::~FileMgr() {
  102|    114|  delete hin;
  103|    114|}
_ZN7FileMgr7getlineERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  105|  2.10k|bool FileMgr::getline(std::string& dest) {
  106|  2.10k|  bool ret = false;
  107|  2.10k|  ++linenum;
  108|  2.10k|  if (fin.is_open()) {
  ------------------
  |  Branch (108:7): [True: 2.10k, False: 0]
  ------------------
  109|  2.10k|    ret = static_cast<bool>(std::getline(fin, dest));
  110|  2.10k|  } else if (hin && hin->is_open()) {
  ------------------
  |  Branch (110:14): [True: 0, False: 0]
  |  Branch (110:21): [True: 0, False: 0]
  ------------------
  111|      0|    ret = hin->getline(dest);
  112|      0|  }
  113|  2.10k|  if (!ret) {
  ------------------
  |  Branch (113:7): [True: 112, False: 1.99k]
  ------------------
  114|    112|    --linenum;
  115|    112|  }
  116|  2.10k|  return ret;
  117|  2.10k|}
_ZN7FileMgr10getlinenumEv:
  119|     96|int FileMgr::getlinenum() {
  120|     96|  return linenum;
  121|     96|}

_ZN7HashMgrC2EPKcS1_S1_:
   89|     38|    : flag_mode(FLAG_CHAR)
   90|     38|    , complexprefixes(0)
   91|     38|    , utf8(0)
   92|     38|    , forbiddenword(FORBIDDENWORD)  // forbidden word signing flag
  ------------------
  |  |  127|     38|#define FORBIDDENWORD 65510
  ------------------
   93|     38|    , langnum(0)
   94|     38|    , csconv(nullptr) {
   95|     38|  load_config(apath, key);
   96|     38|  if (!csconv)
  ------------------
  |  Branch (96:7): [True: 38, False: 0]
  ------------------
   97|     38|    csconv = get_current_cs(SPELL_ENCODING);
  ------------------
  |  |   99|     38|#define SPELL_ENCODING "ISO8859-1"
  ------------------
   98|     38|  int ec = load_tables(tpath, key);
   99|     38|  if (ec) {
  ------------------
  |  Branch (99:7): [True: 0, False: 38]
  ------------------
  100|       |    /* error condition - what should we do here */
  101|      0|    fprintf(stderr, "Hash Manager Error : %d\n", ec);
  102|      0|    free_table();
  103|       |    //keep table size to 1 to fix possible division with zero
  104|      0|    tableptr.resize(1, nullptr);
  105|      0|  }
  106|     38|}
_ZN7HashMgr13release_flagsEPtb:
  108|    560|void HashMgr::release_flags(unsigned short* astr, bool owned) {
  109|    560|  if (owned)
  ------------------
  |  Branch (109:7): [True: 560, False: 0]
  ------------------
  110|    560|    delete[] astr;
  111|    560|}
_ZNK7HashMgr6lookupEPKcm:
  146|   505M|struct hentry* HashMgr::lookup(const char* word, size_t len) const {
  147|   505M|  struct hentry* dp = tableptr[hash(word, len)];
  148|   505M|  if (!dp)
  ------------------
  |  Branch (148:7): [True: 456M, False: 49.9M]
  ------------------
  149|   456M|    return nullptr;
  150|   103M|  for (; dp != nullptr; dp = dp->next) {
  ------------------
  |  Branch (150:10): [True: 55.2M, False: 48.6M]
  ------------------
  151|  55.2M|    if (strcmp(word, dp->word) == 0)
  ------------------
  |  Branch (151:9): [True: 1.34M, False: 53.9M]
  ------------------
  152|  1.34M|      return dp;
  153|  55.2M|  }
  154|  48.6M|  return nullptr;
  155|  49.9M|}
_ZN7HashMgr8add_wordERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiPtiPS7_bib:
  165|  7.41k|                      bool own_aff) {
  166|       |
  167|  7.41k|  if (al > std::numeric_limits<short>::max()) {
  ------------------
  |  Branch (167:7): [True: 0, False: 7.41k]
  ------------------
  168|      0|    HUNSPELL_WARNING(stderr, "error: affix len %d is over max limit\n", al);
  169|      0|    release_flags(aff, own_aff);
  170|      0|    return 1;
  171|      0|  }
  172|       |
  173|  7.41k|  const std::string* word = &in_word;
  174|  7.41k|  const std::string* desc = in_desc;
  175|       |
  176|  7.41k|  std::string* word_copy = nullptr;
  177|  7.41k|  std::string* desc_copy = nullptr;
  178|  7.41k|  if ((!ignorechars.empty() && !has_no_ignored_chars(in_word, ignorechars)) || complexprefixes) {
  ------------------
  |  Branch (178:8): [True: 767, False: 6.65k]
  |  Branch (178:32): [True: 272, False: 495]
  |  Branch (178:80): [True: 454, False: 6.69k]
  ------------------
  179|    726|    word_copy = new std::string(in_word);
  180|       |
  181|    726|    if (!ignorechars.empty()) {
  ------------------
  |  Branch (181:9): [True: 272, False: 454]
  ------------------
  182|    272|      if (utf8) {
  ------------------
  |  Branch (182:11): [True: 81, False: 191]
  ------------------
  183|     81|        wcl = remove_ignored_chars_utf(*word_copy, ignorechars_utf16);
  184|    191|      } else {
  185|    191|        remove_ignored_chars(*word_copy, ignorechars);
  186|    191|      }
  187|    272|    }
  188|       |
  189|    726|    if (complexprefixes) {
  ------------------
  |  Branch (189:9): [True: 454, False: 272]
  ------------------
  190|    454|      if (utf8)
  ------------------
  |  Branch (190:11): [True: 0, False: 454]
  ------------------
  191|      0|        wcl = reverseword_utf(*word_copy);
  192|    454|      else
  193|    454|        reverseword(*word_copy);
  194|       |
  195|    454|      if (in_desc && aliasm.empty()) {
  ------------------
  |  Branch (195:11): [True: 0, False: 454]
  |  Branch (195:22): [True: 0, False: 0]
  ------------------
  196|      0|        desc_copy = new std::string(*in_desc);
  197|       |
  198|      0|        if (complexprefixes) {
  ------------------
  |  Branch (198:13): [True: 0, False: 0]
  ------------------
  199|      0|          if (utf8)
  ------------------
  |  Branch (199:15): [True: 0, False: 0]
  ------------------
  200|      0|            reverseword_utf(*desc_copy);
  201|      0|          else
  202|      0|            reverseword(*desc_copy);
  203|      0|        }
  204|      0|        desc = desc_copy;
  205|      0|      }
  206|    454|    }
  207|       |
  208|    726|    word = word_copy;
  209|    726|  }
  210|       |
  211|       |  // limit of hp->blen
  212|  7.41k|  if (word->size() > std::numeric_limits<unsigned short>::max()) {
  ------------------
  |  Branch (212:7): [True: 250, False: 7.16k]
  ------------------
  213|    250|    HUNSPELL_WARNING(stderr, "error: word len %ld is over max limit\n", word->size());
  214|    250|    delete desc_copy;
  215|    250|    delete word_copy;
  216|    250|    release_flags(aff, own_aff);
  217|    250|    return 1;
  218|    250|  }
  219|       |
  220|  7.16k|  bool upcasehomonym = false;
  221|  7.16k|  int descl = desc ? (!aliasm.empty() ? sizeof(char*) : desc->size() + 1) : 0;
  ------------------
  |  Branch (221:15): [True: 4, False: 7.16k]
  |  Branch (221:23): [True: 0, False: 4]
  ------------------
  222|       |  // variable-length hash record with word and optional fields
  223|  7.16k|  auto hp =
  224|  7.16k|      (struct hentry*)malloc(sizeof(struct hentry) + word->size() + descl);
  225|  7.16k|  if (!hp) {
  ------------------
  |  Branch (225:7): [True: 0, False: 7.16k]
  ------------------
  226|      0|    delete desc_copy;
  227|      0|    delete word_copy;
  228|      0|    release_flags(aff, own_aff);
  229|      0|    return 1;
  230|      0|  }
  231|       |
  232|  7.16k|  char* hpw = hp->word;
  233|  7.16k|  memcpy(hpw, word->data(), word->size());
  234|  7.16k|  hpw[word->size()] = 0;
  235|       |
  236|  7.16k|  int i = hash(hpw, word->size());
  237|       |
  238|  7.16k|  hp->blen = (unsigned short)word->size();
  239|  7.16k|  hp->clen = (unsigned short)wcl;
  240|  7.16k|  hp->alen = (short)al;
  241|  7.16k|  hp->astr = aff;
  242|  7.16k|  hp->next = nullptr;
  243|  7.16k|  hp->next_homonym = nullptr;
  244|  7.16k|  hp->var = (captype == INITCAP) ? H_OPT_INITCAP : 0;
  ------------------
  |  |   93|  7.16k|#define INITCAP 1
  ------------------
                hp->var = (captype == INITCAP) ? H_OPT_INITCAP : 0;
  ------------------
  |  |   50|  4.33k|#define H_OPT_INITCAP (1 << 3)  // is dictionary word capitalized?
  ------------------
  |  Branch (244:13): [True: 4.33k, False: 2.83k]
  ------------------
  245|  7.16k|  if (own_aff)
  ------------------
  |  Branch (245:7): [True: 7.16k, False: 2]
  ------------------
  246|  7.16k|    hp->var |= H_OPT_OWNFLAGS;
  ------------------
  |  |   51|  7.16k|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  247|       |
  248|       |  // store the description string or its pointer
  249|  7.16k|  if (desc) {
  ------------------
  |  Branch (249:7): [True: 4, False: 7.16k]
  ------------------
  250|      4|    hp->var |= H_OPT;
  ------------------
  |  |   47|      4|#define H_OPT (1 << 0)          // is there optional morphological data?
  ------------------
  251|      4|    if (!aliasm.empty()) {
  ------------------
  |  Branch (251:9): [True: 0, False: 4]
  ------------------
  252|      0|      hp->var |= H_OPT_ALIASM;
  ------------------
  |  |   48|      0|#define H_OPT_ALIASM (1 << 1)   // using alias compression?
  ------------------
  253|      0|      store_pointer(hpw + word->size() + 1, get_aliasm(atoi(desc->c_str())));
  254|      4|    } else {
  255|      4|      strcpy(hpw + word->size() + 1, desc->c_str());
  256|      4|    }
  257|      4|    if (HENTRY_FIND(hp, MORPH_PHON)) {
  ------------------
  |  |  114|      4|#define MORPH_PHON "ph:"
  ------------------
  |  Branch (257:9): [True: 2, False: 2]
  ------------------
  258|      2|      hp->var |= H_OPT_PHON;
  ------------------
  |  |   49|      2|#define H_OPT_PHON (1 << 2)     // is there ph: field in the morphological data?
  ------------------
  259|       |      // store ph: fields (pronounciation, misspellings, old orthography etc.)
  260|       |      // of a morphological description in reptable to use in REP replacements.
  261|      2|      size_t predicted = tableptr.size() / MORPH_PHON_RATIO;
  ------------------
  |  |   88|      2|#define MORPH_PHON_RATIO 500
  ------------------
  262|      2|      if (reptable.capacity() < predicted)
  ------------------
  |  Branch (262:11): [True: 2, False: 0]
  ------------------
  263|      2|          reptable.reserve(predicted);
  264|      2|      std::string fields = HENTRY_DATA(hp);
  265|      2|      std::string::const_iterator iter = fields.begin(), start_piece = mystrsep(fields, iter);
  266|      4|      while (start_piece != fields.end()) {
  ------------------
  |  Branch (266:14): [True: 2, False: 2]
  ------------------
  267|      2|        if (std::string(start_piece, iter).find(MORPH_PHON) == 0) {
  ------------------
  |  |  114|      2|#define MORPH_PHON "ph:"
  ------------------
  |  Branch (267:13): [True: 2, False: 0]
  ------------------
  268|      2|          std::string ph = std::string(start_piece, iter).substr(sizeof MORPH_PHON - 1);
  ------------------
  |  |  114|      2|#define MORPH_PHON "ph:"
  ------------------
  269|      2|          if (!ph.empty()) {
  ------------------
  |  Branch (269:15): [True: 2, False: 0]
  ------------------
  270|      2|            std::vector<w_char> w;
  271|      2|            size_t strippatt;
  272|      2|            std::string wordpart;
  273|       |            // dictionary based REP replacement, separated by "->"
  274|       |            // for example "pretty ph:prity ph:priti->pretti" to handle
  275|       |            // both prity -> pretty and pritier -> prettiest suggestions.
  276|      2|            if (((strippatt = ph.find("->")) != std::string::npos) &&
  ------------------
  |  Branch (276:17): [True: 0, False: 2]
  ------------------
  277|      0|                    (strippatt > 0) && (strippatt < ph.size() - 2)) {
  ------------------
  |  Branch (277:21): [True: 0, False: 0]
  |  Branch (277:40): [True: 0, False: 0]
  ------------------
  278|      0|                wordpart = ph.substr(strippatt + 2);
  279|      0|                ph.erase(ph.begin() + strippatt, ph.end());
  280|      0|            } else
  281|      2|                wordpart = in_word;
  282|       |            // when the ph: field ends with the character *,
  283|       |            // strip last character of the pattern and the replacement
  284|       |            // to match in REP suggestions also at character changes,
  285|       |            // for example, "pretty ph:prity*" results "prit->prett"
  286|       |            // REP replacement instead of "prity->pretty", to get
  287|       |            // prity->pretty and pritiest->prettiest suggestions.
  288|      2|            if (ph.at(ph.size()-1) == '*') {
  ------------------
  |  Branch (288:17): [True: 0, False: 2]
  ------------------
  289|      0|              strippatt = 1;
  290|      0|              size_t stripword = 0;
  291|      0|              if (utf8) {
  ------------------
  |  Branch (291:19): [True: 0, False: 0]
  ------------------
  292|      0|                while ((strippatt < ph.size()) &&
  ------------------
  |  Branch (292:24): [True: 0, False: 0]
  ------------------
  293|      0|                  is_utf8_cont(ph.at(ph.size()-strippatt-1)))
  ------------------
  |  Branch (293:19): [True: 0, False: 0]
  ------------------
  294|      0|                     ++strippatt;
  295|      0|                while ((stripword < wordpart.size()) &&
  ------------------
  |  Branch (295:24): [True: 0, False: 0]
  ------------------
  296|      0|                  is_utf8_cont(wordpart.at(wordpart.size()-stripword-1)))
  ------------------
  |  Branch (296:19): [True: 0, False: 0]
  ------------------
  297|      0|                     ++stripword;
  298|      0|              }
  299|      0|              ++strippatt;
  300|      0|              ++stripword;
  301|      0|              if ((ph.size() > strippatt) && (wordpart.size() > stripword)) {
  ------------------
  |  Branch (301:19): [True: 0, False: 0]
  |  Branch (301:46): [True: 0, False: 0]
  ------------------
  302|      0|                ph.erase(ph.size()-strippatt, strippatt);
  303|      0|                wordpart.erase(wordpart.size()-stripword, stripword);
  304|      0|              }
  305|      0|            }
  306|       |            // capitalize lowercase pattern for capitalized words to support
  307|       |            // good suggestions also for capitalized misspellings, eg.
  308|       |            // Wednesday ph:wendsay
  309|       |            // results wendsay -> Wednesday and Wendsay -> Wednesday, too.
  310|      2|            if (captype == INITCAP) {
  ------------------
  |  |   93|      2|#define INITCAP 1
  ------------------
  |  Branch (310:17): [True: 0, False: 2]
  ------------------
  311|      0|              std::string ph_capitalized;
  312|      0|              if (utf8) {
  ------------------
  |  Branch (312:19): [True: 0, False: 0]
  ------------------
  313|      0|                u8_u16(w, ph);
  314|      0|                if (get_captype_utf8(w, langnum) == NOCAP) {
  ------------------
  |  |   92|      0|#define NOCAP 0
  ------------------
  |  Branch (314:21): [True: 0, False: 0]
  ------------------
  315|      0|                  mkinitcap_utf(w, langnum);
  316|      0|                  u16_u8(ph_capitalized, w);
  317|      0|                }
  318|      0|              } else if (get_captype(ph, csconv) == NOCAP)
  ------------------
  |  |   92|      0|#define NOCAP 0
  ------------------
  |  Branch (318:26): [True: 0, False: 0]
  ------------------
  319|      0|                  mkinitcap(ph_capitalized, csconv);
  320|       |
  321|      0|              if (!ph_capitalized.empty()) {
  ------------------
  |  Branch (321:19): [True: 0, False: 0]
  ------------------
  322|       |                // add also lowercase word in the case of German or
  323|       |                // Hungarian to support lowercase suggestions lowercased by
  324|       |                // compound word generation or derivational suffixes
  325|       |                // (for example by adjectival suffix "-i" of geographical
  326|       |                // names in Hungarian:
  327|       |                // Massachusetts ph:messzecsuzec
  328|       |                // messzecsuzeci -> massachusettsi (adjective)
  329|       |                // For lowercasing by conditional PFX rules, see
  330|       |                // tests/germancompounding test example or the
  331|       |                // Hungarian dictionary.)
  332|      0|                if (langnum == LANG_de || langnum == LANG_hu) {
  ------------------
  |  Branch (332:21): [True: 0, False: 0]
  |  Branch (332:43): [True: 0, False: 0]
  ------------------
  333|      0|                  std::string wordpart_lower(wordpart);
  334|      0|                  if (utf8) {
  ------------------
  |  Branch (334:23): [True: 0, False: 0]
  ------------------
  335|      0|                    u8_u16(w, wordpart_lower);
  336|      0|                    mkallsmall_utf(w, langnum);
  337|      0|                    u16_u8(wordpart_lower, w);
  338|      0|                  } else {
  339|      0|                    mkallsmall(wordpart_lower, csconv);
  340|      0|                  }
  341|      0|                  reptable.emplace_back();
  342|      0|                  reptable.back().pattern.assign(ph);
  343|      0|                  reptable.back().outstrings[0].assign(wordpart_lower);
  344|      0|                }
  345|      0|                reptable.emplace_back();
  346|      0|                reptable.back().pattern.assign(ph_capitalized);
  347|      0|                reptable.back().outstrings[0].assign(wordpart);
  348|      0|              }
  349|      0|            }
  350|      2|            reptable.emplace_back();
  351|      2|            reptable.back().pattern.assign(ph);
  352|      2|            reptable.back().outstrings[0].assign(wordpart);
  353|      2|          }
  354|      2|        }
  355|      2|        start_piece = mystrsep(fields, iter);
  356|      2|      }
  357|      2|    }
  358|      4|  }
  359|       |
  360|  7.16k|  struct hentry* dp = tableptr[i];
  361|  7.16k|  if (!dp) {
  ------------------
  |  Branch (361:7): [True: 5.60k, False: 1.56k]
  ------------------
  362|  5.60k|    tableptr[i] = hp;
  363|  5.60k|    delete desc_copy;
  364|  5.60k|    delete word_copy;
  365|  5.60k|    return 0;
  366|  5.60k|  }
  367|  1.83k|  while (dp->next != nullptr) {
  ------------------
  |  Branch (367:10): [True: 280, False: 1.55k]
  ------------------
  368|    280|    if ((!dp->next_homonym) && (strcmp(hp->word, dp->word) == 0)) {
  ------------------
  |  Branch (368:9): [True: 280, False: 0]
  |  Branch (368:32): [True: 6, False: 274]
  ------------------
  369|       |      // remove hidden onlyupcase homonym
  370|      6|      if (!onlyupcase) {
  ------------------
  |  Branch (370:11): [True: 4, False: 2]
  ------------------
  371|      4|        if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (371:13): [True: 0, False: 4]
  |  Branch (371:13): [True: 0, False: 4]
  ------------------
  372|      0|          release_flags(dp->astr, dp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  373|      0|          dp->astr = hp->astr;
  374|      0|          dp->alen = hp->alen;
  375|      0|          dp->var &= ~H_OPT_OWNFLAGS;
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  376|      0|          dp->var |= (hp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  377|      0|          free(hp);
  378|      0|          delete desc_copy;
  379|      0|          delete word_copy;
  380|      0|          return 0;
  381|      4|        } else if (!dp->astr && dp->alen == 0 &&
  ------------------
  |  Branch (381:20): [True: 4, False: 0]
  |  Branch (381:33): [True: 4, False: 0]
  ------------------
  382|      4|                   !hp->astr && hp->alen == 0) {
  ------------------
  |  Branch (382:20): [True: 4, False: 0]
  |  Branch (382:33): [True: 4, False: 0]
  ------------------
  383|       |          // word already exists with no flags, skip duplicate
  384|      4|          release_flags(hp->astr, hp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|      4|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  385|      4|          free(hp);
  386|      4|          delete desc_copy;
  387|      4|          delete word_copy;
  388|      4|          return 0;
  389|      4|        } else {
  390|      0|          dp->next_homonym = hp;
  391|      0|        }
  392|      4|      } else {
  393|      2|        upcasehomonym = true;
  394|      2|      }
  395|      6|    }
  396|    276|    dp = dp->next;
  397|    276|  }
  398|  1.55k|  if (strcmp(hp->word, dp->word) == 0) {
  ------------------
  |  Branch (398:7): [True: 304, False: 1.25k]
  ------------------
  399|       |    // remove hidden onlyupcase homonym
  400|    304|    if (!onlyupcase) {
  ------------------
  |  Branch (400:9): [True: 182, False: 122]
  ------------------
  401|    182|      if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (401:11): [True: 0, False: 182]
  |  Branch (401:11): [True: 0, False: 182]
  ------------------
  402|      0|        release_flags(dp->astr, dp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  403|      0|        dp->astr = hp->astr;
  404|      0|        dp->alen = hp->alen;
  405|      0|        dp->var &= ~H_OPT_OWNFLAGS;
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  406|      0|        dp->var |= (hp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  407|      0|        free(hp);
  408|      0|        delete desc_copy;
  409|      0|        delete word_copy;
  410|      0|        return 0;
  411|    182|      } else if (!dp->astr && dp->alen == 0 &&
  ------------------
  |  Branch (411:18): [True: 182, False: 0]
  |  Branch (411:31): [True: 182, False: 0]
  ------------------
  412|    182|                 !hp->astr && hp->alen == 0) {
  ------------------
  |  Branch (412:18): [True: 182, False: 0]
  |  Branch (412:31): [True: 182, False: 0]
  ------------------
  413|       |        // word already exists with no flags, skip duplicate
  414|    182|        release_flags(hp->astr, hp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|    182|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  415|    182|        free(hp);
  416|    182|        delete desc_copy;
  417|    182|        delete word_copy;
  418|    182|        return 0;
  419|    182|      } else {
  420|      0|        dp->next_homonym = hp;
  421|      0|      }
  422|    182|    } else {
  423|    122|      upcasehomonym = true;
  424|    122|    }
  425|    304|  }
  426|  1.37k|  if (!upcasehomonym) {
  ------------------
  |  Branch (426:7): [True: 1.25k, False: 124]
  ------------------
  427|  1.25k|    dp->next = hp;
  428|  1.25k|  } else {
  429|       |    // remove hidden onlyupcase homonym
  430|    124|    release_flags(hp->astr, hp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|    124|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  431|    124|    free(hp);
  432|    124|  }
  433|       |
  434|  1.37k|  delete desc_copy;
  435|  1.37k|  delete word_copy;
  436|  1.37k|  return 0;
  437|  1.55k|}
_ZN7HashMgr27add_hidden_capitalized_wordERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiPtiPS7_i:
  444|  5.02k|                                         int captype) {
  445|  5.02k|  if (flags == nullptr)
  ------------------
  |  Branch (445:7): [True: 4.93k, False: 90]
  ------------------
  446|  4.93k|    flagslen = 0;
  447|       |
  448|       |  // add inner capitalized forms to handle the following allcap forms:
  449|       |  // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
  450|       |  // Allcaps with suffixes: CIA's -> CIA'S
  451|  5.02k|  if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
  ------------------
  |  |   95|  5.02k|#define HUHCAP 3
  ------------------
                if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
  ------------------
  |  |   96|  4.61k|#define HUHINITCAP 4
  ------------------
  |  Branch (451:8): [True: 413, False: 4.61k]
  |  Branch (451:31): [True: 1.72k, False: 2.89k]
  ------------------
  452|  2.89k|       ((captype == ALLCAP) && (flagslen != 0))) &&
  ------------------
  |  |   94|  2.89k|#define ALLCAP 2
  ------------------
  |  Branch (452:9): [True: 151, False: 2.74k]
  |  Branch (452:32): [True: 8, False: 143]
  ------------------
  453|  2.14k|      !((flagslen != 0) && TESTAFF(flags, forbiddenword, flagslen))) {
  ------------------
  |  |   99|      8|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 8]
  |  |  ------------------
  ------------------
  |  Branch (453:9): [True: 8, False: 2.13k]
  ------------------
  454|  2.14k|    unsigned short* flags2 = new unsigned short[flagslen + 1];
  455|  2.14k|    flags2[flagslen] = ONLYUPCASEFLAG;
  ------------------
  |  |  128|  2.14k|#define ONLYUPCASEFLAG 65511
  ------------------
  456|  2.14k|    if (flagslen) {
  ------------------
  |  Branch (456:9): [True: 8, False: 2.13k]
  ------------------
  457|      8|      memcpy(flags2, flags, flagslen * sizeof(unsigned short));
  458|      8|      std::sort(flags2, flags2 + flagslen + 1);
  459|      8|    }
  460|  2.14k|    if (utf8) {
  ------------------
  |  Branch (460:9): [True: 325, False: 1.81k]
  ------------------
  461|    325|      std::string st;
  462|    325|      std::vector<w_char> w;
  463|    325|      u8_u16(w, word);
  464|    325|      mkallsmall_utf(w, langnum);
  465|    325|      mkinitcap_utf(w, langnum);
  466|    325|      u16_u8(st, w);
  467|    325|      return add_word(st, wcl, flags2, flagslen + 1, dp, true, INITCAP, true);
  ------------------
  |  |   93|    325|#define INITCAP 1
  ------------------
  468|  1.81k|    } else {
  469|  1.81k|      std::string new_word(word);
  470|  1.81k|      mkallsmall(new_word, csconv);
  471|  1.81k|      mkinitcap(new_word, csconv);
  472|  1.81k|      int ret = add_word(new_word, wcl, flags2, flagslen + 1, dp, true, INITCAP, true);
  ------------------
  |  |   93|  1.81k|#define INITCAP 1
  ------------------
  473|  1.81k|      return ret;
  474|  1.81k|    }
  475|  2.14k|  }
  476|  2.88k|  return 0;
  477|  5.02k|}
_ZN7HashMgr20get_clen_and_captypeERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPiRNS0_6vectorI6w_charNS4_ISB_EEEE:
  480|  5.27k|int HashMgr::get_clen_and_captype(const std::string& word, int* captype, std::vector<w_char> &workbuf) {
  481|  5.27k|  int len;
  482|  5.27k|  if (utf8) {
  ------------------
  |  Branch (482:7): [True: 2.51k, False: 2.76k]
  ------------------
  483|  2.51k|    len = u8_u16(workbuf, word);
  484|  2.51k|    *captype = get_captype_utf8(workbuf, langnum);
  485|  2.76k|  } else {
  486|  2.76k|    len = word.size();
  487|  2.76k|    *captype = get_captype(word, csconv);
  488|  2.76k|  }
  489|  5.27k|  return len;
  490|  5.27k|}
_ZN7HashMgr20get_clen_and_captypeERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPi:
  492|  5.11k|int HashMgr::get_clen_and_captype(const std::string& word, int* captype) {
  493|  5.11k|  std::vector<w_char> workbuf;
  494|  5.11k|  return get_clen_and_captype(word, captype, workbuf);
  495|  5.11k|}
_ZN7HashMgr21remove_forbidden_flagERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  518|  6.57k|void HashMgr::remove_forbidden_flag(const std::string& word) {
  519|  6.57k|  struct hentry* dp = lookup(word.c_str(), word.size());
  520|  6.57k|  if (!dp)
  ------------------
  |  Branch (520:7): [True: 6.39k, False: 178]
  ------------------
  521|  6.39k|    return;
  522|    356|  while (dp) {
  ------------------
  |  Branch (522:10): [True: 178, False: 178]
  ------------------
  523|    178|    if (dp->astr && TESTAFF(dp->astr, forbiddenword, dp->alen)) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (523:9): [True: 0, False: 178]
  ------------------
  524|      0|      if (dp->alen == 1) {
  ------------------
  |  Branch (524:11): [True: 0, False: 0]
  ------------------
  525|      0|        release_flags(dp->astr, dp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  526|      0|        dp->astr = nullptr;
  527|      0|        dp->alen = 0;
  528|      0|        dp->var &= ~H_OPT_OWNFLAGS;
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  529|      0|      } else {
  530|      0|        auto newflags = new unsigned short[dp->alen - 1];
  531|      0|        int j = 0;
  532|      0|        for (int i = 0; i < dp->alen; i++) {
  ------------------
  |  Branch (532:25): [True: 0, False: 0]
  ------------------
  533|      0|          if (dp->astr[i] != forbiddenword)
  ------------------
  |  Branch (533:15): [True: 0, False: 0]
  ------------------
  534|      0|            newflags[j++] = dp->astr[i];
  535|      0|        }
  536|      0|        release_flags(dp->astr, dp->var & H_OPT_OWNFLAGS);
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  537|      0|        dp->astr = newflags;
  538|      0|        dp->alen = (short)j;
  539|      0|        dp->var |= H_OPT_OWNFLAGS;
  ------------------
  |  |   51|      0|#define H_OPT_OWNFLAGS (1 << 4) // astr is independently allocated?
  ------------------
  540|      0|      }
  541|      0|    }
  542|    178|    dp = dp->next_homonym;
  543|    178|  }
  544|    178|}
_ZN7HashMgr3addERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  547|  5.10k|int HashMgr::add(const std::string& word) {
  548|  5.10k|  remove_forbidden_flag(word);
  549|  5.10k|  int captype, al = 0;
  550|  5.10k|  unsigned short* flags = nullptr;
  551|  5.10k|  int wcl = get_clen_and_captype(word, &captype);
  552|  5.10k|  if (add_word(word, wcl, flags, al, nullptr, false, captype, true))
  ------------------
  |  Branch (552:7): [True: 250, False: 4.85k]
  ------------------
  553|    250|    return 1;
  554|  4.85k|  return add_hidden_capitalized_word(word, wcl, flags, al, nullptr, captype);
  555|  5.10k|}
_ZN7HashMgr14add_with_affixERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_:
  568|  1.46k|int HashMgr::add_with_affix(const std::string& word, const std::string& example) {
  569|       |  // detect captype and modify word length for UTF-8 encoding
  570|  1.46k|  struct hentry* dp = lookup(example.c_str(), example.size());
  571|  1.46k|  remove_forbidden_flag(word);
  572|  1.46k|  if (dp && dp->astr) {
  ------------------
  |  Branch (572:7): [True: 46, False: 1.41k]
  |  Branch (572:13): [True: 8, False: 38]
  ------------------
  573|      8|    int captype;
  574|      8|    int wcl = get_clen_and_captype(word, &captype);
  575|      8|    auto flags = new unsigned short[dp->alen];
  576|      8|    memcpy(flags, dp->astr, dp->alen * sizeof(unsigned short));
  577|      8|    if (add_word(word, wcl, flags, dp->alen, nullptr, false, captype, true))
  ------------------
  |  Branch (577:9): [True: 0, False: 8]
  ------------------
  578|      0|      return 1;
  579|      8|    return add_hidden_capitalized_word(word, wcl, flags, dp->alen, nullptr, captype);
  580|      8|  }
  581|  1.45k|  return 1;
  582|  1.46k|}
_ZNK7HashMgr14walk_hashtableERiP6hentry:
  586|  1.97M|struct hentry* HashMgr::walk_hashtable(int& col, struct hentry* hp) const {
  587|  1.97M|  if (hp && hp->next != nullptr)
  ------------------
  |  Branch (587:7): [True: 1.91M, False: 59.6k]
  |  Branch (587:13): [True: 146k, False: 1.76M]
  ------------------
  588|   146k|    return hp->next;
  589|  60.3M|  for (col++; col < (int)tableptr.size(); ++col) {
  ------------------
  |  Branch (589:15): [True: 60.2M, False: 59.6k]
  ------------------
  590|  60.2M|    if (tableptr[col])
  ------------------
  |  Branch (590:9): [True: 1.76M, False: 58.4M]
  ------------------
  591|  1.76M|      return tableptr[col];
  592|  60.2M|  }
  593|       |  // null at end and reset to start
  594|  59.6k|  col = -1;
  595|  59.6k|  return nullptr;
  596|  1.82M|}
_ZN7HashMgr11load_tablesEPKcS1_:
  599|     38|int HashMgr::load_tables(const char* tpath, const char* key) {
  600|       |  // open dictionary file
  601|     38|  FileMgr* dict = new FileMgr(tpath, key);
  602|       |
  603|       |  // first read the first line of file to get hash table size
  604|     38|  std::string ts;
  605|     38|  if (!dict->getline(ts)) {
  ------------------
  |  Branch (605:7): [True: 0, False: 38]
  ------------------
  606|      0|    fprintf(stderr, "error: empty dic file %s\n", tpath);
  607|      0|    delete dict;
  608|      0|    return 2;
  609|      0|  }
  610|     38|  mychomp(ts);
  611|       |
  612|       |  /* remove byte order mark */
  613|     38|  if (ts.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
  ------------------
  |  Branch (613:7): [True: 0, False: 38]
  ------------------
  614|      0|    ts.erase(0, 3);
  615|      0|  }
  616|       |
  617|     38|  int tablesize = atoi(ts.c_str());
  618|       |
  619|     38|  const int nExtra = 5 + USERWORD;
  ------------------
  |  |   57|     38|#define USERWORD 1000
  ------------------
  620|       |#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
  621|       |  // covers full-form uncompressed dictionaries (~7M for uk_UA expanded)
  622|       |  const int max_allowed = 10000000;
  623|       |#else
  624|     38|  const int max_allowed = (10000 - 1 - nExtra) / int(sizeof(struct hentry*));
  625|     38|#endif
  626|       |
  627|     38|  if (tablesize <= 0 || tablesize >= max_allowed) {
  ------------------
  |  Branch (627:7): [True: 0, False: 38]
  |  Branch (627:25): [True: 0, False: 38]
  ------------------
  628|      0|    fprintf(stderr,
  629|      0|            "error: %s: line 1: missing or bad word count in the dic file\n",
  630|      0|            tpath);
  631|      0|    delete dict;
  632|      0|    return 4;
  633|      0|  }
  634|     38|  tablesize += nExtra;
  635|     38|  if ((tablesize & 1) == 0)
  ------------------
  |  Branch (635:7): [True: 18, False: 20]
  ------------------
  636|     18|    tablesize++;
  637|       |
  638|       |  // allocate the hash table
  639|     38|  tableptr.resize(tablesize, nullptr);
  640|       |
  641|       |  // loop through all words on much list and add to hash
  642|       |  // table and create word and affix strings
  643|       |
  644|     38|  std::vector<w_char> workbuf;
  645|       |
  646|     38|  int nLineCount(0);
  647|    198|  while (dict->getline(ts)) {
  ------------------
  |  Branch (647:10): [True: 160, False: 38]
  ------------------
  648|    160|    ++nLineCount;
  649|    160|#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  650|       |    // limit words loaded to avoid O(n^2) hash chain walk timeout
  651|    160|    if (nLineCount >= tablesize)
  ------------------
  |  Branch (651:9): [True: 0, False: 160]
  ------------------
  652|      0|      break;
  653|    160|#endif
  654|    160|    mychomp(ts);
  655|       |    // split each line into word and morphological description
  656|    160|    size_t dp_pos = 0;
  657|    160|    while ((dp_pos = ts.find(':', dp_pos)) != std::string::npos) {
  ------------------
  |  Branch (657:12): [True: 4, False: 156]
  ------------------
  658|      4|      if ((dp_pos > 3) && (ts[dp_pos - 3] == ' ' || ts[dp_pos - 3] == '\t')) {
  ------------------
  |  Branch (658:11): [True: 4, False: 0]
  |  Branch (658:28): [True: 0, False: 4]
  |  Branch (658:53): [True: 4, False: 0]
  ------------------
  659|      4|        for (dp_pos -= 3; dp_pos > 0 && (ts[dp_pos-1] == ' ' || ts[dp_pos-1] == '\t'); --dp_pos)
  ------------------
  |  Branch (659:27): [True: 4, False: 0]
  |  Branch (659:42): [True: 0, False: 4]
  |  Branch (659:65): [True: 0, False: 4]
  ------------------
  660|      0|          ;
  661|      4|        if (dp_pos == 0) {  // missing word
  ------------------
  |  Branch (661:13): [True: 0, False: 4]
  ------------------
  662|      0|          dp_pos = std::string::npos;
  663|      4|        } else {
  664|      4|          ++dp_pos;
  665|      4|        }
  666|      4|        break;
  667|      4|      }
  668|      0|      ++dp_pos;
  669|      0|    }
  670|       |
  671|       |    // tabulator is the old morphological field separator
  672|    160|    size_t dp2_pos = ts.find('\t');
  673|    160|    if (dp2_pos != std::string::npos && (dp_pos == std::string::npos || dp2_pos < dp_pos)) {
  ------------------
  |  Branch (673:9): [True: 4, False: 156]
  |  Branch (673:42): [True: 0, False: 4]
  |  Branch (673:73): [True: 4, False: 0]
  ------------------
  674|      4|      dp_pos = dp2_pos + 1;
  675|      4|    }
  676|       |
  677|    160|    std::string dp;
  678|    160|    if (dp_pos != std::string::npos) {
  ------------------
  |  Branch (678:9): [True: 4, False: 156]
  ------------------
  679|      4|      dp.assign(ts.substr(dp_pos));
  680|      4|      ts.resize(dp_pos - 1);
  681|      4|    }
  682|       |
  683|       |    // split each line into word and affix char strings
  684|       |    // "\/" signs slash in words (not affix separator)
  685|       |    // "/" at beginning of the line is word character (not affix separator)
  686|    160|    size_t ap_pos = ts.find('/');
  687|    160|    while (ap_pos != std::string::npos) {
  ------------------
  |  Branch (687:12): [True: 82, False: 78]
  ------------------
  688|     82|      if (ap_pos == 0) {
  ------------------
  |  Branch (688:11): [True: 0, False: 82]
  ------------------
  689|      0|        ++ap_pos;
  690|      0|        continue;
  691|     82|      } else if (ts[ap_pos - 1] != '\\')
  ------------------
  |  Branch (691:18): [True: 82, False: 0]
  ------------------
  692|     82|        break;
  693|       |      // replace "\/" with "/"
  694|      0|      ts.erase(ap_pos - 1, 1);
  695|      0|      ap_pos = ts.find('/', ap_pos);
  696|      0|    }
  697|       |
  698|    160|    unsigned short* flags;
  699|    160|    int al;
  700|    160|    if (ap_pos != std::string::npos && ap_pos != ts.size()) {
  ------------------
  |  Branch (700:9): [True: 82, False: 78]
  |  Branch (700:40): [True: 82, False: 0]
  ------------------
  701|     82|      std::string ap(ts.substr(ap_pos + 1));
  702|     82|      ts.resize(ap_pos);
  703|     82|      if (!aliasf.empty()) {
  ------------------
  |  Branch (703:11): [True: 2, False: 80]
  ------------------
  704|      2|        int index = atoi(ap.c_str());
  705|      2|        al = get_aliasf(index, &flags, dict);
  706|      2|        if (!al) {
  ------------------
  |  Branch (706:13): [True: 0, False: 2]
  ------------------
  707|      0|          HUNSPELL_WARNING(stderr, "error: line %d: bad flag vector alias\n",
  708|      0|                           dict->getlinenum());
  709|      0|        }
  710|     80|      } else {
  711|     80|        al = decode_flags(&flags, ap, dict);
  712|     80|        if (al == -1) {
  ------------------
  |  Branch (712:13): [True: 0, False: 80]
  ------------------
  713|      0|          HUNSPELL_WARNING(stderr, "Can't allocate memory.\n");
  714|      0|          delete dict;
  715|      0|          return 6;
  716|      0|        }
  717|     80|        std::sort(flags, flags + al);
  718|     80|      }
  719|     82|    } else {
  720|     78|      al = 0;
  721|     78|      flags = nullptr;
  722|     78|    }
  723|       |
  724|    160|    int captype;
  725|    160|    int wcl = get_clen_and_captype(ts, &captype, workbuf);
  726|    160|    const std::string* dp_str = dp.empty() ? nullptr : &dp;
  ------------------
  |  Branch (726:33): [True: 156, False: 4]
  ------------------
  727|       |    // add the word and its index plus its capitalized form optionally
  728|    160|    bool own = aliasf.empty();
  729|    160|    if (add_word(ts, wcl, flags, al, dp_str, false, captype, own) ||
  ------------------
  |  Branch (729:9): [True: 0, False: 160]
  ------------------
  730|    160|        add_hidden_capitalized_word(ts, wcl, flags, al, dp_str, captype)) {
  ------------------
  |  Branch (730:9): [True: 0, False: 160]
  ------------------
  731|      0|      delete dict;
  732|      0|      return 5;
  733|      0|    }
  734|    160|  }
  735|       |
  736|     38|  int ret(0);
  737|       |
  738|       |  // reject ludicrous tablesizes
  739|     38|  if (tablesize > 8192 + nExtra && tablesize > nLineCount * 10 + nExtra) {
  ------------------
  |  Branch (739:7): [True: 0, False: 38]
  |  Branch (739:36): [True: 0, False: 0]
  ------------------
  740|      0|    HUNSPELL_WARNING(stderr, ".dic initial approximate word count line value of %d is too large for %d lines\n", tablesize, nLineCount);
  741|      0|    ret = 3;
  742|      0|  }
  743|       |
  744|     38|  delete dict;
  745|     38|  return ret;
  746|     38|}
_ZNK7HashMgr4hashEPKcm:
  750|   505M|int HashMgr::hash(const char* word, size_t len) const {
  751|   505M|  unsigned long hv = 0;
  752|   505M|  size_t i = 0;
  753|  2.50G|  while (i < 4 && i < len)
  ------------------
  |  Branch (753:10): [True: 2.01G, False: 485M]
  |  Branch (753:19): [True: 1.99G, False: 20.4M]
  ------------------
  754|  1.99G|    hv = (hv << 8) | word[i++];
  755|  11.1G|  while (i < len) {
  ------------------
  |  Branch (755:10): [True: 10.6G, False: 505M]
  ------------------
  756|  10.6G|    ROTATE(hv, ROTATE_LEN);
  ------------------
  |  |   44|  10.6G|  (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q)) - 1));
  ------------------
  757|  10.6G|    hv ^= word[i++];
  758|  10.6G|  }
  759|   505M|  return (unsigned long)hv % tableptr.size();
  760|   505M|}
_ZNK7HashMgr12decode_flagsEPPtRKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEP7FileMgr:
  762|    100|int HashMgr::decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const {
  763|    100|  int len;
  764|    100|  if (flags.empty()) {
  ------------------
  |  Branch (764:7): [True: 0, False: 100]
  ------------------
  765|      0|    *result = nullptr;
  766|      0|    return 0;
  767|      0|  }
  768|    100|  switch (flag_mode) {
  769|      0|    case FLAG_LONG: {  // two-character flags (1x2yZz -> 1x 2y Zz)
  ------------------
  |  Branch (769:5): [True: 0, False: 100]
  ------------------
  770|      0|      len = flags.size();
  771|      0|      if ((len & 1) == 1 && af != nullptr)
  ------------------
  |  Branch (771:11): [True: 0, False: 0]
  |  Branch (771:29): [True: 0, False: 0]
  ------------------
  772|      0|        HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n",
  773|      0|                         af->getlinenum());
  774|      0|      len >>= 1;
  775|      0|      *result = new unsigned short[len];
  776|      0|      for (int i = 0; i < len; i++) {
  ------------------
  |  Branch (776:23): [True: 0, False: 0]
  ------------------
  777|      0|        unsigned short flag = ((unsigned short)((unsigned char)flags[i << 1]) << 8) |
  778|      0|                              ((unsigned short)((unsigned char)flags[(i << 1) | 1]));
  779|       |
  780|      0|        (*result)[i] = flag;
  781|      0|      }
  782|      0|      break;
  783|      0|    }
  784|      0|    case FLAG_NUM: {  // decimal numbers separated by comma (4521,23,233 -> 4521
  ------------------
  |  Branch (784:5): [True: 0, False: 100]
  ------------------
  785|       |                      // 23 233)
  786|      0|      len = int(1 + std::count_if(flags.begin(), flags.end(), [](char c) { return c == ','; }));
  787|      0|      *result = new unsigned short[len];
  788|      0|      unsigned short* dest = *result;
  789|      0|      const char* src = flags.c_str();
  790|      0|      for (size_t p = 0; p < flags.size(); ++p) {
  ------------------
  |  Branch (790:26): [True: 0, False: 0]
  ------------------
  791|      0|        if (flags[p] == ',') {
  ------------------
  |  Branch (791:13): [True: 0, False: 0]
  ------------------
  792|      0|          int i = atoi(src);
  793|      0|          if ((i > std::numeric_limits<unsigned short>::max() || i < 0) && af != nullptr) {
  ------------------
  |  Branch (793:16): [True: 0, False: 0]
  |  Branch (793:66): [True: 0, False: 0]
  |  Branch (793:76): [True: 0, False: 0]
  ------------------
  794|      0|            HUNSPELL_WARNING(
  795|      0|                stderr, "error: line %d: flag id %d is out of range\n",
  796|      0|                af->getlinenum(), i);
  797|      0|             i = 0;
  798|      0|          }
  799|      0|          *dest = (unsigned short)i;
  800|      0|          if (*dest == 0 && af != nullptr)
  ------------------
  |  Branch (800:15): [True: 0, False: 0]
  |  Branch (800:29): [True: 0, False: 0]
  ------------------
  801|      0|            HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
  802|      0|                             af->getlinenum());
  803|      0|          src = flags.c_str() + p + 1;
  804|      0|          dest++;
  805|      0|        }
  806|      0|      }
  807|      0|      int i = atoi(src);
  808|      0|      if ((i > std::numeric_limits<unsigned short>::max() || i < 0) && af) {
  ------------------
  |  Branch (808:12): [True: 0, False: 0]
  |  Branch (808:62): [True: 0, False: 0]
  |  Branch (808:72): [True: 0, False: 0]
  ------------------
  809|      0|        HUNSPELL_WARNING(stderr,
  810|      0|                         "error: line %d: flag id %d is out of range\n",
  811|      0|                         af->getlinenum(), i);
  812|      0|        i = 0;
  813|      0|      }
  814|      0|      *dest = (unsigned short)i;
  815|      0|      if (*dest == 0 && af)
  ------------------
  |  Branch (815:11): [True: 0, False: 0]
  |  Branch (815:25): [True: 0, False: 0]
  ------------------
  816|      0|        HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
  817|      0|                         af->getlinenum());
  818|      0|      break;
  819|      0|    }
  820|      0|    case FLAG_UNI: {  // UTF-8 characters
  ------------------
  |  Branch (820:5): [True: 0, False: 100]
  ------------------
  821|      0|      std::vector<w_char> w;
  822|      0|      u8_u16(w, flags);
  823|      0|      len = w.size();
  824|      0|      *result = new unsigned short[len];
  825|      0|#if defined(_WIN32) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__))  || defined(__LITTLE_ENDIAN__)
  826|      0|      memcpy(*result, w.data(), len * sizeof(unsigned short));
  827|       |#else
  828|       |      unsigned short* dest = *result;
  829|       |      for (const w_char wc : w) {
  830|       |        *dest = (unsigned short)wc;
  831|       |        dest++;
  832|       |      }
  833|       |#endif
  834|      0|      break;
  835|      0|    }
  836|    100|    default: {  // Ispell's one-character flags (erfg -> e r f g)
  ------------------
  |  Branch (836:5): [True: 100, False: 0]
  ------------------
  837|    100|      len = flags.size();
  838|    100|      *result = new unsigned short[len];
  839|    100|      unsigned short* dest = *result;
  840|    118|      for (const char flag : flags) {
  ------------------
  |  Branch (840:28): [True: 118, False: 100]
  ------------------
  841|    118|        *dest = (unsigned char)flag;
  842|    118|        dest++;
  843|    118|      }
  844|    100|    }
  845|    100|  }
  846|    100|  return len;
  847|    100|}
_ZNK7HashMgr11decode_flagERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  923|     92|unsigned short HashMgr::decode_flag(const std::string& f) const {
  924|     92|  unsigned short s = 0;
  925|     92|  int i;
  926|     92|  switch (flag_mode) {
  927|      0|    case FLAG_LONG:
  ------------------
  |  Branch (927:5): [True: 0, False: 92]
  ------------------
  928|      0|      if (f.size() >= 2)
  ------------------
  |  Branch (928:11): [True: 0, False: 0]
  ------------------
  929|      0|        s = ((unsigned short)((unsigned char)f[0]) << 8) | ((unsigned short)((unsigned char)f[1]));
  930|      0|      break;
  931|      0|    case FLAG_NUM:
  ------------------
  |  Branch (931:5): [True: 0, False: 92]
  ------------------
  932|      0|      i = atoi(f.c_str());
  933|      0|      if (i > std::numeric_limits<unsigned short>::max() || i < 0) {
  ------------------
  |  Branch (933:11): [True: 0, False: 0]
  |  Branch (933:61): [True: 0, False: 0]
  ------------------
  934|      0|        HUNSPELL_WARNING(stderr, "error: flag id %d is out of range\n", i);
  935|      0|        i = 0;
  936|      0|      }
  937|      0|      s = (unsigned short)i;
  938|      0|      break;
  939|      0|    case FLAG_UNI: {
  ------------------
  |  Branch (939:5): [True: 0, False: 92]
  ------------------
  940|      0|      std::vector<w_char> w;
  941|      0|      u8_u16(w, f);
  942|      0|      if (!w.empty())
  ------------------
  |  Branch (942:11): [True: 0, False: 0]
  ------------------
  943|      0|        s = (unsigned short)w[0];
  944|      0|      break;
  945|      0|    }
  946|     92|    default:
  ------------------
  |  Branch (946:5): [True: 92, False: 0]
  ------------------
  947|     92|      if (!f.empty())
  ------------------
  |  Branch (947:11): [True: 92, False: 0]
  ------------------
  948|     92|        s = (unsigned char)f[0];
  949|     92|  }
  950|     92|  if (s == 0)
  ------------------
  |  Branch (950:7): [True: 0, False: 92]
  ------------------
  951|      0|    HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n");
  952|     92|  return s;
  953|     92|}
_ZN7HashMgr11load_configEPKcS1_:
  989|     38|int HashMgr::load_config(const char* affpath, const char* key) {
  990|     38|  int firstline = 1;
  991|       |
  992|       |  // open the affix file
  993|     38|  FileMgr* afflst = new FileMgr(affpath, key);
  994|       |
  995|       |  // read in each line ignoring any that do not
  996|       |  // start with a known line type indicator
  997|       |
  998|     38|  std::string line;
  999|    922|  while (afflst->getline(line)) {
  ------------------
  |  Branch (999:10): [True: 886, False: 36]
  ------------------
 1000|    886|    mychomp(line);
 1001|       |
 1002|       |    /* remove byte order mark */
 1003|    886|    if (firstline) {
  ------------------
  |  Branch (1003:9): [True: 38, False: 848]
  ------------------
 1004|     38|      firstline = 0;
 1005|     38|      if (line.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
  ------------------
  |  Branch (1005:11): [True: 0, False: 38]
  ------------------
 1006|      0|        line.erase(0, 3);
 1007|      0|      }
 1008|     38|    }
 1009|       |
 1010|       |    /* parse in the try string */
 1011|    886|    if ((line.compare(0, 4, "FLAG", 4) == 0) && line.size() > 4 && isspace(line[4])) {
  ------------------
  |  Branch (1011:9): [True: 0, False: 886]
  |  Branch (1011:49): [True: 0, False: 0]
  |  Branch (1011:68): [True: 0, False: 0]
  ------------------
 1012|      0|      if (flag_mode != FLAG_CHAR) {
  ------------------
  |  Branch (1012:11): [True: 0, False: 0]
  ------------------
 1013|      0|        HUNSPELL_WARNING(stderr,
 1014|      0|                         "error: line %d: multiple definitions of the FLAG "
 1015|      0|                         "affix file parameter\n",
 1016|      0|                         afflst->getlinenum());
 1017|      0|      }
 1018|      0|      if (line.find("long") != std::string::npos)
  ------------------
  |  Branch (1018:11): [True: 0, False: 0]
  ------------------
 1019|      0|        flag_mode = FLAG_LONG;
 1020|      0|      if (line.find("num") != std::string::npos)
  ------------------
  |  Branch (1020:11): [True: 0, False: 0]
  ------------------
 1021|      0|        flag_mode = FLAG_NUM;
 1022|      0|      if (line.find("UTF-8") != std::string::npos)
  ------------------
  |  Branch (1022:11): [True: 0, False: 0]
  ------------------
 1023|      0|        flag_mode = FLAG_UNI;
 1024|      0|      if (flag_mode == FLAG_CHAR) {
  ------------------
  |  Branch (1024:11): [True: 0, False: 0]
  ------------------
 1025|      0|        HUNSPELL_WARNING(
 1026|      0|            stderr,
 1027|      0|            "error: line %d: FLAG needs `num', `long' or `UTF-8' parameter\n",
 1028|      0|            afflst->getlinenum());
 1029|      0|      }
 1030|      0|    }
 1031|       |
 1032|    886|    if (line.compare(0, 13, "FORBIDDENWORD", 13) == 0) {
  ------------------
  |  Branch (1032:9): [True: 2, False: 884]
  ------------------
 1033|      2|      std::string st;
 1034|      2|      if (!parse_string(line, st, afflst->getlinenum())) {
  ------------------
  |  Branch (1034:11): [True: 0, False: 2]
  ------------------
 1035|      0|        delete afflst;
 1036|      0|        return 1;
 1037|      0|      }
 1038|      2|      forbiddenword = decode_flag(st);
 1039|      2|    }
 1040|       |
 1041|    886|    if (line.compare(0, 3, "SET", 3) == 0) {
  ------------------
  |  Branch (1041:9): [True: 18, False: 868]
  ------------------
 1042|     18|      if (!parse_string(line, enc, afflst->getlinenum())) {
  ------------------
  |  Branch (1042:11): [True: 0, False: 18]
  ------------------
 1043|      0|        delete afflst;
 1044|      0|        return 1;
 1045|      0|      }
 1046|     18|      if (enc == "UTF-8") {
  ------------------
  |  Branch (1046:11): [True: 18, False: 0]
  ------------------
 1047|     18|        utf8 = 1;
 1048|     18|      } else
 1049|      0|        csconv = get_current_cs(enc);
 1050|     18|    }
 1051|       |
 1052|    886|    if (line.compare(0, 4, "LANG", 4) == 0) {
  ------------------
  |  Branch (1052:9): [True: 2, False: 884]
  ------------------
 1053|      2|      if (!parse_string(line, lang, afflst->getlinenum())) {
  ------------------
  |  Branch (1053:11): [True: 0, False: 2]
  ------------------
 1054|      0|        delete afflst;
 1055|      0|        return 1;
 1056|      0|      }
 1057|      2|      langnum = get_lang_num(lang);
 1058|      2|    }
 1059|       |
 1060|       |    /* parse in the ignored characters (for example, Arabic optional diacritics
 1061|       |     * characters */
 1062|    886|    if (line.compare(0, 6, "IGNORE", 6) == 0) {
  ------------------
  |  Branch (1062:9): [True: 4, False: 882]
  ------------------
 1063|      4|      if (!parse_array(line, ignorechars, ignorechars_utf16,
  ------------------
  |  Branch (1063:11): [True: 0, False: 4]
  ------------------
 1064|      4|                       utf8, afflst->getlinenum())) {
 1065|      0|        delete afflst;
 1066|      0|        return 1;
 1067|      0|      }
 1068|      4|    }
 1069|       |
 1070|    886|    if ((line.compare(0, 2, "AF", 2) == 0) && line.size() > 2 && isspace(line[2])) {
  ------------------
  |  Branch (1070:9): [True: 2, False: 884]
  |  Branch (1070:47): [True: 2, False: 0]
  |  Branch (1070:66): [True: 2, False: 0]
  ------------------
 1071|      2|      if (!parse_aliasf(line, afflst)) {
  ------------------
  |  Branch (1071:11): [True: 0, False: 2]
  ------------------
 1072|      0|        delete afflst;
 1073|      0|        return 1;
 1074|      0|      }
 1075|      2|    }
 1076|       |
 1077|    886|    if ((line.compare(0, 2, "AM", 2) == 0) && line.size() > 2 && isspace(line[2])) {
  ------------------
  |  Branch (1077:9): [True: 0, False: 886]
  |  Branch (1077:47): [True: 0, False: 0]
  |  Branch (1077:66): [True: 0, False: 0]
  ------------------
 1078|      0|      if (!parse_aliasm(line, afflst)) {
  ------------------
  |  Branch (1078:11): [True: 0, False: 0]
  ------------------
 1079|      0|        delete afflst;
 1080|      0|        return 1;
 1081|      0|      }
 1082|      0|    }
 1083|       |
 1084|    886|    if (line.compare(0, 15, "COMPLEXPREFIXES", 15) == 0)
  ------------------
  |  Branch (1084:9): [True: 2, False: 884]
  ------------------
 1085|      2|      complexprefixes = 1;
 1086|       |
 1087|       |    /* parse in the typical fault correcting table */
 1088|    886|    if (line.compare(0, 3, "REP", 3) == 0) {
  ------------------
  |  Branch (1088:9): [True: 6, False: 880]
  ------------------
 1089|      6|      if (!parse_reptable(line, afflst)) {
  ------------------
  |  Branch (1089:11): [True: 0, False: 6]
  ------------------
 1090|      0|        delete afflst;
 1091|      0|        return 1;
 1092|      0|      }
 1093|      6|    }
 1094|       |
 1095|       |    // don't check the full affix file, yet
 1096|    886|    if (((line.compare(0, 3, "SFX", 3) == 0) ||
  ------------------
  |  Branch (1096:10): [True: 42, False: 844]
  ------------------
 1097|    844|         (line.compare(0, 3, "PFX", 3) == 0)) &&
  ------------------
  |  Branch (1097:10): [True: 24, False: 820]
  ------------------
 1098|     66|            line.size() > 3 && isspace(line[3]) &&
  ------------------
  |  Branch (1098:13): [True: 66, False: 0]
  |  Branch (1098:32): [True: 66, False: 0]
  ------------------
 1099|     66|            !reptable.empty()) // (REP table is in the end of Afrikaans aff file)
  ------------------
  |  Branch (1099:13): [True: 2, False: 64]
  ------------------
 1100|      2|      break;
 1101|    886|  }
 1102|       |
 1103|     38|  delete afflst;
 1104|     38|  return 0;
 1105|     38|}
_ZN7HashMgr12parse_aliasfERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgr:
 1108|      2|bool HashMgr::parse_aliasf(const std::string& line, FileMgr* af) {
 1109|      2|  if (!aliasf.empty()) {
  ------------------
  |  Branch (1109:7): [True: 0, False: 2]
  ------------------
 1110|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
 1111|      0|                     af->getlinenum());
 1112|      0|    return false;
 1113|      0|  }
 1114|      2|  int i = 0, np = 0, numaliasf = 0;
 1115|      2|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 1116|      6|  while (start_piece != line.end()) {
  ------------------
  |  Branch (1116:10): [True: 4, False: 2]
  ------------------
 1117|      4|    switch (i) {
 1118|      2|      case 0: {
  ------------------
  |  Branch (1118:7): [True: 2, False: 2]
  ------------------
 1119|      2|        np++;
 1120|      2|        break;
 1121|      0|      }
 1122|      2|      case 1: {
  ------------------
  |  Branch (1122:7): [True: 2, False: 2]
  ------------------
 1123|      2|        numaliasf = atoi(std::string(start_piece, iter).c_str());
 1124|      2|        if (numaliasf < 1) {
  ------------------
  |  Branch (1124:13): [True: 0, False: 2]
  ------------------
 1125|      0|          aliasf.clear();
 1126|      0|          aliasflen.clear();
 1127|      0|          HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
 1128|      0|                           af->getlinenum());
 1129|      0|          return false;
 1130|      0|        }
 1131|      2|        aliasf.reserve(std::min(numaliasf, 16384));
 1132|      2|        aliasflen.reserve(std::min(numaliasf, 16384));
 1133|      2|        np++;
 1134|      2|        break;
 1135|      2|      }
 1136|      0|      default:
  ------------------
  |  Branch (1136:7): [True: 0, False: 4]
  ------------------
 1137|      0|        break;
 1138|      4|    }
 1139|      4|    ++i;
 1140|      4|    start_piece = mystrsep(line, iter);
 1141|      4|  }
 1142|      2|  if (np != 2) {
  ------------------
  |  Branch (1142:7): [True: 0, False: 2]
  ------------------
 1143|      0|    aliasf.clear();
 1144|      0|    aliasflen.clear();
 1145|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
 1146|      0|                     af->getlinenum());
 1147|      0|    return false;
 1148|      0|  }
 1149|       |
 1150|       |  /* now parse the numaliasf lines to read in the remainder of the table */
 1151|      6|  for (int j = 0; j < numaliasf; ++j) {
  ------------------
  |  Branch (1151:19): [True: 4, False: 2]
  ------------------
 1152|      4|    std::string nl;
 1153|      4|    unsigned short* alias = nullptr;
 1154|      4|    unsigned aliaslen = 0;
 1155|      4|    i = 0;
 1156|      4|    if (af->getline(nl)) {
  ------------------
  |  Branch (1156:9): [True: 4, False: 0]
  ------------------
 1157|      4|      mychomp(nl);
 1158|      4|      iter = nl.begin();
 1159|      4|      start_piece = mystrsep(nl, iter);
 1160|      4|      bool errored = false;
 1161|     12|      while (!errored && start_piece != nl.end()) {
  ------------------
  |  Branch (1161:14): [True: 12, False: 0]
  |  Branch (1161:14): [True: 8, False: 4]
  |  Branch (1161:26): [True: 8, False: 4]
  ------------------
 1162|      8|        switch (i) {
 1163|      4|          case 0: {
  ------------------
  |  Branch (1163:11): [True: 4, False: 4]
  ------------------
 1164|      4|            if (nl.compare(start_piece - nl.begin(), 2, "AF", 2) != 0) {
  ------------------
  |  Branch (1164:17): [True: 0, False: 4]
  ------------------
 1165|      0|              errored = true;
 1166|      0|              break;
 1167|      0|            }
 1168|      4|            break;
 1169|      4|          }
 1170|      4|          case 1: {
  ------------------
  |  Branch (1170:11): [True: 4, False: 4]
  ------------------
 1171|      4|            std::string piece(start_piece, iter);
 1172|      4|            aliaslen =
 1173|      4|                (unsigned short)decode_flags(&alias, piece, af);
 1174|      4|            std::sort(alias, alias + aliaslen);
 1175|      4|            break;
 1176|      4|          }
 1177|      0|          default:
  ------------------
  |  Branch (1177:11): [True: 0, False: 8]
  ------------------
 1178|      0|            break;
 1179|      8|        }
 1180|      8|        ++i;
 1181|      8|        start_piece = mystrsep(nl, iter);
 1182|      8|      }
 1183|      4|    }
 1184|      4|    if (!alias) {
  ------------------
  |  Branch (1184:9): [True: 0, False: 4]
  ------------------
 1185|      0|      for (int k = 0; k < j; ++k) {
  ------------------
  |  Branch (1185:23): [True: 0, False: 0]
  ------------------
 1186|      0|        delete[] aliasf[k];
 1187|      0|      }
 1188|      0|      aliasf.clear();
 1189|      0|      aliasflen.clear();
 1190|      0|      HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 1191|      0|                       af->getlinenum());
 1192|      0|      return false;
 1193|      0|    }
 1194|       |
 1195|      4|    aliasf.push_back(alias);
 1196|      4|    aliasflen.push_back(aliaslen);
 1197|      4|  }
 1198|      2|  return true;
 1199|      2|}
_ZNK7HashMgr9is_aliasfEv:
 1201|     44|int HashMgr::is_aliasf() const {
 1202|     44|  return !aliasf.empty();
 1203|     44|}
_ZNK7HashMgr10get_aliasfEiPPtP7FileMgr:
 1205|      4|int HashMgr::get_aliasf(int index, unsigned short** fvec, FileMgr* af) const {
 1206|      4|  if (index > 0 && static_cast<size_t>(index) <= aliasflen.size()) {
  ------------------
  |  Branch (1206:7): [True: 4, False: 0]
  |  Branch (1206:20): [True: 4, False: 0]
  ------------------
 1207|      4|    *fvec = aliasf[index - 1];
 1208|      4|    return aliasflen[index - 1];
 1209|      4|  }
 1210|      0|  HUNSPELL_WARNING(stderr, "error: line %d: bad flag alias index: %d\n",
 1211|      0|                   af->getlinenum(), index);
 1212|      0|  *fvec = nullptr;
 1213|      0|  return 0;
 1214|      4|}
_ZNK7HashMgr9is_aliasmEv:
 1310|     32|int HashMgr::is_aliasm() const {
 1311|     32|  return !aliasm.empty();
 1312|     32|}
_ZN7HashMgr14parse_reptableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP7FileMgr:
 1322|      6|bool HashMgr::parse_reptable(const std::string& line, FileMgr* af) {
 1323|      6|  if (!reptable.empty()) {
  ------------------
  |  Branch (1323:7): [True: 0, False: 6]
  ------------------
 1324|      0|    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
 1325|      0|                     af->getlinenum());
 1326|      0|    return false;
 1327|      0|  }
 1328|      6|  int numrep = -1, i = 0, np = 0;
 1329|      6|  auto iter = line.begin(), start_piece = mystrsep(line, iter);
 1330|     18|  while (start_piece != line.end()) {
  ------------------
  |  Branch (1330:10): [True: 12, False: 6]
  ------------------
 1331|     12|    switch (i) {
 1332|      6|      case 0: {
  ------------------
  |  Branch (1332:7): [True: 6, False: 6]
  ------------------
 1333|      6|        np++;
 1334|      6|        break;
 1335|      0|      }
 1336|      6|      case 1: {
  ------------------
  |  Branch (1336:7): [True: 6, False: 6]
  ------------------
 1337|      6|        numrep = atoi(std::string(start_piece, iter).c_str());
 1338|      6|        if (numrep < 1) {
  ------------------
  |  Branch (1338:13): [True: 0, False: 6]
  ------------------
 1339|      0|          HUNSPELL_WARNING(stderr, "error: line %d: incorrect entry number\n",
 1340|      0|                           af->getlinenum());
 1341|      0|          return false;
 1342|      0|        }
 1343|      6|        reptable.reserve(std::min(numrep, 16384));
 1344|      6|        np++;
 1345|      6|        break;
 1346|      6|      }
 1347|      0|      default:
  ------------------
  |  Branch (1347:7): [True: 0, False: 12]
  ------------------
 1348|      0|        break;
 1349|     12|    }
 1350|     12|    ++i;
 1351|     12|    start_piece = mystrsep(line, iter);
 1352|     12|  }
 1353|      6|  if (np != 2) {
  ------------------
  |  Branch (1353:7): [True: 0, False: 6]
  ------------------
 1354|      0|    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
 1355|      0|                     af->getlinenum());
 1356|      0|    return false;
 1357|      0|  }
 1358|       |
 1359|       |  /* now parse the numrep lines to read in the remainder of the table */
 1360|     12|  for (int j = 0; j < numrep; ++j) {
  ------------------
  |  Branch (1360:19): [True: 6, False: 6]
  ------------------
 1361|      6|    std::string nl;
 1362|      6|    reptable.emplace_back();
 1363|      6|    int type = 0;
 1364|      6|    if (af->getline(nl)) {
  ------------------
  |  Branch (1364:9): [True: 6, False: 0]
  ------------------
 1365|      6|      mychomp(nl);
 1366|      6|      iter = nl.begin();
 1367|      6|      i = 0;
 1368|      6|      start_piece = mystrsep(nl, iter);
 1369|      6|      bool errored = false;
 1370|     24|      while (!errored && start_piece != nl.end()) {
  ------------------
  |  Branch (1370:14): [True: 24, False: 0]
  |  Branch (1370:14): [True: 18, False: 6]
  |  Branch (1370:26): [True: 18, False: 6]
  ------------------
 1371|     18|        switch (i) {
 1372|      6|          case 0: {
  ------------------
  |  Branch (1372:11): [True: 6, False: 12]
  ------------------
 1373|      6|            if (nl.compare(start_piece - nl.begin(), 3, "REP", 3) != 0) {
  ------------------
  |  Branch (1373:17): [True: 0, False: 6]
  ------------------
 1374|      0|              errored = true;
 1375|      0|              break;
 1376|      0|            }
 1377|      6|            break;
 1378|      6|          }
 1379|      6|          case 1: {
  ------------------
  |  Branch (1379:11): [True: 6, False: 12]
  ------------------
 1380|      6|            if (*start_piece == '^')
  ------------------
  |  Branch (1380:17): [True: 0, False: 6]
  ------------------
 1381|      0|              type = 1;
 1382|      6|            reptable.back().pattern.assign(start_piece + type, iter);
 1383|      6|            mystrrep(reptable.back().pattern, "_", " ");
 1384|      6|            if (!reptable.back().pattern.empty() && reptable.back().pattern[reptable.back().pattern.size() - 1] == '$') {
  ------------------
  |  Branch (1384:17): [True: 6, False: 0]
  |  Branch (1384:53): [True: 0, False: 6]
  ------------------
 1385|      0|              type += 2;
 1386|      0|              reptable.back().pattern.resize(reptable.back().pattern.size() - 1);
 1387|      0|            }
 1388|      6|            break;
 1389|      6|          }
 1390|      6|          case 2: {
  ------------------
  |  Branch (1390:11): [True: 6, False: 12]
  ------------------
 1391|      6|            reptable.back().outstrings[type].assign(start_piece, iter);
 1392|      6|            mystrrep(reptable.back().outstrings[type], "_", " ");
 1393|      6|            break;
 1394|      6|          }
 1395|      0|          default:
  ------------------
  |  Branch (1395:11): [True: 0, False: 18]
  ------------------
 1396|      0|            break;
 1397|     18|        }
 1398|     18|        ++i;
 1399|     18|        start_piece = mystrsep(nl, iter);
 1400|     18|      }
 1401|      6|    }
 1402|      6|    if (reptable.back().pattern.empty() || reptable.back().outstrings[type].empty()) {
  ------------------
  |  Branch (1402:9): [True: 0, False: 6]
  |  Branch (1402:44): [True: 0, False: 6]
  ------------------
 1403|      0|      HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
 1404|      0|                       af->getlinenum());
 1405|      0|      reptable.clear();
 1406|      0|      return false;
 1407|      0|    }
 1408|      6|  }
 1409|      6|  return true;
 1410|      6|}
_ZNK7HashMgr12get_reptableEv:
 1413|   359k|const std::vector<replentry>& HashMgr::get_reptable() const {
 1414|   359k|  return reptable;
 1415|   359k|}

_ZN12HunspellImplC2EPKcS1_S1_:
  190|     38|  : affixpath(affpath) {
  191|     38|  csconv = nullptr;
  192|     38|  utf8 = 0;
  193|     38|  complexprefixes = 0;
  194|       |
  195|       |  /* first set up the hash manager */
  196|     38|  m_HMgrs.push_back(std::make_unique<HashMgr>(dpath, affpath, key));
  197|       |
  198|       |  /* next set up the affix manager */
  199|       |  /* it needs access to the hash manager lookup methods */
  200|     38|  pAMgr = std::make_unique<AffixMgr>(affpath, m_HMgrs, key);
  201|       |
  202|       |  /* get the preferred try string and the dictionary */
  203|       |  /* encoding from the Affix Manager for that dictionary */
  204|     38|  std::string try_string = pAMgr->get_try_string();
  205|     38|  encoding = pAMgr->get_encoding();
  206|     38|  langnum = pAMgr->get_langnum();
  207|     38|  utf8 = pAMgr->get_utf8();
  208|     38|  if (!utf8)
  ------------------
  |  Branch (208:7): [True: 20, False: 18]
  ------------------
  209|     20|    csconv = get_current_cs(encoding);
  210|     38|  complexprefixes = pAMgr->get_complexprefixes();
  211|     38|  wordbreak = pAMgr->get_breaktable();
  212|       |
  213|       |  /* and finally set up the suggestion manager */
  214|     38|  pSMgr = std::make_unique<SuggestMgr>(try_string, MAXSUGGESTION, pAMgr.get());
  ------------------
  |  |   82|     38|#define MAXSUGGESTION 15
  ------------------
  215|     38|}
_ZN12HunspellImpl12clean_ignoreERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKS6_:
  234|  16.0M|                                const std::string& src) {
  235|  16.0M|  dest.clear();
  236|  16.0M|  dest.assign(src);
  237|  16.0M|  const char* ignoredchars = pAMgr ? pAMgr->get_ignore() : nullptr;
  ------------------
  |  Branch (237:30): [True: 16.0M, False: 0]
  ------------------
  238|  16.0M|  if (ignoredchars != nullptr) {
  ------------------
  |  Branch (238:7): [True: 1.60M, False: 14.4M]
  ------------------
  239|  1.60M|    if (utf8) {
  ------------------
  |  Branch (239:9): [True: 362k, False: 1.24M]
  ------------------
  240|   362k|      const std::vector<w_char>& ignoredchars_utf16 =
  241|   362k|          pAMgr->get_ignore_utf16();
  242|   362k|      remove_ignored_chars_utf(dest, ignoredchars_utf16);
  243|  1.24M|    } else {
  244|  1.24M|      remove_ignored_chars(dest, ignoredchars);
  245|  1.24M|    }
  246|  1.60M|  }
  247|  16.0M|}
_ZN12HunspellImpl10cleanword2ERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorI6w_charNS4_IS9_EEEERKS6_PiPm:
  261|  7.54M|                         size_t* pabbrev) {
  262|  7.54M|  dest.clear();
  263|  7.54M|  dest_utf.clear();
  264|       |
  265|       |  // remove IGNORE characters from the string
  266|  7.54M|  std::string w2;
  267|  7.54M|  clean_ignore(w2, src);
  268|       |
  269|  7.54M|  const char* q = w2.c_str();
  270|  7.54M|  int nl = (int)w2.size();
  271|       |
  272|       |  // first skip over any leading blanks
  273|  7.63M|  while (*q == ' ') {
  ------------------
  |  Branch (273:10): [True: 94.9k, False: 7.54M]
  ------------------
  274|  94.9k|    ++q;
  275|  94.9k|    nl--;
  276|  94.9k|  }
  277|       |
  278|       |  // now strip off any trailing periods (recording their presence)
  279|  7.54M|  *pabbrev = 0;
  280|       |
  281|  8.94M|  while ((nl > 0) && (*(q + nl - 1) == '.')) {
  ------------------
  |  Branch (281:10): [True: 8.57M, False: 372k]
  |  Branch (281:22): [True: 1.40M, False: 7.16M]
  ------------------
  282|  1.40M|    nl--;
  283|  1.40M|    (*pabbrev)++;
  284|  1.40M|  }
  285|       |
  286|       |  // if no characters are left it can't be capitalized
  287|  7.54M|  if (nl <= 0) {
  ------------------
  |  Branch (287:7): [True: 372k, False: 7.16M]
  ------------------
  288|   372k|    *pcaptype = NOCAP;
  ------------------
  |  |   92|   372k|#define NOCAP 0
  ------------------
  289|   372k|    return 0;
  290|   372k|  }
  291|       |
  292|  7.16M|  dest.append(q, nl);
  293|  7.16M|  nl = dest.size();
  294|  7.16M|  if (utf8) {
  ------------------
  |  Branch (294:7): [True: 1.65M, False: 5.51M]
  ------------------
  295|  1.65M|    u8_u16(dest_utf, dest);
  296|  1.65M|    *pcaptype = get_captype_utf8(dest_utf, langnum);
  297|  5.51M|  } else {
  298|  5.51M|    *pcaptype = get_captype(dest, csconv);
  299|  5.51M|  }
  300|  7.16M|  return nl;
  301|  7.54M|}
_ZN12HunspellImpl9cleanwordERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKS6_PiSA_:
  306|  4.96k|                        int* pabbrev) {
  307|  4.96k|  dest.clear();
  308|  4.96k|  const unsigned char* q = (const unsigned char*)src.c_str();
  309|  4.96k|  int firstcap = 0, nl = (int)src.size();
  310|       |
  311|       |  // first skip over any leading blanks
  312|  8.21k|  while (*q == ' ') {
  ------------------
  |  Branch (312:10): [True: 3.24k, False: 4.96k]
  ------------------
  313|  3.24k|    ++q;
  314|  3.24k|    nl--;
  315|  3.24k|  }
  316|       |
  317|       |  // now strip off any trailing periods (recording their presence)
  318|  4.96k|  *pabbrev = 0;
  319|       |
  320|  11.4k|  while ((nl > 0) && (*(q + nl - 1) == '.')) {
  ------------------
  |  Branch (320:10): [True: 11.2k, False: 152]
  |  Branch (320:22): [True: 6.44k, False: 4.81k]
  ------------------
  321|  6.44k|    nl--;
  322|  6.44k|    (*pabbrev)++;
  323|  6.44k|  }
  324|       |
  325|       |  // if no characters are left it can't be capitalized
  326|  4.96k|  if (nl <= 0) {
  ------------------
  |  Branch (326:7): [True: 152, False: 4.81k]
  ------------------
  327|    152|    *pcaptype = NOCAP;
  ------------------
  |  |   92|    152|#define NOCAP 0
  ------------------
  328|    152|    return;
  329|    152|  }
  330|       |
  331|       |  // now determine the capitalization type of the first nl letters
  332|  4.81k|  int ncap = 0;
  333|  4.81k|  int nneutral = 0;
  334|  4.81k|  int nc = 0;
  335|       |
  336|  4.81k|  if (!utf8) {
  ------------------
  |  Branch (336:7): [True: 2.54k, False: 2.26k]
  ------------------
  337|  14.9M|    while (nl > 0) {
  ------------------
  |  Branch (337:12): [True: 14.9M, False: 2.54k]
  ------------------
  338|  14.9M|      nc++;
  339|  14.9M|      if (csconv[(*q)].ccase)
  ------------------
  |  Branch (339:11): [True: 14.8M, False: 145k]
  ------------------
  340|  14.8M|        ncap++;
  341|  14.9M|      if (csconv[(*q)].cupper == csconv[(*q)].clower)
  ------------------
  |  Branch (341:11): [True: 122k, False: 14.8M]
  ------------------
  342|   122k|        nneutral++;
  343|  14.9M|      dest.push_back(*q++);
  344|  14.9M|      nl--;
  345|  14.9M|    }
  346|       |    // remember to terminate the destination string
  347|  2.54k|    firstcap = csconv[static_cast<unsigned char>(dest[0])].ccase;
  348|  2.54k|  } else {
  349|  2.26k|    std::vector<w_char> t;
  350|  2.26k|    u8_u16(t, src);
  351|  2.10M|    for (auto& wc : t) {
  ------------------
  |  Branch (351:19): [True: 2.10M, False: 2.26k]
  ------------------
  352|  2.10M|      const auto idx = (unsigned short)wc;
  353|  2.10M|      const auto low = unicodetolower(idx, langnum);
  354|  2.10M|      if (idx != low)
  ------------------
  |  Branch (354:11): [True: 1.62M, False: 477k]
  ------------------
  355|  1.62M|        ncap++;
  356|  2.10M|      if (unicodetoupper(idx, langnum) == low)
  ------------------
  |  Branch (356:11): [True: 473k, False: 1.62M]
  ------------------
  357|   473k|        nneutral++;
  358|  2.10M|    }
  359|  2.26k|    u16_u8(dest, t);
  360|  2.26k|    if (ncap) {
  ------------------
  |  Branch (360:9): [True: 1.53k, False: 730]
  ------------------
  361|  1.53k|      const auto idx = (unsigned short)t[0];
  362|  1.53k|      firstcap = (idx != unicodetolower(idx, langnum));
  363|  1.53k|    }
  364|  2.26k|  }
  365|       |
  366|       |  // now finally set the captype
  367|  4.81k|  if (ncap == 0) {
  ------------------
  |  Branch (367:7): [True: 1.44k, False: 3.37k]
  ------------------
  368|  1.44k|    *pcaptype = NOCAP;
  ------------------
  |  |   92|  1.44k|#define NOCAP 0
  ------------------
  369|  3.37k|  } else if ((ncap == 1) && firstcap) {
  ------------------
  |  Branch (369:14): [True: 1.78k, False: 1.59k]
  |  Branch (369:29): [True: 1.34k, False: 436]
  ------------------
  370|  1.34k|    *pcaptype = INITCAP;
  ------------------
  |  |   93|  1.34k|#define INITCAP 1
  ------------------
  371|  2.02k|  } else if ((ncap == nc) || ((ncap + nneutral) == nc)) {
  ------------------
  |  Branch (371:14): [True: 70, False: 1.95k]
  |  Branch (371:30): [True: 326, False: 1.63k]
  ------------------
  372|    396|    *pcaptype = ALLCAP;
  ------------------
  |  |   94|    396|#define ALLCAP 2
  ------------------
  373|  1.63k|  } else if ((ncap > 1) && firstcap) {
  ------------------
  |  Branch (373:14): [True: 1.22k, False: 406]
  |  Branch (373:28): [True: 796, False: 429]
  ------------------
  374|    796|    *pcaptype = HUHINITCAP;
  ------------------
  |  |   96|    796|#define HUHINITCAP 4
  ------------------
  375|    835|  } else {
  376|    835|    *pcaptype = HUHCAP;
  ------------------
  |  |   95|    835|#define HUHCAP 3
  ------------------
  377|    835|  }
  378|  4.81k|}
_ZN12HunspellImpl8mkallcapERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  380|  3.54k|void HunspellImpl::mkallcap(std::string& u8) {
  381|  3.54k|  if (utf8) {
  ------------------
  |  Branch (381:7): [True: 1.67k, False: 1.87k]
  ------------------
  382|  1.67k|    std::vector<w_char> u16;
  383|  1.67k|    u8_u16(u16, u8);
  384|  1.67k|    ::mkallcap_utf(u16, langnum);
  385|  1.67k|    u16_u8(u8, u16);
  386|  1.87k|  } else {
  387|  1.87k|    ::mkallcap(u8, csconv);
  388|  1.87k|  }
  389|  3.54k|}
_ZN12HunspellImpl11mkallsmall2ERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorI6w_charNS4_IS9_EEEE:
  391|   807k|int HunspellImpl::mkallsmall2(std::string& u8, std::vector<w_char>& u16) {
  392|   807k|  if (utf8) {
  ------------------
  |  Branch (392:7): [True: 215k, False: 592k]
  ------------------
  393|   215k|    ::mkallsmall_utf(u16, langnum);
  394|   215k|    u16_u8(u8, u16);
  395|   592k|  } else {
  396|   592k|    ::mkallsmall(u8, csconv);
  397|   592k|  }
  398|   807k|  return u8.size();
  399|   807k|}
_ZN12HunspellImpl11is_keepcaseEPK6hentry:
  437|  12.1k|int HunspellImpl::is_keepcase(const hentry* rv) {
  438|  12.1k|  return pAMgr && rv->astr && pAMgr->get_keepcase() &&
  ------------------
  |  Branch (438:10): [True: 12.1k, False: 0]
  |  Branch (438:19): [True: 624, False: 11.5k]
  |  Branch (438:31): [True: 69, False: 555]
  ------------------
  439|     69|         TESTAFF(rv->astr, pAMgr->get_keepcase(), rv->alen);
  ------------------
  |  |   99|  12.2k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 37, False: 32]
  |  |  ------------------
  ------------------
  440|  12.1k|}
_ZN12HunspellImpl10insert_sugERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_:
  443|  13.9k|void HunspellImpl::insert_sug(std::vector<std::string>& slst, const std::string& word) {
  444|  13.9k|  slst.insert(slst.begin(), word);
  445|  13.9k|}
_ZN12HunspellImpl5spellERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorIS6_NS4_IS6_EEEEPiPS6_NS0_6chrono10time_pointINSF_12steady_clockENSF_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEE:
  449|  7.54M|                         std::chrono::steady_clock::time_point suggest_start) {
  450|       |  // something very broken if spell ends up calling itself with the same word
  451|  7.54M|  if (std::find(candidate_stack.begin(), candidate_stack.end(), word) != candidate_stack.end())
  ------------------
  |  Branch (451:7): [True: 0, False: 7.54M]
  ------------------
  452|      0|    return false;
  453|       |
  454|       |  // ofz#42529814 prevent deeply nested wordbreak recursion
  455|  7.54M|  if (candidate_stack.size() >= MAXBREAKDEPTH)
  ------------------
  |  |   86|  7.54M|#define MAXBREAKDEPTH 10
  ------------------
  |  Branch (455:7): [True: 0, False: 7.54M]
  ------------------
  456|      0|    return false;
  457|       |
  458|  7.54M|  candidate_stack.push_back(word);
  459|  7.54M|  bool r = spell_internal(word, candidate_stack, info, root, suggest_start);
  460|  7.54M|  candidate_stack.pop_back();
  461|       |
  462|  7.54M|  if (r && root) {
  ------------------
  |  Branch (462:7): [True: 1.60M, False: 5.94M]
  |  Branch (462:12): [True: 0, False: 1.60M]
  ------------------
  463|       |    // output conversion
  464|      0|    RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : nullptr;
  ------------------
  |  Branch (464:19): [True: 0, False: 0]
  ------------------
  465|      0|    if (rl) {
  ------------------
  |  Branch (465:9): [True: 0, False: 0]
  ------------------
  466|      0|      std::string wspace;
  467|      0|      if (rl->conv(*root, wspace)) {
  ------------------
  |  Branch (467:11): [True: 0, False: 0]
  ------------------
  468|      0|        *root = std::move(wspace);
  469|      0|      }
  470|      0|    }
  471|      0|  }
  472|  7.54M|  return r;
  473|  7.54M|}
_ZN12HunspellImpl14spell_internalERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorIS6_NS4_IS6_EEEEPiPS6_NS0_6chrono10time_pointINSF_12steady_clockENSF_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEE:
  477|  7.54M|                                  std::chrono::steady_clock::time_point suggest_start) {
  478|  7.54M|  struct hentry* rv = nullptr;
  479|       |
  480|  7.54M|  int info2 = 0;
  481|  7.54M|  if (!info)
  ------------------
  |  Branch (481:7): [True: 7.54M, False: 30]
  ------------------
  482|  7.54M|    info = &info2;
  483|     30|  else
  484|     30|    *info = 0;
  485|       |
  486|       |  // Hunspell supports XML input of the simplified API (see manual)
  487|  7.54M|  if (word == SPELL_XML)
  ------------------
  |  |   79|  7.54M|#define SPELL_XML "<?xml?>"
  ------------------
  |  Branch (487:7): [True: 67.9k, False: 7.47M]
  ------------------
  488|  67.9k|    return true;
  489|  7.47M|  if (utf8) {
  ------------------
  |  Branch (489:7): [True: 1.69M, False: 5.77M]
  ------------------
  490|  1.69M|    if (word.size() >= MAXWORDUTF8LEN)
  ------------------
  |  |   86|  1.69M|#define MAXWORDUTF8LEN (MAXWORDLEN * 3)
  |  |  ------------------
  |  |  |  |   89|  1.69M|#define MAXWORDLEN 100
  |  |  ------------------
  ------------------
  |  Branch (490:9): [True: 4.46k, False: 1.69M]
  ------------------
  491|  4.46k|      return false;
  492|  5.77M|  } else {
  493|  5.77M|    if (word.size() >= MAXWORDLEN)
  ------------------
  |  |   89|  5.77M|#define MAXWORDLEN 100
  ------------------
  |  Branch (493:9): [True: 6.45k, False: 5.77M]
  ------------------
  494|  6.45k|      return false;
  495|  5.77M|  }
  496|  7.46M|  int captype = NOCAP;
  ------------------
  |  |   92|  7.46M|#define NOCAP 0
  ------------------
  497|  7.46M|  size_t abbv = 0;
  498|  7.46M|  size_t wl = 0;
  499|       |
  500|  7.46M|  std::string scw;
  501|  7.46M|  std::vector<w_char> sunicw;
  502|       |
  503|       |  // input conversion
  504|  7.46M|  RepList* rl = pAMgr ? pAMgr->get_iconvtable() : nullptr;
  ------------------
  |  Branch (504:17): [True: 7.46M, False: 0]
  ------------------
  505|  7.46M|  {
  506|  7.46M|    std::string wspace;
  507|       |
  508|  7.46M|    bool convstatus = rl ? rl->conv(word, wspace) : false;
  ------------------
  |  Branch (508:23): [True: 250k, False: 7.21M]
  ------------------
  509|  7.46M|    if (convstatus)
  ------------------
  |  Branch (509:9): [True: 1, False: 7.46M]
  ------------------
  510|      1|      wl = cleanword2(scw, sunicw, wspace, &captype, &abbv);
  511|  7.46M|    else
  512|  7.46M|      wl = cleanword2(scw, sunicw, word, &captype, &abbv);
  513|  7.46M|  }
  514|       |
  515|  7.46M|#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
  516|  7.46M|    if (wl > 32768)
  ------------------
  |  Branch (516:9): [True: 0, False: 7.46M]
  ------------------
  517|      0|      return false;
  518|  7.46M|#endif
  519|       |
  520|       |#ifdef MOZILLA_CLIENT
  521|       |  // accept the abbreviated words without dots
  522|       |  // workaround for the incomplete tokenization of Mozilla
  523|       |  abbv = 1;
  524|       |#endif
  525|       |
  526|  7.46M|  if (wl == 0 || m_HMgrs.empty())
  ------------------
  |  Branch (526:7): [True: 372k, False: 7.09M]
  |  Branch (526:18): [True: 0, False: 7.09M]
  ------------------
  527|   372k|    return true;
  528|  7.09M|  if (root)
  ------------------
  |  Branch (528:7): [True: 0, False: 7.09M]
  ------------------
  529|      0|    root->clear();
  530|       |
  531|       |  // allow numbers with dots, dashes and commas (but forbid double separators:
  532|       |  // "..", "--" etc.)
  533|  7.09M|  enum { NBEGIN, NNUM, NSEP };
  534|  7.09M|  int nstate = NBEGIN;
  535|  7.09M|  size_t i;
  536|       |
  537|  10.8M|  for (i = 0; (i < wl); i++) {
  ------------------
  |  Branch (537:15): [True: 10.3M, False: 533k]
  ------------------
  538|  10.3M|    if ((scw[i] <= '9') && (scw[i] >= '0')) {
  ------------------
  |  Branch (538:9): [True: 8.16M, False: 2.16M]
  |  Branch (538:28): [True: 3.45M, False: 4.70M]
  ------------------
  539|  3.45M|      nstate = NNUM;
  540|  6.87M|    } else if ((scw[i] == ',') || (scw[i] == '.') || (scw[i] == '-')) {
  ------------------
  |  Branch (540:16): [True: 28.1k, False: 6.84M]
  |  Branch (540:35): [True: 703k, False: 6.14M]
  |  Branch (540:54): [True: 1.43M, False: 4.70M]
  ------------------
  541|  2.16M|      if ((nstate == NSEP) || (i == 0))
  ------------------
  |  Branch (541:11): [True: 76.0k, False: 2.09M]
  |  Branch (541:31): [True: 1.77M, False: 314k]
  ------------------
  542|  1.85M|        break;
  543|   314k|      nstate = NSEP;
  544|   314k|    } else
  545|  4.70M|      break;
  546|  10.3M|  }
  547|  7.09M|  if ((i == wl) && (nstate == NNUM))
  ------------------
  |  Branch (547:7): [True: 533k, False: 6.56M]
  |  Branch (547:20): [True: 423k, False: 109k]
  ------------------
  548|   423k|    return true;
  549|       |
  550|  6.67M|  switch (captype) {
  ------------------
  |  Branch (550:11): [True: 6.67M, False: 0]
  ------------------
  551|   503k|    case HUHCAP:
  ------------------
  |  |   95|   503k|#define HUHCAP 3
  ------------------
  |  Branch (551:5): [True: 503k, False: 6.16M]
  ------------------
  552|       |    /* FALLTHROUGH */
  553|   707k|    case HUHINITCAP:
  ------------------
  |  |   96|   707k|#define HUHINITCAP 4
  ------------------
  |  Branch (553:5): [True: 203k, False: 6.46M]
  ------------------
  554|   707k|      *info |= SPELL_ORIGCAP;
  ------------------
  |  |   83|   707k|#define SPELL_ORIGCAP (1 << 5)
  ------------------
  555|       |    /* FALLTHROUGH */
  556|  6.17M|    case NOCAP:
  ------------------
  |  |   92|  6.17M|#define NOCAP 0
  ------------------
  |  Branch (556:5): [True: 5.46M, False: 1.20M]
  ------------------
  557|  6.17M|      rv = checkword(scw, info, root, suggest_start);
  558|  6.17M|      if ((abbv) && !(rv)) {
  ------------------
  |  Branch (558:11): [True: 857k, False: 5.31M]
  |  Branch (558:21): [True: 856k, False: 1.16k]
  ------------------
  559|   856k|        std::string u8buffer(scw);
  560|   856k|        u8buffer.push_back('.');
  561|   856k|        rv = checkword(u8buffer, info, root, suggest_start);
  562|   856k|      }
  563|  6.17M|      break;
  564|   167k|    case ALLCAP: {
  ------------------
  |  |   94|   167k|#define ALLCAP 2
  ------------------
  |  Branch (564:5): [True: 167k, False: 6.50M]
  ------------------
  565|   167k|      *info |= SPELL_ORIGCAP;
  ------------------
  |  |   83|   167k|#define SPELL_ORIGCAP (1 << 5)
  ------------------
  566|   167k|      rv = checkword(scw, info, root, suggest_start);
  567|   167k|      if (rv)
  ------------------
  |  Branch (567:11): [True: 16, False: 167k]
  ------------------
  568|     16|        break;
  569|   167k|      if (abbv) {
  ------------------
  |  Branch (569:11): [True: 16.8k, False: 151k]
  ------------------
  570|  16.8k|        std::string u8buffer(scw);
  571|  16.8k|        u8buffer.push_back('.');
  572|  16.8k|        rv = checkword(u8buffer, info, root, suggest_start);
  573|  16.8k|        if (rv)
  ------------------
  |  Branch (573:13): [True: 0, False: 16.8k]
  ------------------
  574|      0|          break;
  575|  16.8k|      }
  576|       |      // Spec. prefix handling for Catalan, French, Italian:
  577|       |      // prefixes separated by apostrophe (SANT'ELIA -> Sant'+Elia).
  578|   167k|      size_t apos = pAMgr ? scw.find('\'') : std::string::npos;
  ------------------
  |  Branch (578:21): [True: 167k, False: 0]
  ------------------
  579|   167k|      if (apos != std::string::npos) {
  ------------------
  |  Branch (579:11): [True: 57.4k, False: 110k]
  ------------------
  580|  57.4k|        mkallsmall2(scw, sunicw);
  581|       |        //conversion may result in string with different len to pre-mkallsmall2
  582|       |        //so re-scan
  583|  57.4k|        if (apos != std::string::npos && apos < scw.size() - 1) {
  ------------------
  |  Branch (583:13): [True: 57.4k, False: 0]
  |  Branch (583:42): [True: 53.0k, False: 4.39k]
  ------------------
  584|  53.0k|          std::string part1 = scw.substr(0, apos + 1), part2 = scw.substr(apos + 1);
  585|  53.0k|          if (utf8) {
  ------------------
  |  Branch (585:15): [True: 10.1k, False: 42.9k]
  ------------------
  586|  10.1k|            std::vector<w_char> part1u, part2u;
  587|  10.1k|            u8_u16(part1u, part1);
  588|  10.1k|            u8_u16(part2u, part2);
  589|  10.1k|            mkinitcap2(part2, part2u);
  590|  10.1k|            scw = part1 + part2;
  591|  10.1k|            sunicw = std::move(part1u);
  592|  10.1k|            sunicw.insert(sunicw.end(), part2u.begin(), part2u.end());
  593|  10.1k|            rv = checkword(scw, info, root, suggest_start);
  594|  10.1k|            if (rv)
  ------------------
  |  Branch (594:17): [True: 0, False: 10.1k]
  ------------------
  595|      0|              break;
  596|  42.9k|          } else {
  597|  42.9k|            mkinitcap2(part2, sunicw);
  598|  42.9k|            scw = part1 + part2;
  599|  42.9k|            rv = checkword(scw, info, root, suggest_start);
  600|  42.9k|            if (rv)
  ------------------
  |  Branch (600:17): [True: 1, False: 42.9k]
  ------------------
  601|      1|              break;
  602|  42.9k|          }
  603|  53.0k|          mkinitcap2(scw, sunicw);
  604|  53.0k|          rv = checkword(scw, info, root, suggest_start);
  605|  53.0k|          if (rv)
  ------------------
  |  Branch (605:15): [True: 0, False: 53.0k]
  ------------------
  606|      0|            break;
  607|  53.0k|        }
  608|  57.4k|      }
  609|   167k|      if (pAMgr && pAMgr->get_checksharps() && scw.find("SS") != std::string::npos) {
  ------------------
  |  Branch (609:11): [True: 167k, False: 0]
  |  Branch (609:20): [True: 0, False: 167k]
  |  Branch (609:48): [True: 0, False: 0]
  ------------------
  610|       |
  611|      0|        mkallsmall2(scw, sunicw);
  612|      0|        std::string u8buffer(scw);
  613|      0|        rv = spellsharps(u8buffer, 0, 0, 0, info, root, suggest_start);
  614|      0|        if (!rv) {
  ------------------
  |  Branch (614:13): [True: 0, False: 0]
  ------------------
  615|      0|          mkinitcap2(scw, sunicw);
  616|      0|          rv = spellsharps(scw, 0, 0, 0, info, root, suggest_start);
  617|      0|        }
  618|      0|        if ((abbv) && !(rv)) {
  ------------------
  |  Branch (618:13): [True: 0, False: 0]
  |  Branch (618:23): [True: 0, False: 0]
  ------------------
  619|      0|          u8buffer.push_back('.');
  620|      0|          rv = spellsharps(u8buffer, 0, 0, 0, info, root, suggest_start);
  621|      0|          if (!rv) {
  ------------------
  |  Branch (621:15): [True: 0, False: 0]
  ------------------
  622|      0|            u8buffer = std::string(scw);
  623|      0|            u8buffer.push_back('.');
  624|      0|            rv = spellsharps(u8buffer, 0, 0, 0, info, root, suggest_start);
  625|      0|          }
  626|      0|        }
  627|      0|        if (rv)
  ------------------
  |  Branch (627:13): [True: 0, False: 0]
  ------------------
  628|      0|          break;
  629|      0|      }
  630|   167k|    }
  631|       |      /* FALLTHROUGH */
  632|   494k|    case INITCAP: {
  ------------------
  |  |   93|   494k|#define INITCAP 1
  ------------------
  |  Branch (632:5): [True: 326k, False: 6.34M]
  ------------------
  633|       |      // handle special capitalization of dotted I
  634|   494k|      bool Idot = (utf8 && (unsigned char) scw[0] == 0xc4 && (unsigned char) scw[1] == 0xb0);
  ------------------
  |  Branch (634:20): [True: 118k, False: 375k]
  |  Branch (634:28): [True: 0, False: 118k]
  |  Branch (634:62): [True: 0, False: 0]
  ------------------
  635|   494k|      *info |= SPELL_ORIGCAP;
  ------------------
  |  |   83|   494k|#define SPELL_ORIGCAP (1 << 5)
  ------------------
  636|   494k|      if (captype == ALLCAP) {
  ------------------
  |  |   94|   494k|#define ALLCAP 2
  ------------------
  |  Branch (636:11): [True: 167k, False: 326k]
  ------------------
  637|   167k|          mkallsmall2(scw, sunicw);
  638|   167k|          mkinitcap2(scw, sunicw);
  639|   167k|          if (Idot)
  ------------------
  |  Branch (639:15): [True: 0, False: 167k]
  ------------------
  640|      0|             scw.replace(0, 1, "\xc4\xb0");
  641|   167k|      }
  642|   494k|      if (captype == INITCAP)
  ------------------
  |  |   93|   494k|#define INITCAP 1
  ------------------
  |  Branch (642:11): [True: 326k, False: 167k]
  ------------------
  643|   326k|        *info |= SPELL_INITCAP;
  ------------------
  |  |   82|   326k|#define SPELL_INITCAP (1 << 4)
  ------------------
  644|   494k|      rv = checkword(scw, info, root, suggest_start);
  645|   494k|      if (captype == INITCAP)
  ------------------
  |  |   93|   494k|#define INITCAP 1
  ------------------
  |  Branch (645:11): [True: 326k, False: 167k]
  ------------------
  646|   326k|        *info &= ~SPELL_INITCAP;
  ------------------
  |  |   82|   326k|#define SPELL_INITCAP (1 << 4)
  ------------------
  647|       |      // forbid bad capitalization
  648|       |      // (for example, ijs -> Ijs instead of IJs in Dutch)
  649|       |      // use explicit forms in dic: Ijs/F (F = FORBIDDENWORD flag)
  650|   494k|      if (*info & SPELL_FORBIDDEN) {
  ------------------
  |  |   79|   494k|#define SPELL_FORBIDDEN (1 << 1)
  ------------------
  |  Branch (650:11): [True: 0, False: 494k]
  ------------------
  651|      0|        rv = nullptr;
  652|      0|        break;
  653|      0|      }
  654|   494k|      if (rv && is_keepcase(rv) && (captype == ALLCAP))
  ------------------
  |  |   94|     10|#define ALLCAP 2
  ------------------
  |  Branch (654:11): [True: 7.99k, False: 486k]
  |  Branch (654:17): [True: 10, False: 7.98k]
  |  Branch (654:36): [True: 2, False: 8]
  ------------------
  655|      2|        rv = nullptr;
  656|   494k|      if (rv || (Idot && langnum != LANG_az && langnum != LANG_tr && langnum != LANG_crh))
  ------------------
  |  Branch (656:11): [True: 7.99k, False: 486k]
  |  Branch (656:18): [True: 0, False: 486k]
  |  Branch (656:26): [True: 0, False: 0]
  |  Branch (656:48): [True: 0, False: 0]
  |  Branch (656:70): [True: 0, False: 0]
  ------------------
  657|  7.99k|        break;
  658|       |
  659|   486k|      mkallsmall2(scw, sunicw);
  660|   486k|      std::string u8buffer(scw);
  661|   486k|      mkinitcap2(scw, sunicw);
  662|       |
  663|   486k|      rv = checkword(u8buffer, info, root, suggest_start);
  664|   486k|      if (abbv && !rv) {
  ------------------
  |  Branch (664:11): [True: 92.1k, False: 394k]
  |  Branch (664:19): [True: 91.9k, False: 168]
  ------------------
  665|  91.9k|        u8buffer.push_back('.');
  666|  91.9k|        rv = checkword(u8buffer, info, root, suggest_start);
  667|  91.9k|        if (!rv) {
  ------------------
  |  Branch (667:13): [True: 91.9k, False: 1]
  ------------------
  668|  91.9k|          u8buffer = scw;
  669|  91.9k|          u8buffer.push_back('.');
  670|  91.9k|          if (captype == INITCAP)
  ------------------
  |  |   93|  91.9k|#define INITCAP 1
  ------------------
  |  Branch (670:15): [True: 75.1k, False: 16.8k]
  ------------------
  671|  75.1k|            *info |= SPELL_INITCAP;
  ------------------
  |  |   82|  75.1k|#define SPELL_INITCAP (1 << 4)
  ------------------
  672|  91.9k|          rv = checkword(u8buffer, info, root, suggest_start);
  673|  91.9k|          if (captype == INITCAP)
  ------------------
  |  |   93|  91.9k|#define INITCAP 1
  ------------------
  |  Branch (673:15): [True: 75.1k, False: 16.8k]
  ------------------
  674|  75.1k|            *info &= ~SPELL_INITCAP;
  ------------------
  |  |   82|  75.1k|#define SPELL_INITCAP (1 << 4)
  ------------------
  675|  91.9k|          if (rv && is_keepcase(rv) && (captype == ALLCAP))
  ------------------
  |  |   94|     23|#define ALLCAP 2
  ------------------
  |  Branch (675:15): [True: 23, False: 91.9k]
  |  Branch (675:21): [True: 23, False: 0]
  |  Branch (675:40): [True: 9, False: 14]
  ------------------
  676|      9|            rv = nullptr;
  677|  91.9k|          break;
  678|  91.9k|        }
  679|  91.9k|      }
  680|   394k|      if (rv && is_keepcase(rv) &&
  ------------------
  |  Branch (680:11): [True: 4.14k, False: 390k]
  |  Branch (680:17): [True: 4, False: 4.14k]
  ------------------
  681|      4|          ((captype == ALLCAP) ||
  ------------------
  |  |   94|      4|#define ALLCAP 2
  ------------------
  |  Branch (681:12): [True: 1, False: 3]
  ------------------
  682|       |           // if CHECKSHARPS: KEEPCASE words with \xDF  are allowed
  683|       |           // in INITCAP form, too.
  684|      3|           !(pAMgr->get_checksharps() &&
  ------------------
  |  Branch (684:14): [True: 0, False: 3]
  ------------------
  685|      0|             ((utf8 && u8buffer.find("\xC3\x9F") != std::string::npos) ||
  ------------------
  |  Branch (685:16): [True: 0, False: 0]
  |  Branch (685:24): [True: 0, False: 0]
  ------------------
  686|      0|              (!utf8 && u8buffer.find('\xDF') != std::string::npos)))))
  ------------------
  |  Branch (686:16): [True: 0, False: 0]
  |  Branch (686:25): [True: 0, False: 0]
  ------------------
  687|      4|        rv = nullptr;
  688|   394k|      break;
  689|   486k|    }
  690|  6.67M|  }
  691|       |
  692|  6.67M|  if (rv) {
  ------------------
  |  Branch (692:7): [True: 25.0k, False: 6.64M]
  ------------------
  693|  25.0k|    if (pAMgr && pAMgr->get_warn() && rv->astr &&
  ------------------
  |  Branch (693:9): [True: 25.0k, False: 0]
  |  Branch (693:9): [True: 4, False: 25.0k]
  |  Branch (693:18): [True: 1.92k, False: 23.0k]
  |  Branch (693:39): [True: 36, False: 1.88k]
  ------------------
  694|     36|        TESTAFF(rv->astr, pAMgr->get_warn(), rv->alen)) {
  ------------------
  |  |   99|     36|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 4, False: 32]
  |  |  ------------------
  ------------------
  695|      4|      *info |= SPELL_WARN;
  ------------------
  |  |   84|      4|#define SPELL_WARN (1 << 6)
  ------------------
  696|      4|      if (pAMgr->get_forbidwarn())
  ------------------
  |  Branch (696:11): [True: 0, False: 4]
  ------------------
  697|      0|        return false;
  698|      4|      return true;
  699|      4|    }
  700|  25.0k|    return true;
  701|  25.0k|  }
  702|       |
  703|       |  // recursive breaking at break points
  704|  6.64M|  if (!wordbreak.empty() && !(*info & SPELL_FORBIDDEN)) {
  ------------------
  |  |   79|  6.64M|#define SPELL_FORBIDDEN (1 << 1)
  ------------------
  |  Branch (704:7): [True: 6.64M, False: 0]
  |  Branch (704:29): [True: 6.64M, False: 0]
  ------------------
  705|       |
  706|  6.64M|    int nbr = 0;
  707|  6.64M|    wl = scw.size();
  708|       |
  709|       |    // calculate break points for recursion limit
  710|  19.8M|    for (auto& j : wordbreak) {
  ------------------
  |  Branch (710:18): [True: 19.8M, False: 6.64M]
  ------------------
  711|  19.8M|      size_t pos = 0;
  712|  27.2M|      while ((pos = scw.find(j, pos)) != std::string::npos) {
  ------------------
  |  Branch (712:14): [True: 7.38M, False: 19.8M]
  ------------------
  713|  7.38M|        ++nbr;
  714|  7.38M|        pos += j.size();
  715|  7.38M|      }
  716|  19.8M|    }
  717|  6.64M|    if (nbr >= MAXBREAKDEPTH)
  ------------------
  |  |   86|  6.64M|#define MAXBREAKDEPTH 10
  ------------------
  |  Branch (717:9): [True: 2.71k, False: 6.64M]
  ------------------
  718|  2.71k|      return false;
  719|       |
  720|       |    // check boundary patterns (^begin and end$)
  721|  19.7M|    for (auto& j : wordbreak) {
  ------------------
  |  Branch (721:18): [True: 19.7M, False: 5.97M]
  ------------------
  722|  19.7M|      size_t plen = j.size();
  723|  19.7M|      if (plen == 1 || plen > wl)
  ------------------
  |  Branch (723:11): [True: 6.64M, False: 13.1M]
  |  Branch (723:24): [True: 1.96M, False: 11.1M]
  ------------------
  724|  8.60M|        continue;
  725|       |
  726|  11.1M|      if (j[0] == '^' && scw.compare(0, plen - 1, j, 1, plen - 1) == 0 &&
  ------------------
  |  Branch (726:11): [True: 5.62M, False: 5.54M]
  |  Branch (726:11): [True: 93.7k, False: 11.0M]
  |  Branch (726:26): [True: 662k, False: 4.96M]
  ------------------
  727|   662k|          spell(scw.substr(plen - 1), candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (727:11): [True: 93.7k, False: 568k]
  ------------------
  728|  93.7k|        *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|  93.7k|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  729|  93.7k|        return true;
  730|  93.7k|      }
  731|       |
  732|  11.0M|      if (j[plen - 1] == '$' &&
  ------------------
  |  Branch (732:11): [True: 5.53M, False: 5.54M]
  ------------------
  733|  5.53M|          scw.compare(wl - plen + 1, plen - 1, j, 0, plen - 1) == 0) {
  ------------------
  |  Branch (733:11): [True: 2.21M, False: 3.31M]
  ------------------
  734|  2.21M|        std::string suffix(scw.substr(wl - plen + 1));
  735|  2.21M|        scw.resize(wl - plen + 1);
  736|  2.21M|        if (spell(scw, candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (736:13): [True: 575k, False: 1.64M]
  ------------------
  737|   575k|          *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|   575k|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  738|   575k|          return true;
  739|   575k|        }
  740|  1.64M|        scw.append(suffix);
  741|  1.64M|      }
  742|  11.0M|    }
  743|       |
  744|       |    // other patterns
  745|  17.7M|    for (auto& j : wordbreak) {
  ------------------
  |  Branch (745:18): [True: 17.7M, False: 5.93M]
  ------------------
  746|  17.7M|      size_t plen = j.size();
  747|  17.7M|      size_t found = scw.find(j);
  748|  17.7M|      if ((found > 0) && (found < wl - plen)) {
  ------------------
  |  Branch (748:11): [True: 16.7M, False: 1.03M]
  |  Branch (748:26): [True: 1.84M, False: 14.9M]
  ------------------
  749|  1.84M|        size_t found2 = scw.find(j, found + 1);
  750|       |        // try to break at the second occurance
  751|       |        // to recognize dictionary words with wordbreak
  752|  1.84M|        if (found2 > 0 && (found2 < wl - plen))
  ------------------
  |  Branch (752:13): [True: 1.84M, False: 0]
  |  Branch (752:27): [True: 754k, False: 1.08M]
  ------------------
  753|   754k|            found = found2;
  754|  1.84M|        std::string substring(scw.substr(found + plen));
  755|  1.84M|        if (!spell(substring, candidate_stack, nullptr, nullptr, suggest_start))
  ------------------
  |  Branch (755:13): [True: 1.35M, False: 490k]
  ------------------
  756|  1.35M|          continue;
  757|   490k|        std::string suffix(scw.substr(found));
  758|   490k|        scw.resize(found);
  759|       |        // examine 2 sides of the break point
  760|   490k|        if (spell(scw, candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (760:13): [True: 38.4k, False: 451k]
  ------------------
  761|  38.4k|          *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|  38.4k|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  762|  38.4k|          return true;
  763|  38.4k|        }
  764|   451k|        scw.append(suffix);
  765|       |
  766|       |        // LANG_hu: spec. dash rule
  767|   451k|        if (langnum == LANG_hu && j == "-") {
  ------------------
  |  Branch (767:13): [True: 262, False: 451k]
  |  Branch (767:35): [True: 262, False: 0]
  ------------------
  768|    262|          suffix = scw.substr(found + 1);
  769|    262|          scw.resize(found + 1);
  770|    262|          if (spell(scw, candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (770:15): [True: 0, False: 262]
  ------------------
  771|      0|            *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|      0|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  772|      0|            return true;  // check the first part with dash
  773|      0|          }
  774|    262|          scw.append(suffix);
  775|    262|        }
  776|       |        // end of LANG specific region
  777|   451k|      }
  778|  17.7M|    }
  779|       |
  780|       |    // other patterns (break at first break point)
  781|  17.7M|    for (auto& j : wordbreak) {
  ------------------
  |  Branch (781:18): [True: 17.7M, False: 5.93M]
  ------------------
  782|  17.7M|      size_t plen = j.size(), found = scw.find(j);
  783|  17.7M|      if ((found > 0) && (found < wl - plen)) {
  ------------------
  |  Branch (783:11): [True: 16.7M, False: 1.03M]
  |  Branch (783:26): [True: 1.79M, False: 14.9M]
  ------------------
  784|  1.79M|        if (!spell(scw.substr(found + plen), candidate_stack, nullptr, nullptr, suggest_start))
  ------------------
  |  Branch (784:13): [True: 1.44M, False: 352k]
  ------------------
  785|  1.44M|          continue;
  786|   352k|        std::string suffix(scw.substr(found));
  787|   352k|        scw.resize(found);
  788|       |        // examine 2 sides of the break point
  789|   352k|        if (spell(scw, candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (789:13): [True: 3.35k, False: 349k]
  ------------------
  790|  3.35k|          *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|  3.35k|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  791|  3.35k|          return true;
  792|  3.35k|        }
  793|   349k|        scw.append(suffix);
  794|       |
  795|       |        // LANG_hu: spec. dash rule
  796|   349k|        if (langnum == LANG_hu && j == "-") {
  ------------------
  |  Branch (796:13): [True: 121, False: 349k]
  |  Branch (796:35): [True: 121, False: 0]
  ------------------
  797|    121|          suffix = scw.substr(found + 1);
  798|    121|          scw.resize(found + 1);
  799|    121|          if (spell(scw, candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (799:15): [True: 0, False: 121]
  ------------------
  800|      0|            *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|      0|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  801|      0|            return true;  // check the first part with dash
  802|      0|          }
  803|    121|          scw.append(suffix);
  804|    121|        }
  805|       |        // end of LANG specific region
  806|   349k|      }
  807|  17.7M|    }
  808|  5.93M|  }
  809|       |
  810|  5.93M|  return false;
  811|  6.64M|}
_ZN12HunspellImpl9checkwordERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPiPS6_NS0_6chrono10time_pointINSB_12steady_clockENSB_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEE:
  814|  8.49M|                                       std::chrono::steady_clock::time_point suggest_start) {
  815|       |  // check overall suggest time limit
  816|  8.49M|  if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  8.49M|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (816:7): [True: 0, False: 8.49M]
  ------------------
  817|      0|    return nullptr;
  818|       |
  819|  8.49M|  std::string word;
  820|       |
  821|       |  // remove IGNORE characters from the string
  822|  8.49M|  clean_ignore(word, w);
  823|       |
  824|  8.49M|  if (word.empty())
  ------------------
  |  Branch (824:7): [True: 296, False: 8.49M]
  ------------------
  825|    296|    return nullptr;
  826|       |
  827|       |  // word reversing wrapper for complex prefixes
  828|  8.49M|  if (complexprefixes) {
  ------------------
  |  Branch (828:7): [True: 668k, False: 7.83M]
  ------------------
  829|   668k|    if (utf8)
  ------------------
  |  Branch (829:9): [True: 0, False: 668k]
  ------------------
  830|      0|      reverseword_utf(word);
  831|   668k|    else
  832|   668k|      reverseword(word);
  833|   668k|  }
  834|       |
  835|  8.49M|  int len = word.size();
  836|       |
  837|       |  // look word in hash table
  838|  8.49M|  struct hentry* he = nullptr;
  839|  16.9M|  for (size_t i = 0; (i < m_HMgrs.size()) && !he; ++i) {
  ------------------
  |  Branch (839:22): [True: 8.49M, False: 8.49M]
  |  Branch (839:46): [True: 8.49M, False: 0]
  ------------------
  840|  8.49M|    he = m_HMgrs[i]->lookup(word.c_str(), word.size());
  841|       |
  842|       |    // check forbidden and onlyincompound words
  843|  8.49M|    if ((he) && (he->astr) && (pAMgr) &&
  ------------------
  |  Branch (843:9): [True: 25.1k, False: 8.47M]
  |  Branch (843:9): [True: 0, False: 8.49M]
  |  Branch (843:17): [True: 751, False: 24.4k]
  |  Branch (843:31): [True: 751, False: 0]
  ------------------
  844|    751|        TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) {
  ------------------
  |  |   99|    751|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 751]
  |  |  ------------------
  ------------------
  845|      0|      if (info)
  ------------------
  |  Branch (845:11): [True: 0, False: 0]
  ------------------
  846|      0|        *info |= SPELL_FORBIDDEN;
  ------------------
  |  |   79|      0|#define SPELL_FORBIDDEN (1 << 1)
  ------------------
  847|       |      // LANG_hu section: set dash information for suggestions
  848|      0|      if (langnum == LANG_hu) {
  ------------------
  |  Branch (848:11): [True: 0, False: 0]
  ------------------
  849|      0|        if (pAMgr->get_compoundflag() &&
  ------------------
  |  Branch (849:13): [True: 0, False: 0]
  |  Branch (849:13): [True: 0, False: 0]
  ------------------
  850|      0|            TESTAFF(he->astr, pAMgr->get_compoundflag(), he->alen)) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  851|      0|          if (info)
  ------------------
  |  Branch (851:15): [True: 0, False: 0]
  ------------------
  852|      0|            *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|      0|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  853|      0|        }
  854|      0|      }
  855|      0|      return nullptr;
  856|      0|    }
  857|       |
  858|       |    // he = next not needaffix, onlyincompound homonym or onlyupcase word
  859|  8.49M|    while (he && (he->astr) && pAMgr &&
  ------------------
  |  Branch (859:12): [True: 25.1k, False: 8.47M]
  |  Branch (859:12): [True: 122, False: 8.49M]
  |  Branch (859:18): [True: 751, False: 24.4k]
  |  Branch (859:32): [True: 751, False: 0]
  ------------------
  860|    751|           ((pAMgr->get_needaffix() &&
  ------------------
  |  Branch (860:14): [True: 52, False: 699]
  ------------------
  861|     52|             TESTAFF(he->astr, pAMgr->get_needaffix(), he->alen)) ||
  ------------------
  |  |   99|     52|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 52]
  |  |  ------------------
  ------------------
  862|    751|            (pAMgr->get_onlyincompound() &&
  ------------------
  |  Branch (862:14): [True: 0, False: 751]
  ------------------
  863|      0|             TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  864|    751|            (info && (*info & SPELL_INITCAP) &&
  ------------------
  |  |   82|    751|#define SPELL_INITCAP (1 << 4)
  ------------------
  |  Branch (864:14): [True: 751, False: 0]
  |  Branch (864:22): [True: 144, False: 607]
  ------------------
  865|    144|             TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen))))
  ------------------
  |  |   99|    144|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 122, False: 22]
  |  |  ------------------
  ------------------
  866|    122|      he = he->next_homonym;
  867|  8.49M|  }
  868|       |
  869|       |  // check with affixes
  870|  8.49M|  if (!he && pAMgr) {
  ------------------
  |  Branch (870:7): [True: 8.47M, False: 25.0k]
  |  Branch (870:14): [True: 8.47M, False: 0]
  ------------------
  871|       |    // try stripping off affixes
  872|  8.47M|    AffixScratch scratch;
  873|  8.47M|    he = pAMgr->affix_check(word, 0, len, scratch, 0);
  874|       |
  875|       |    // check compound restriction and onlyupcase
  876|  8.47M|    if (he && he->astr &&
  ------------------
  |  Branch (876:9): [True: 2, False: 8.47M]
  |  Branch (876:9): [True: 0, False: 8.47M]
  |  Branch (876:15): [True: 2, False: 0]
  ------------------
  877|      2|        ((pAMgr->get_onlyincompound() &&
  ------------------
  |  Branch (877:11): [True: 0, False: 2]
  ------------------
  878|      0|          TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  879|      2|         (info && (*info & SPELL_INITCAP) &&
  ------------------
  |  |   82|      2|#define SPELL_INITCAP (1 << 4)
  ------------------
  |  Branch (879:11): [True: 2, False: 0]
  |  Branch (879:19): [True: 0, False: 2]
  ------------------
  880|      0|          TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)))) {
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  881|      0|      he = nullptr;
  882|      0|    }
  883|       |
  884|  8.47M|    if (he) {
  ------------------
  |  Branch (884:9): [True: 2, False: 8.47M]
  ------------------
  885|      2|      if ((he->astr) && (pAMgr) &&
  ------------------
  |  Branch (885:11): [True: 2, False: 0]
  |  Branch (885:11): [True: 0, False: 2]
  |  Branch (885:25): [True: 2, False: 0]
  ------------------
  886|      2|          TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) {
  ------------------
  |  |   99|      2|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 2]
  |  |  ------------------
  ------------------
  887|      0|        if (info)
  ------------------
  |  Branch (887:13): [True: 0, False: 0]
  ------------------
  888|      0|          *info |= SPELL_FORBIDDEN;
  ------------------
  |  |   79|      0|#define SPELL_FORBIDDEN (1 << 1)
  ------------------
  889|      0|        return nullptr;
  890|      0|      }
  891|      2|      if (root) {
  ------------------
  |  Branch (891:11): [True: 0, False: 2]
  ------------------
  892|      0|        root->assign(he->word);
  893|      0|        if (complexprefixes) {
  ------------------
  |  Branch (893:13): [True: 0, False: 0]
  ------------------
  894|      0|          if (utf8)
  ------------------
  |  Branch (894:15): [True: 0, False: 0]
  ------------------
  895|      0|            reverseword_utf(*root);
  896|      0|          else
  897|      0|            reverseword(*root);
  898|      0|        }
  899|      0|      }
  900|       |      // try check compound word
  901|  8.47M|    } else if (pAMgr->get_compound()) {
  ------------------
  |  Branch (901:16): [True: 2.01M, False: 6.45M]
  ------------------
  902|  2.01M|      struct hentry* rwords[100] = {};  // buffer for COMPOUND pattern checking
  903|       |
  904|       |      // first allow only 2 words in the compound
  905|  2.01M|      int setinfo = SPELL_COMPOUND_2;
  ------------------
  |  |   85|  2.01M|#define SPELL_COMPOUND_2 (1 << 7)  // permit only 2 dictionary words in the compound
  ------------------
  906|  2.01M|      if (info)
  ------------------
  |  Branch (906:11): [True: 2.01M, False: 0]
  ------------------
  907|  2.01M|        setinfo |= *info;
  908|  2.01M|      he = pAMgr->compound_check(word, 0, 0, 100, 0, nullptr, (hentry**)&rwords, 0, 0, &setinfo, scratch);
  909|  2.01M|      if (info)
  ------------------
  |  Branch (909:11): [True: 2.01M, False: 0]
  ------------------
  910|  2.01M|        *info = setinfo & ~SPELL_COMPOUND_2;
  ------------------
  |  |   85|  2.01M|#define SPELL_COMPOUND_2 (1 << 7)  // permit only 2 dictionary words in the compound
  ------------------
  911|       |      // if not 2-word compoud word, try with 3 or more words
  912|       |      // (only if original info didn't forbid it)
  913|  2.01M|      if (!he && info && !(*info & SPELL_COMPOUND_2)) {
  ------------------
  |  |   85|  2.01M|#define SPELL_COMPOUND_2 (1 << 7)  // permit only 2 dictionary words in the compound
  ------------------
  |  Branch (913:11): [True: 2.01M, False: 0]
  |  Branch (913:18): [True: 2.01M, False: 0]
  |  Branch (913:26): [True: 2.01M, False: 0]
  ------------------
  914|  2.01M|        *info &= ~SPELL_COMPOUND_2;
  ------------------
  |  |   85|  2.01M|#define SPELL_COMPOUND_2 (1 << 7)  // permit only 2 dictionary words in the compound
  ------------------
  915|  2.01M|        he = pAMgr->compound_check(word, 0, 0, 100, 0, nullptr, (hentry**)&rwords, 0, 0, info, scratch);
  916|       |        // accept the compound with 3 or more words only if it is
  917|       |        // - not a dictionary word with a typo and
  918|       |        // - not two words written separately,
  919|       |        // - or if it's an arbitrary number accepted by compound rules (e.g. 999%)
  920|  2.01M|        if (he && !isdigit(word[0]))
  ------------------
  |  Branch (920:13): [True: 0, False: 2.01M]
  |  Branch (920:19): [True: 0, False: 0]
  ------------------
  921|      0|        {
  922|      0|          std::vector<std::string> slst;
  923|      0|          if (pSMgr->suggest(slst, word, nullptr, /*test_simplesug=*/true))
  ------------------
  |  Branch (923:15): [True: 0, False: 0]
  ------------------
  924|      0|            he = nullptr;
  925|      0|        }
  926|  2.01M|      }
  927|       |
  928|       |      // LANG_hu section: `moving rule' with last dash
  929|  2.01M|      if ((!he) && (langnum == LANG_hu) && (word[len - 1] == '-')) {
  ------------------
  |  Branch (929:11): [True: 2.01M, False: 0]
  |  Branch (929:20): [True: 25.4k, False: 1.99M]
  |  Branch (929:44): [True: 8.39k, False: 17.0k]
  ------------------
  930|  8.39k|        std::string dup(word, 0, len - 1);
  931|  8.39k|        he = pAMgr->compound_check(dup, -5, 0, 100, 0, nullptr, (hentry**)&rwords, 1, 0, info, scratch);
  932|  8.39k|      }
  933|       |      // end of LANG specific region
  934|  2.01M|      if (he) {
  ------------------
  |  Branch (934:11): [True: 0, False: 2.01M]
  ------------------
  935|      0|        if (root) {
  ------------------
  |  Branch (935:13): [True: 0, False: 0]
  ------------------
  936|      0|          root->assign(he->word);
  937|      0|          if (complexprefixes) {
  ------------------
  |  Branch (937:15): [True: 0, False: 0]
  ------------------
  938|      0|            if (utf8)
  ------------------
  |  Branch (938:17): [True: 0, False: 0]
  ------------------
  939|      0|              reverseword_utf(*root);
  940|      0|            else
  941|      0|              reverseword(*root);
  942|      0|          }
  943|      0|        }
  944|      0|        if (info)
  ------------------
  |  Branch (944:13): [True: 0, False: 0]
  ------------------
  945|      0|          *info |= SPELL_COMPOUND;
  ------------------
  |  |   78|      0|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  946|      0|      }
  947|  2.01M|    }
  948|  8.47M|  }
  949|       |
  950|  8.49M|  return he;
  951|  8.49M|}
_ZN12HunspellImpl7suggestERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorIS6_NS4_IS6_EEEENS0_6chrono10time_pointINSD_12steady_clockENSD_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEE:
  959|  87.7k|std::vector<std::string> HunspellImpl::suggest(const std::string& word, std::vector<std::string>& suggest_candidate_stack, std::chrono::steady_clock::time_point suggest_start) {
  960|       |
  961|  87.7k|  if (suggest_candidate_stack.size() > MAX_CANDIDATE_STACK_DEPTH || // apply a fairly arbitrary depth limit
  ------------------
  |  |  954|   175k|#define MAX_CANDIDATE_STACK_DEPTH 512
  ------------------
  |  Branch (961:7): [True: 0, False: 87.7k]
  |  Branch (961:7): [True: 0, False: 87.7k]
  ------------------
  962|       |      // something very broken if suggest ends up calling itself with the same word
  963|  87.7k|      std::find(suggest_candidate_stack.begin(), suggest_candidate_stack.end(), word) != suggest_candidate_stack.end()) {
  ------------------
  |  Branch (963:7): [True: 0, False: 87.7k]
  ------------------
  964|      0|    return { };
  965|      0|  }
  966|       |
  967|  87.7k|  if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  87.7k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (967:7): [True: 0, False: 87.7k]
  ------------------
  968|      0|    return { };
  969|       |
  970|  87.7k|  bool capwords;
  971|  87.7k|  size_t abbv;
  972|  87.7k|  int captype;
  973|  87.7k|  std::vector<std::string> spell_candidate_stack;
  974|  87.7k|  suggest_candidate_stack.push_back(word);
  975|  87.7k|  std::vector<std::string> slst = suggest_internal(word, spell_candidate_stack, suggest_candidate_stack,
  976|  87.7k|                                                   capwords, abbv, captype, suggest_start);
  977|  87.7k|  suggest_candidate_stack.pop_back();
  978|       |  // word reversing wrapper for complex prefixes
  979|  87.7k|  if (complexprefixes) {
  ------------------
  |  Branch (979:7): [True: 4.55k, False: 83.1k]
  ------------------
  980|  4.55k|    for (auto& j : slst) {
  ------------------
  |  Branch (980:18): [True: 2.34k, False: 4.55k]
  ------------------
  981|  2.34k|      if (utf8)
  ------------------
  |  Branch (981:11): [True: 0, False: 2.34k]
  ------------------
  982|      0|        reverseword_utf(j);
  983|  2.34k|      else
  984|  2.34k|        reverseword(j);
  985|  2.34k|    }
  986|  4.55k|  }
  987|       |
  988|       |  // capitalize
  989|  87.7k|  if (capwords) {
  ------------------
  |  Branch (989:7): [True: 24.0k, False: 63.7k]
  ------------------
  990|  24.0k|    for (auto& j : slst) {
  ------------------
  |  Branch (990:18): [True: 14.5k, False: 24.0k]
  ------------------
  991|  14.5k|      std::string capitalized(j);
  992|  14.5k|      mkinitcap(capitalized);
  993|  14.5k|      if (capitalized == word)
  ------------------
  |  Branch (993:11): [True: 40, False: 14.4k]
  ------------------
  994|     40|        continue;  // capitalizing would just reproduce the misspelled word
  995|  14.4k|      j = std::move(capitalized);
  996|  14.4k|    }
  997|  24.0k|  }
  998|       |
  999|       |  // expand suggestions with dot(s)
 1000|  87.7k|  if (abbv && pAMgr && pAMgr->get_sugswithdots() && word.size() >= abbv) {
  ------------------
  |  Branch (1000:7): [True: 3.16k, False: 84.5k]
  |  Branch (1000:15): [True: 3.16k, False: 0]
  |  Branch (1000:24): [True: 0, False: 3.16k]
  |  Branch (1000:53): [True: 0, False: 0]
  ------------------
 1001|      0|    for (auto& j : slst) {
  ------------------
  |  Branch (1001:18): [True: 0, False: 0]
  ------------------
 1002|      0|      j.append(word.substr(word.size() - abbv));
 1003|      0|    }
 1004|      0|  }
 1005|       |
 1006|       |  // remove bad capitalized and forbidden forms
 1007|  87.7k|  if (pAMgr && (pAMgr->get_keepcase() || pAMgr->get_forbiddenword())) {
  ------------------
  |  Branch (1007:7): [True: 87.7k, False: 0]
  |  Branch (1007:17): [True: 4.59k, False: 83.1k]
  |  Branch (1007:42): [True: 83.1k, False: 0]
  ------------------
 1008|  87.7k|    switch (captype) {
  ------------------
  |  Branch (1008:13): [True: 21.7k, False: 65.9k]
  ------------------
 1009|  11.8k|      case INITCAP:
  ------------------
  |  |   93|  11.8k|#define INITCAP 1
  ------------------
  |  Branch (1009:7): [True: 11.8k, False: 75.8k]
  ------------------
 1010|  21.7k|      case ALLCAP: {
  ------------------
  |  |   94|  21.7k|#define ALLCAP 2
  ------------------
  |  Branch (1010:7): [True: 9.89k, False: 77.8k]
  ------------------
 1011|  21.7k|        size_t l = 0;
 1012|  32.0k|        for (size_t j = 0; j < slst.size(); ++j) {
  ------------------
  |  Branch (1012:28): [True: 10.2k, False: 21.7k]
  ------------------
 1013|  10.2k|          if (slst[j].find(' ') == std::string::npos && !spell(slst[j], spell_candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (1013:15): [True: 9.66k, False: 574]
  |  Branch (1013:57): [True: 4.23k, False: 5.42k]
  ------------------
 1014|  4.23k|            std::string s;
 1015|  4.23k|            std::vector<w_char> w;
 1016|  4.23k|            if (utf8) {
  ------------------
  |  Branch (1016:17): [True: 3.39k, False: 847]
  ------------------
 1017|  3.39k|              u8_u16(w, slst[j]);
 1018|  3.39k|            } else {
 1019|    847|              s = slst[j];
 1020|    847|            }
 1021|  4.23k|            mkallsmall2(s, w);
 1022|  4.23k|            if (spell(s, spell_candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (1022:17): [True: 4, False: 4.23k]
  ------------------
 1023|      4|              slst[l] = std::move(s);
 1024|      4|              ++l;
 1025|  4.23k|            } else {
 1026|  4.23k|              mkinitcap2(s, w);
 1027|  4.23k|              if (spell(s, spell_candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (1027:19): [True: 11, False: 4.22k]
  ------------------
 1028|     11|                slst[l] = std::move(s);
 1029|     11|                ++l;
 1030|     11|              }
 1031|  4.23k|            }
 1032|  5.99k|          } else {
 1033|  5.99k|            slst[l] = slst[j];
 1034|  5.99k|            ++l;
 1035|  5.99k|          }
 1036|  10.2k|        }
 1037|  21.7k|        slst.resize(l);
 1038|  21.7k|      }
 1039|  87.7k|    }
 1040|  87.7k|  }
 1041|       |
 1042|       |  // remove duplications
 1043|  87.7k|  size_t l = 0;
 1044|   115k|  for (size_t j = 0; j < slst.size(); ++j) {
  ------------------
  |  Branch (1044:22): [True: 27.4k, False: 87.7k]
  ------------------
 1045|  27.4k|    slst[l] = slst[j];
 1046|  44.6k|    for (size_t k = 0; k < l; ++k) {
  ------------------
  |  Branch (1046:24): [True: 18.2k, False: 26.4k]
  ------------------
 1047|  18.2k|      if (slst[k] == slst[j]) {
  ------------------
  |  Branch (1047:11): [True: 1.06k, False: 17.1k]
  ------------------
 1048|  1.06k|        --l;
 1049|  1.06k|        break;
 1050|  1.06k|      }
 1051|  18.2k|    }
 1052|  27.4k|    ++l;
 1053|  27.4k|  }
 1054|  87.7k|  slst.resize(l);
 1055|       |
 1056|       |  // output conversion
 1057|  87.7k|  RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : nullptr;
  ------------------
  |  Branch (1057:17): [True: 87.7k, False: 0]
  ------------------
 1058|  87.7k|  if (rl) {
  ------------------
  |  Branch (1058:7): [True: 4.69k, False: 83.0k]
  ------------------
 1059|  4.69k|    size_t l = 0;
 1060|  5.60k|    for (size_t i = 0; i < slst.size(); ++i) {
  ------------------
  |  Branch (1060:24): [True: 918, False: 4.69k]
  ------------------
 1061|    918|      std::string wspace;
 1062|    918|      if (rl->conv(slst[i], wspace)) {
  ------------------
  |  Branch (1062:11): [True: 249, False: 669]
  ------------------
 1063|    249|        slst[i] = std::move(wspace);
 1064|    249|      }
 1065|       |      // gh#1002: OCONV can map a generated form back to the input word
 1066|       |      // (e.g. "románórum" -> "romanórum" when the user typed "romanórum"),
 1067|       |      // leaving the misspelled word as its own suggestion.
 1068|    918|      if (slst[i] == word)
  ------------------
  |  Branch (1068:11): [True: 0, False: 918]
  ------------------
 1069|      0|        continue;
 1070|    918|      if (l != i)
  ------------------
  |  Branch (1070:11): [True: 0, False: 918]
  ------------------
 1071|      0|        slst[l] = std::move(slst[i]);
 1072|    918|      ++l;
 1073|    918|    }
 1074|  4.69k|    slst.resize(l);
 1075|  4.69k|  }
 1076|  87.7k|  return slst;
 1077|  87.7k|}
_ZN12HunspellImpl7suggestERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1079|  58.1k|std::vector<std::string> HunspellImpl::suggest(const std::string& word) {
 1080|  58.1k|  std::vector<std::string> suggest_candidate_stack;
 1081|  58.1k|  auto suggest_start = std::chrono::steady_clock::now();
 1082|  58.1k|  return suggest(word, suggest_candidate_stack, suggest_start);
 1083|  58.1k|}
_ZN12HunspellImpl16suggest_internalERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorIS6_NS4_IS6_EEEESC_RbRmRiNS0_6chrono10time_pointINSG_12steady_clockENSG_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEE:
 1089|  87.7k|        std::chrono::steady_clock::time_point suggest_start) {
 1090|  87.7k|  captype = NOCAP;
  ------------------
  |  |   92|  87.7k|#define NOCAP 0
  ------------------
 1091|  87.7k|  abbv = 0;
 1092|  87.7k|  capwords = false;
 1093|       |
 1094|  87.7k|  std::vector<std::string> slst;
 1095|       |
 1096|  87.7k|  int onlycmpdsug = 0;
 1097|  87.7k|  if (!pSMgr || m_HMgrs.empty())
  ------------------
  |  Branch (1097:7): [True: 0, False: 87.7k]
  |  Branch (1097:17): [True: 0, False: 87.7k]
  ------------------
 1098|      0|    return slst;
 1099|       |
 1100|       |  // process XML input of the simplified API (see manual)
 1101|  87.7k|  if (word.compare(0, sizeof(SPELL_XML) - 3, SPELL_XML, sizeof(SPELL_XML) - 3) == 0) {
  ------------------
  |  |   79|  87.7k|#define SPELL_XML "<?xml?>"
  ------------------
                if (word.compare(0, sizeof(SPELL_XML) - 3, SPELL_XML, sizeof(SPELL_XML) - 3) == 0) {
  ------------------
  |  |   79|  87.7k|#define SPELL_XML "<?xml?>"
  ------------------
                if (word.compare(0, sizeof(SPELL_XML) - 3, SPELL_XML, sizeof(SPELL_XML) - 3) == 0) {
  ------------------
  |  |   79|  87.7k|#define SPELL_XML "<?xml?>"
  ------------------
  |  Branch (1101:7): [True: 20.4k, False: 67.2k]
  ------------------
 1102|  20.4k|    return spellml(word);
 1103|  20.4k|  }
 1104|  67.2k|  if (utf8) {
  ------------------
  |  Branch (1104:7): [True: 32.2k, False: 34.9k]
  ------------------
 1105|  32.2k|    if (word.size() >= MAXWORDUTF8LEN)
  ------------------
  |  |   86|  32.2k|#define MAXWORDUTF8LEN (MAXWORDLEN * 3)
  |  |  ------------------
  |  |  |  |   89|  32.2k|#define MAXWORDLEN 100
  |  |  ------------------
  ------------------
  |  Branch (1105:9): [True: 117, False: 32.1k]
  ------------------
 1106|    117|      return slst;
 1107|  34.9k|  } else {
 1108|  34.9k|    if (word.size() >= MAXWORDLEN)
  ------------------
  |  |   89|  34.9k|#define MAXWORDLEN 100
  ------------------
  |  Branch (1108:9): [True: 150, False: 34.8k]
  ------------------
 1109|    150|      return slst;
 1110|  34.9k|  }
 1111|  66.9k|  size_t wl = 0;
 1112|       |
 1113|  66.9k|  std::string scw;
 1114|  66.9k|  std::vector<w_char> sunicw;
 1115|       |
 1116|       |  // input conversion
 1117|  66.9k|  RepList* rl = (pAMgr) ? pAMgr->get_iconvtable() : nullptr;
  ------------------
  |  Branch (1117:17): [True: 66.9k, False: 0]
  ------------------
 1118|  66.9k|  {
 1119|  66.9k|    std::string wspace;
 1120|       |
 1121|  66.9k|    bool convstatus = rl ? rl->conv(word, wspace) : false;
  ------------------
  |  Branch (1121:23): [True: 3.60k, False: 63.3k]
  ------------------
 1122|  66.9k|    if (convstatus)
  ------------------
  |  Branch (1122:9): [True: 0, False: 66.9k]
  ------------------
 1123|      0|      wl = cleanword2(scw, sunicw, wspace, &captype, &abbv);
 1124|  66.9k|    else
 1125|  66.9k|      wl = cleanword2(scw, sunicw, word, &captype, &abbv);
 1126|       |
 1127|  66.9k|    if (wl == 0)
  ------------------
  |  Branch (1127:9): [True: 0, False: 66.9k]
  ------------------
 1128|      0|      return slst;
 1129|       |
 1130|  66.9k|#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
 1131|  66.9k|    if (wl > 32768)
  ------------------
  |  Branch (1131:9): [True: 0, False: 66.9k]
  ------------------
 1132|      0|      return slst;
 1133|  66.9k|#endif
 1134|  66.9k|  }
 1135|       |
 1136|  66.9k|  bool good = false;
 1137|       |
 1138|       |  // check capitalized form for FORCEUCASE
 1139|  66.9k|  if (pAMgr && captype == NOCAP && pAMgr->get_forceucase()) {
  ------------------
  |  |   92|   133k|#define NOCAP 0
  ------------------
  |  Branch (1139:7): [True: 66.9k, False: 0]
  |  Branch (1139:16): [True: 20.3k, False: 46.6k]
  |  Branch (1139:36): [True: 0, False: 20.3k]
  ------------------
 1140|      0|    int info = SPELL_ORIGCAP;
  ------------------
  |  |   83|      0|#define SPELL_ORIGCAP (1 << 5)
  ------------------
 1141|      0|    if (checkword(scw, &info, nullptr, suggest_start)) {
  ------------------
  |  Branch (1141:9): [True: 0, False: 0]
  ------------------
 1142|      0|      std::string form(std::move(scw));
 1143|      0|      mkinitcap(form);
 1144|      0|      slst.push_back(std::move(form));
 1145|      0|      return slst;
 1146|      0|    }
 1147|      0|  }
 1148|       |
 1149|  66.9k|  switch (captype) {
  ------------------
  |  Branch (1149:11): [True: 66.9k, False: 0]
  ------------------
 1150|  20.3k|    case NOCAP: {
  ------------------
  |  |   92|  20.3k|#define NOCAP 0
  ------------------
  |  Branch (1150:5): [True: 20.3k, False: 46.6k]
  ------------------
 1151|  20.3k|      good |= pSMgr->suggest(slst, scw, &onlycmpdsug);
 1152|  20.3k|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  20.3k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1152:11): [True: 0, False: 20.3k]
  ------------------
 1153|      0|          return slst;
 1154|  20.3k|      if (abbv) {
  ------------------
  |  Branch (1154:11): [True: 1.95k, False: 18.3k]
  ------------------
 1155|  1.95k|        std::string wspace(scw);
 1156|  1.95k|        wspace.push_back('.');
 1157|  1.95k|        good |= pSMgr->suggest(slst, wspace, &onlycmpdsug);
 1158|  1.95k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  1.95k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1158:13): [True: 0, False: 1.95k]
  ------------------
 1159|      0|            return slst;
 1160|  1.95k|      }
 1161|  20.3k|      break;
 1162|  20.3k|    }
 1163|       |
 1164|  20.3k|    case INITCAP: {
  ------------------
  |  |   93|  11.8k|#define INITCAP 1
  ------------------
  |  Branch (1164:5): [True: 11.8k, False: 55.0k]
  ------------------
 1165|  11.8k|      capwords = true;
 1166|  11.8k|      good |= pSMgr->suggest(slst, scw, &onlycmpdsug);
 1167|  11.8k|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  11.8k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1167:11): [True: 0, False: 11.8k]
  ------------------
 1168|      0|          return slst;
 1169|  11.8k|      std::string wspace(scw);
 1170|  11.8k|      mkallsmall2(wspace, sunicw);
 1171|  11.8k|      good |= pSMgr->suggest(slst, wspace, &onlycmpdsug);
 1172|  11.8k|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  11.8k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1172:11): [True: 0, False: 11.8k]
  ------------------
 1173|      0|          return slst;
 1174|  11.8k|      break;
 1175|  11.8k|    }
 1176|  12.1k|    case HUHINITCAP:
  ------------------
  |  |   96|  12.1k|#define HUHINITCAP 4
  ------------------
  |  Branch (1176:5): [True: 12.1k, False: 54.8k]
  ------------------
 1177|  12.1k|      capwords = true;
 1178|       |      /* FALLTHROUGH */
 1179|  24.8k|    case HUHCAP: {
  ------------------
  |  |   95|  24.8k|#define HUHCAP 3
  ------------------
  |  Branch (1179:5): [True: 12.7k, False: 54.2k]
  ------------------
 1180|  24.8k|      good |= pSMgr->suggest(slst, scw, &onlycmpdsug);
 1181|  24.8k|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  24.8k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1181:11): [True: 0, False: 24.8k]
  ------------------
 1182|      0|          return slst;
 1183|       |      // something.The -> something. The
 1184|  24.8k|      size_t dot_pos = scw.find('.');
 1185|  24.8k|      if (dot_pos != std::string::npos) {
  ------------------
  |  Branch (1185:11): [True: 7.93k, False: 16.9k]
  ------------------
 1186|  7.93k|        std::string postdot = scw.substr(dot_pos + 1);
 1187|  7.93k|        int captype_;
 1188|  7.93k|        if (utf8) {
  ------------------
  |  Branch (1188:13): [True: 1.82k, False: 6.11k]
  ------------------
 1189|  1.82k|          std::vector<w_char> postdotu;
 1190|  1.82k|          u8_u16(postdotu, postdot);
 1191|  1.82k|          captype_ = get_captype_utf8(postdotu, langnum);
 1192|  6.11k|        } else {
 1193|  6.11k|          captype_ = get_captype(postdot, csconv);
 1194|  6.11k|        }
 1195|  7.93k|        if (captype_ == INITCAP) {
  ------------------
  |  |   93|  7.93k|#define INITCAP 1
  ------------------
  |  Branch (1195:13): [True: 2.04k, False: 5.89k]
  ------------------
 1196|  2.04k|          std::string str(scw);
 1197|  2.04k|          str.insert(dot_pos + 1, 1, ' ');
 1198|  2.04k|          insert_sug(slst, str);
 1199|  2.04k|        }
 1200|  7.93k|      }
 1201|       |
 1202|  24.8k|      std::string wspace;
 1203|       |
 1204|  24.8k|      if (captype == HUHINITCAP) {
  ------------------
  |  |   96|  24.8k|#define HUHINITCAP 4
  ------------------
  |  Branch (1204:11): [True: 12.1k, False: 12.7k]
  ------------------
 1205|       |        // TheOpenOffice.org -> The OpenOffice.org
 1206|  12.1k|        wspace = scw;
 1207|  12.1k|        mkinitsmall2(wspace, sunicw);
 1208|  12.1k|        good |= pSMgr->suggest(slst, wspace, &onlycmpdsug);
 1209|  12.1k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  12.1k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1209:13): [True: 0, False: 12.1k]
  ------------------
 1210|      0|            return slst;
 1211|  12.1k|      }
 1212|  24.8k|      wspace = scw;
 1213|  24.8k|      mkallsmall2(wspace, sunicw);
 1214|  24.8k|      if (spell(wspace, spell_candidate_stack, nullptr, nullptr, suggest_start))
  ------------------
  |  Branch (1214:11): [True: 806, False: 24.0k]
  ------------------
 1215|    806|        insert_sug(slst, wspace);
 1216|  24.8k|      size_t prevns = slst.size();
 1217|  24.8k|      good |= pSMgr->suggest(slst, wspace, &onlycmpdsug);
 1218|  24.8k|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  24.8k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1218:11): [True: 3, False: 24.8k]
  ------------------
 1219|      3|          return slst;
 1220|  24.8k|      if (captype == HUHINITCAP) {
  ------------------
  |  |   96|  24.8k|#define HUHINITCAP 4
  ------------------
  |  Branch (1220:11): [True: 12.1k, False: 12.7k]
  ------------------
 1221|  12.1k|        mkinitcap2(wspace, sunicw);
 1222|  12.1k|        if (spell(wspace, spell_candidate_stack, nullptr, nullptr, suggest_start))
  ------------------
  |  Branch (1222:13): [True: 347, False: 11.7k]
  ------------------
 1223|    347|          insert_sug(slst, wspace);
 1224|  12.1k|        good |= pSMgr->suggest(slst, wspace, &onlycmpdsug);
 1225|  12.1k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  12.1k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1225:13): [True: 0, False: 12.1k]
  ------------------
 1226|      0|            return slst;
 1227|  12.1k|      }
 1228|       |      // aNew -> "a New" (instead of "a new")
 1229|  25.3k|      for (size_t j = prevns; j < slst.size(); ++j) {
  ------------------
  |  Branch (1229:31): [True: 464, False: 24.8k]
  ------------------
 1230|    464|        const char* space = strchr(slst[j].c_str(), ' ');
 1231|    464|        if (space) {
  ------------------
  |  Branch (1231:13): [True: 346, False: 118]
  ------------------
 1232|    346|          size_t slen = strlen(space + 1);
 1233|       |          // different case after space (need capitalisation)
 1234|    346|          if ((slen < wl) && strcmp(scw.c_str() + wl - slen, space + 1) != 0) {
  ------------------
  |  Branch (1234:15): [True: 346, False: 0]
  |  Branch (1234:30): [True: 336, False: 10]
  ------------------
 1235|    336|            std::string first(slst[j].c_str(), space + 1);
 1236|    336|            std::string second(space + 1);
 1237|    336|            std::vector<w_char> w;
 1238|    336|            if (utf8)
  ------------------
  |  Branch (1238:17): [True: 100, False: 236]
  ------------------
 1239|    100|              u8_u16(w, second);
 1240|    336|            mkinitcap2(second, w);
 1241|       |            // set as first suggestion
 1242|    336|            slst.erase(slst.begin() + j);
 1243|    336|            slst.insert(slst.begin(), first + second);
 1244|    336|          }
 1245|    346|        }
 1246|    464|      }
 1247|  24.8k|      break;
 1248|  24.8k|    }
 1249|       |
 1250|  9.89k|    case ALLCAP: {
  ------------------
  |  |   94|  9.89k|#define ALLCAP 2
  ------------------
  |  Branch (1250:5): [True: 9.89k, False: 57.0k]
  ------------------
 1251|  9.89k|      std::string wspace(scw);
 1252|  9.89k|      mkallsmall2(wspace, sunicw);
 1253|  9.89k|      good |= pSMgr->suggest(slst, wspace, &onlycmpdsug);
 1254|  9.89k|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  9.89k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1254:11): [True: 0, False: 9.89k]
  ------------------
 1255|      0|          return slst;
 1256|  9.89k|      if (pAMgr && pAMgr->get_keepcase() && spell(wspace, spell_candidate_stack, nullptr, nullptr, suggest_start))
  ------------------
  |  Branch (1256:11): [True: 9.89k, False: 0]
  |  Branch (1256:20): [True: 441, False: 9.45k]
  |  Branch (1256:45): [True: 0, False: 441]
  ------------------
 1257|      0|        insert_sug(slst, wspace);
 1258|  9.89k|      mkinitcap2(wspace, sunicw);
 1259|  9.89k|      good |= pSMgr->suggest(slst, wspace, &onlycmpdsug);
 1260|  9.89k|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  9.89k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1260:11): [True: 0, False: 9.89k]
  ------------------
 1261|      0|          return slst;
 1262|  9.89k|      for (auto& j : slst) {
  ------------------
  |  Branch (1262:20): [True: 476, False: 9.89k]
  ------------------
 1263|    476|        mkallcap(j);
 1264|    476|        if (pAMgr && pAMgr->get_checksharps()) {
  ------------------
  |  Branch (1264:13): [True: 476, False: 0]
  |  Branch (1264:22): [True: 0, False: 476]
  ------------------
 1265|      0|          if (utf8) {
  ------------------
  |  Branch (1265:15): [True: 0, False: 0]
  ------------------
 1266|      0|            mystrrep(j, "\xC3\x9F", "SS");
 1267|      0|          } else {
 1268|      0|            mystrrep(j, "\xDF", "SS");
 1269|      0|          }
 1270|      0|        }
 1271|    476|      }
 1272|  9.89k|      break;
 1273|  9.89k|    }
 1274|  66.9k|  }
 1275|       |
 1276|       |  // LANG_hu section: replace '-' with ' ' in Hungarian
 1277|  66.9k|  if (langnum == LANG_hu) {
  ------------------
  |  Branch (1277:7): [True: 3.65k, False: 63.3k]
  ------------------
 1278|  3.65k|    for (auto& j : slst) {
  ------------------
  |  Branch (1278:18): [True: 162, False: 3.65k]
  ------------------
 1279|    162|      size_t pos = j.find('-');
 1280|    162|      if (pos != std::string::npos) {
  ------------------
  |  Branch (1280:11): [True: 30, False: 132]
  ------------------
 1281|     30|        int info;
 1282|     30|        std::string w(j.substr(0, pos));
 1283|     30|        w.append(j.substr(pos + 1));
 1284|     30|        (void)spell(w, spell_candidate_stack, &info, nullptr, suggest_start);
 1285|     30|        if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) {
  ------------------
  |  |   78|     30|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
                      if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) {
  ------------------
  |  |   79|      0|#define SPELL_FORBIDDEN (1 << 1)
  ------------------
  |  Branch (1285:13): [True: 0, False: 30]
  |  Branch (1285:40): [True: 0, False: 0]
  ------------------
 1286|      0|          j[pos] = ' ';
 1287|      0|        } else
 1288|     30|          j[pos] = '-';
 1289|     30|      }
 1290|    162|    }
 1291|  3.65k|  }
 1292|       |  // END OF LANG_hu section
 1293|       |  // try ngram approach since found nothing good suggestion
 1294|  66.9k|  if (!good && pAMgr && (slst.empty() || onlycmpdsug) && (pAMgr->get_maxngramsugs() != 0)) {
  ------------------
  |  Branch (1294:7): [True: 66.9k, False: 63]
  |  Branch (1294:16): [True: 66.9k, False: 0]
  |  Branch (1294:26): [True: 62.4k, False: 4.47k]
  |  Branch (1294:42): [True: 4.44k, False: 25]
  |  Branch (1294:58): [True: 59.6k, False: 7.20k]
  ------------------
 1295|  59.6k|    switch (captype) {
  ------------------
  |  Branch (1295:13): [True: 59.6k, False: 0]
  ------------------
 1296|  17.5k|      case NOCAP: {
  ------------------
  |  |   92|  17.5k|#define NOCAP 0
  ------------------
  |  Branch (1296:7): [True: 17.5k, False: 42.1k]
  ------------------
 1297|  17.5k|        pSMgr->ngsuggest(slst, scw.c_str(), m_HMgrs, NOCAP);
  ------------------
  |  |   92|  17.5k|#define NOCAP 0
  ------------------
 1298|  17.5k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  17.5k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1298:13): [True: 0, False: 17.5k]
  ------------------
 1299|      0|            return slst;
 1300|  17.5k|        break;
 1301|  17.5k|      }
 1302|       |      /* FALLTHROUGH */
 1303|  17.5k|      case HUHINITCAP:
  ------------------
  |  |   96|  11.5k|#define HUHINITCAP 4
  ------------------
  |  Branch (1303:7): [True: 11.5k, False: 48.1k]
  ------------------
 1304|  11.5k|        capwords = true;
 1305|       |      /* FALLTHROUGH */
 1306|  23.3k|      case HUHCAP: {
  ------------------
  |  |   95|  23.3k|#define HUHCAP 3
  ------------------
  |  Branch (1306:7): [True: 11.7k, False: 47.8k]
  ------------------
 1307|  23.3k|        std::string wspace(scw);
 1308|  23.3k|        mkallsmall2(wspace, sunicw);
 1309|  23.3k|        pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, HUHCAP);
  ------------------
  |  |   95|  23.3k|#define HUHCAP 3
  ------------------
 1310|  23.3k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  23.3k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1310:13): [True: 0, False: 23.3k]
  ------------------
 1311|      0|            return slst;
 1312|  23.3k|        break;
 1313|  23.3k|      }
 1314|  23.3k|      case INITCAP: {
  ------------------
  |  |   93|  10.1k|#define INITCAP 1
  ------------------
  |  Branch (1314:7): [True: 10.1k, False: 49.5k]
  ------------------
 1315|  10.1k|        capwords = true;
 1316|  10.1k|        std::string wspace(scw);
 1317|  10.1k|        mkallsmall2(wspace, sunicw);
 1318|  10.1k|        pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, INITCAP);
  ------------------
  |  |   93|  10.1k|#define INITCAP 1
  ------------------
 1319|  10.1k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  10.1k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1319:13): [True: 0, False: 10.1k]
  ------------------
 1320|      0|            return slst;
 1321|  10.1k|        break;
 1322|  10.1k|      }
 1323|  10.1k|      case ALLCAP: {
  ------------------
  |  |   94|  8.66k|#define ALLCAP 2
  ------------------
  |  Branch (1323:7): [True: 8.66k, False: 51.0k]
  ------------------
 1324|  8.66k|        std::string wspace(scw);
 1325|  8.66k|        mkallsmall2(wspace, sunicw);
 1326|  8.66k|        size_t oldns = slst.size();
 1327|  8.66k|        pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, ALLCAP);
  ------------------
  |  |   94|  8.66k|#define ALLCAP 2
  ------------------
 1328|  8.66k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  8.66k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1328:13): [True: 0, False: 8.66k]
  ------------------
 1329|      0|            return slst;
 1330|  11.7k|        for (size_t j = oldns; j < slst.size(); ++j) {
  ------------------
  |  Branch (1330:32): [True: 3.07k, False: 8.66k]
  ------------------
 1331|  3.07k|          mkallcap(slst[j]);
 1332|  3.07k|        }
 1333|  8.66k|        break;
 1334|  8.66k|      }
 1335|  59.6k|    }
 1336|  59.6k|  }
 1337|       |
 1338|       |  // try dash suggestion (Afo-American -> Afro-American)
 1339|       |  // Note: LibreOffice was modified to treat dashes as word
 1340|       |  // characters to check "scot-free" etc. word forms, but
 1341|       |  // we need to handle suggestions for "Afo-American", etc.,
 1342|       |  // while "Afro-American" is missing from the dictionary.
 1343|       |  // TODO avoid possible overgeneration
 1344|  66.9k|  size_t dash_pos = scw.find('-');
 1345|  66.9k|  if (dash_pos != std::string::npos) {
  ------------------
  |  Branch (1345:7): [True: 32.6k, False: 34.2k]
  ------------------
 1346|  32.6k|    int nodashsug = 1;
 1347|  39.3k|    for (size_t j = 0; j < slst.size() && nodashsug == 1; ++j) {
  ------------------
  |  Branch (1347:24): [True: 7.09k, False: 32.2k]
  |  Branch (1347:43): [True: 6.65k, False: 444]
  ------------------
 1348|  6.65k|      if (slst[j].find('-') != std::string::npos)
  ------------------
  |  Branch (1348:11): [True: 2.51k, False: 4.14k]
  ------------------
 1349|  2.51k|        nodashsug = 0;
 1350|  6.65k|    }
 1351|       |
 1352|  32.6k|    size_t prev_pos = 0;
 1353|  32.6k|    bool last = false;
 1354|       |
 1355|   101k|    while (!good && nodashsug && !last) {
  ------------------
  |  Branch (1355:12): [True: 101k, False: 37]
  |  Branch (1355:21): [True: 69.5k, False: 32.0k]
  |  Branch (1355:34): [True: 68.9k, False: 591]
  ------------------
 1356|  68.9k|      if (dash_pos == scw.size())
  ------------------
  |  Branch (1356:11): [True: 5.56k, False: 63.3k]
  ------------------
 1357|  5.56k|        last = true;
 1358|  68.9k|      std::string chunk = scw.substr(prev_pos, dash_pos - prev_pos);
 1359|  68.9k|      if (chunk != word && !spell(chunk, spell_candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (1359:11): [True: 68.9k, False: 0]
  |  Branch (1359:28): [True: 29.5k, False: 39.4k]
  ------------------
 1360|  29.5k|        std::vector<std::string> nlst = suggest(chunk, suggest_candidate_stack, suggest_start);
 1361|  29.5k|        if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|  29.5k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1361:13): [True: 3, False: 29.5k]
  ------------------
 1362|      3|            return slst;
 1363|  40.2k|        for (auto j = nlst.rbegin(); j != nlst.rend(); ++j) {
  ------------------
  |  Branch (1363:38): [True: 10.7k, False: 29.5k]
  ------------------
 1364|  10.7k|          std::string wspace = scw.substr(0, prev_pos);
 1365|  10.7k|          wspace.append(*j);
 1366|  10.7k|          if (!last) {
  ------------------
  |  Branch (1366:15): [True: 8.28k, False: 2.43k]
  ------------------
 1367|  8.28k|            wspace.append("-");
 1368|  8.28k|            wspace.append(scw.substr(dash_pos + 1));
 1369|  8.28k|          }
 1370|  10.7k|          int info = 0;
 1371|  10.7k|          if (pAMgr && pAMgr->get_forbiddenword())
  ------------------
  |  Branch (1371:15): [True: 10.7k, False: 0]
  |  Branch (1371:24): [True: 10.7k, False: 0]
  ------------------
 1372|  10.7k|            checkword(wspace, &info, nullptr, suggest_start);
 1373|  10.7k|          if (!(info & SPELL_FORBIDDEN))
  ------------------
  |  |   79|  10.7k|#define SPELL_FORBIDDEN (1 << 1)
  ------------------
  |  Branch (1373:15): [True: 10.7k, False: 0]
  ------------------
 1374|  10.7k|            insert_sug(slst, wspace);
 1375|  10.7k|        }
 1376|  29.5k|        nodashsug = 0;
 1377|  29.5k|      }
 1378|  68.9k|      if (!last) {
  ------------------
  |  Branch (1378:11): [True: 63.3k, False: 5.56k]
  ------------------
 1379|  63.3k|        prev_pos = dash_pos + 1;
 1380|  63.3k|        dash_pos = scw.find('-', prev_pos);
 1381|  63.3k|      }
 1382|  68.9k|      if (dash_pos == std::string::npos)
  ------------------
  |  Branch (1382:11): [True: 12.5k, False: 56.3k]
  ------------------
 1383|  12.5k|        dash_pos = scw.size();
 1384|  68.9k|    }
 1385|  32.6k|  }
 1386|  66.9k|  return slst;
 1387|  66.9k|}
_ZN12HunspellImpl4stemERKNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEE:
 1393|  1.10k|std::vector<std::string> HunspellImpl::stem(const std::vector<std::string>& desc) {
 1394|  1.10k|  std::vector<std::string> slst;
 1395|       |
 1396|  1.10k|  std::string result2;
 1397|  1.10k|  if (desc.empty())
  ------------------
  |  Branch (1397:7): [True: 907, False: 195]
  ------------------
 1398|    907|    return slst;
 1399|    195|  for (const auto& i : desc) {
  ------------------
  |  Branch (1399:22): [True: 195, False: 195]
  ------------------
 1400|    195|    std::string result;
 1401|       |
 1402|       |    // add compound word parts (except the last one)
 1403|    195|    const char* s = i.c_str();
 1404|    195|    const char* part = strstr(s, MORPH_PART);
  ------------------
  |  |  116|    195|#define MORPH_PART "pa:"
  ------------------
 1405|    195|    if (part) {
  ------------------
  |  Branch (1405:9): [True: 0, False: 195]
  ------------------
 1406|      0|      const char* nextpart = strstr(part + 1, MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 1407|      0|      while (nextpart) {
  ------------------
  |  Branch (1407:14): [True: 0, False: 0]
  ------------------
 1408|      0|        std::string field;
 1409|      0|        copy_field(field, part, MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 1410|      0|        result.append(field);
 1411|      0|        part = nextpart;
 1412|      0|        nextpart = strstr(part + 1, MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 1413|      0|      }
 1414|      0|      s = part;
 1415|      0|    }
 1416|       |
 1417|    195|    std::string tok(s);
 1418|    195|    size_t alt = 0;
 1419|    195|    while ((alt = tok.find(" | ", alt)) != std::string::npos) {
  ------------------
  |  Branch (1419:12): [True: 0, False: 195]
  ------------------
 1420|      0|      tok[alt + 1] = MSEP_ALT;
  ------------------
  |  |  123|      0|#define MSEP_ALT '\v'
  ------------------
 1421|      0|    }
 1422|    195|    std::vector<std::string> pl = line_tok(tok, MSEP_ALT);
  ------------------
  |  |  123|    195|#define MSEP_ALT '\v'
  ------------------
 1423|    195|    for (auto& k : pl) {
  ------------------
  |  Branch (1423:18): [True: 195, False: 195]
  ------------------
 1424|       |      // add derivational suffixes
 1425|    195|      if (k.find(MORPH_DERI_SFX) != std::string::npos) {
  ------------------
  |  |  109|    195|#define MORPH_DERI_SFX "ds:"
  ------------------
  |  Branch (1425:11): [True: 0, False: 195]
  ------------------
 1426|       |        // remove inflectional suffixes
 1427|      0|        const size_t is = k.find(MORPH_INFL_SFX);
  ------------------
  |  |  110|      0|#define MORPH_INFL_SFX "is:"
  ------------------
 1428|      0|        if (is != std::string::npos)
  ------------------
  |  Branch (1428:13): [True: 0, False: 0]
  ------------------
 1429|      0|          k.resize(is);
 1430|      0|        std::vector<std::string> singlepl;
 1431|      0|        singlepl.push_back(k);
 1432|      0|        std::string sg = pSMgr->suggest_gen(singlepl, k);
 1433|      0|        if (!sg.empty()) {
  ------------------
  |  Branch (1433:13): [True: 0, False: 0]
  ------------------
 1434|      0|          std::vector<std::string> gen = line_tok(sg, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1435|      0|          for (auto& j : gen) {
  ------------------
  |  Branch (1435:24): [True: 0, False: 0]
  ------------------
 1436|      0|            result2.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1437|      0|            result2.append(result);
 1438|      0|            result2.append(j);
 1439|      0|          }
 1440|      0|        }
 1441|    195|      } else {
 1442|    195|        result2.push_back(MSEP_REC);
  ------------------
  |  |  122|    195|#define MSEP_REC '\n'
  ------------------
 1443|    195|        result2.append(result);
 1444|    195|        if (k.find(MORPH_SURF_PFX) != std::string::npos) {
  ------------------
  |  |  112|    195|#define MORPH_SURF_PFX "sp:"
  ------------------
  |  Branch (1444:13): [True: 0, False: 195]
  ------------------
 1445|      0|          std::string field;
 1446|      0|          copy_field(field, k, MORPH_SURF_PFX);
  ------------------
  |  |  112|      0|#define MORPH_SURF_PFX "sp:"
  ------------------
 1447|      0|          result2.append(field);
 1448|      0|        }
 1449|    195|        std::string field;
 1450|    195|        copy_field(field, k, MORPH_STEM);
  ------------------
  |  |  103|    195|#define MORPH_STEM "st:"
  ------------------
 1451|    195|        result2.append(field);
 1452|    195|      }
 1453|    195|    }
 1454|    195|  }
 1455|    195|  slst = line_tok(result2, MSEP_REC);
  ------------------
  |  |  122|    195|#define MSEP_REC '\n'
  ------------------
 1456|    195|  uniqlist(slst);
 1457|    195|  return slst;
 1458|  1.10k|}
_ZN12HunspellImpl4stemERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1460|  1.10k|std::vector<std::string> HunspellImpl::stem(const std::string& word) {
 1461|  1.10k|  return stem(analyze(word));
 1462|  1.10k|}
_ZN12HunspellImpl9mkinitcapERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1472|  14.5k|void HunspellImpl::mkinitcap(std::string& u8) {
 1473|  14.5k|  if (utf8) {
  ------------------
  |  Branch (1473:7): [True: 3.73k, False: 10.7k]
  ------------------
 1474|  3.73k|    std::vector<w_char> u16;
 1475|  3.73k|    u8_u16(u16, u8);
 1476|  3.73k|    ::mkinitcap_utf(u16, langnum);
 1477|  3.73k|    u16_u8(u8, u16);
 1478|  10.7k|  } else {
 1479|  10.7k|    ::mkinitcap(u8, csconv);
 1480|  10.7k|  }
 1481|  14.5k|}
_ZN12HunspellImpl10mkinitcap2ERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorI6w_charNS4_IS9_EEEE:
 1483|   789k|int HunspellImpl::mkinitcap2(std::string& u8, std::vector<w_char>& u16) {
 1484|   789k|  if (utf8) {
  ------------------
  |  Branch (1484:7): [True: 197k, False: 592k]
  ------------------
 1485|   197k|    ::mkinitcap_utf(u16, langnum);
 1486|   197k|    u16_u8(u8, u16);
 1487|   592k|  } else {
 1488|   592k|    ::mkinitcap(u8, csconv);
 1489|   592k|  }
 1490|   789k|  return u8.size();
 1491|   789k|}
_ZN12HunspellImpl12mkinitsmall2ERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERNS0_6vectorI6w_charNS4_IS9_EEEE:
 1493|  12.1k|int HunspellImpl::mkinitsmall2(std::string& u8, std::vector<w_char>& u16) {
 1494|  12.1k|  if (utf8) {
  ------------------
  |  Branch (1494:7): [True: 2.60k, False: 9.53k]
  ------------------
 1495|  2.60k|    ::mkinitsmall_utf(u16, langnum);
 1496|  2.60k|    u16_u8(u8, u16);
 1497|  9.53k|  } else {
 1498|  9.53k|    ::mkinitsmall(u8, csconv);
 1499|  9.53k|  }
 1500|  12.1k|  return u8.size();
 1501|  12.1k|}
_ZN12HunspellImpl3addERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1503|  5.10k|int HunspellImpl::add(const std::string& word) {
 1504|  5.10k|  if (!m_HMgrs.empty())
  ------------------
  |  Branch (1504:7): [True: 5.10k, False: 0]
  ------------------
 1505|  5.10k|    return m_HMgrs[0]->add(word);
 1506|      0|  return 0;
 1507|  5.10k|}
_ZN12HunspellImpl14add_with_affixERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_:
 1515|  1.46k|int HunspellImpl::add_with_affix(const std::string& word, const std::string& example) {
 1516|  1.46k|  if (!m_HMgrs.empty())
  ------------------
  |  Branch (1516:7): [True: 1.46k, False: 0]
  ------------------
 1517|  1.46k|    return m_HMgrs[0]->add_with_affix(word, example);
 1518|      0|  return 0;
 1519|  1.46k|}
_ZN12HunspellImpl10cat_resultERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKS6_:
 1538|  7.76M|void HunspellImpl::cat_result(std::string& result, const std::string& st) {
 1539|  7.76M|  if (!st.empty()) {
  ------------------
  |  Branch (1539:7): [True: 1.88k, False: 7.76M]
  ------------------
 1540|  1.88k|    if (!result.empty())
  ------------------
  |  Branch (1540:9): [True: 200, False: 1.68k]
  ------------------
 1541|    200|      result.append("\n");
 1542|  1.88k|    result.append(st);
 1543|  1.88k|  }
 1544|  7.76M|}
_ZN12HunspellImpl7analyzeERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1546|  7.28k|std::vector<std::string> HunspellImpl::analyze(const std::string& word) {
 1547|  7.28k|  std::vector<std::string> slst = analyze_internal(word);
 1548|       |  // output conversion
 1549|  7.28k|  RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : nullptr;
  ------------------
  |  Branch (1549:17): [True: 7.28k, False: 0]
  ------------------
 1550|  7.28k|  if (rl) {
  ------------------
  |  Branch (1550:7): [True: 381, False: 6.90k]
  ------------------
 1551|    448|    for (size_t i = 0; rl && i < slst.size(); ++i) {
  ------------------
  |  Branch (1551:24): [True: 448, False: 0]
  |  Branch (1551:30): [True: 67, False: 381]
  ------------------
 1552|     67|      std::string wspace;
 1553|     67|      if (rl->conv(slst[i], wspace)) {
  ------------------
  |  Branch (1553:11): [True: 13, False: 54]
  ------------------
 1554|     13|        slst[i] = std::move(wspace);
 1555|     13|      }
 1556|     67|    }
 1557|    381|  }
 1558|  7.28k|  return slst;
 1559|  7.28k|}
_ZN12HunspellImpl16analyze_internalERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1561|  7.28k|std::vector<std::string> HunspellImpl::analyze_internal(const std::string& word) {
 1562|  7.28k|  std::vector<std::string> candidate_stack, slst;
 1563|  7.28k|  if (!pSMgr || m_HMgrs.empty())
  ------------------
  |  Branch (1563:7): [True: 0, False: 7.28k]
  |  Branch (1563:17): [True: 0, False: 7.28k]
  ------------------
 1564|      0|    return slst;
 1565|  7.28k|  if (utf8) {
  ------------------
  |  Branch (1565:7): [True: 3.43k, False: 3.84k]
  ------------------
 1566|  3.43k|    if (word.size() >= MAXWORDUTF8LEN)
  ------------------
  |  |   86|  3.43k|#define MAXWORDUTF8LEN (MAXWORDLEN * 3)
  |  |  ------------------
  |  |  |  |   89|  3.43k|#define MAXWORDLEN 100
  |  |  ------------------
  ------------------
  |  Branch (1566:9): [True: 603, False: 2.83k]
  ------------------
 1567|    603|      return slst;
 1568|  3.84k|  } else {
 1569|  3.84k|    if (word.size() >= MAXWORDLEN)
  ------------------
  |  |   89|  3.84k|#define MAXWORDLEN 100
  ------------------
  |  Branch (1569:9): [True: 810, False: 3.03k]
  ------------------
 1570|    810|      return slst;
 1571|  3.84k|  }
 1572|  5.87k|  int captype = NOCAP;
  ------------------
  |  |   92|  5.87k|#define NOCAP 0
  ------------------
 1573|  5.87k|  size_t abbv = 0;
 1574|  5.87k|  size_t wl = 0;
 1575|       |
 1576|  5.87k|  std::string scw;
 1577|  5.87k|  std::vector<w_char> sunicw;
 1578|       |
 1579|       |  // input conversion
 1580|  5.87k|  RepList* rl = (pAMgr) ? pAMgr->get_iconvtable() : nullptr;
  ------------------
  |  Branch (1580:17): [True: 5.87k, False: 0]
  ------------------
 1581|  5.87k|  {
 1582|  5.87k|    std::string wspace;
 1583|       |
 1584|  5.87k|    bool convstatus = rl ? rl->conv(word, wspace) : false;
  ------------------
  |  Branch (1584:23): [True: 314, False: 5.55k]
  ------------------
 1585|  5.87k|    if (convstatus)
  ------------------
  |  Branch (1585:9): [True: 0, False: 5.87k]
  ------------------
 1586|      0|      wl = cleanword2(scw, sunicw, wspace, &captype, &abbv);
 1587|  5.87k|    else
 1588|  5.87k|      wl = cleanword2(scw, sunicw, word, &captype, &abbv);
 1589|       |
 1590|  5.87k|#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
 1591|  5.87k|    if (wl > 32768)
  ------------------
  |  Branch (1591:9): [True: 0, False: 5.87k]
  ------------------
 1592|      0|      return slst;
 1593|  5.87k|#endif
 1594|  5.87k|  }
 1595|       |
 1596|  5.87k|  if (wl == 0) {
  ------------------
  |  Branch (1596:7): [True: 400, False: 5.47k]
  ------------------
 1597|    400|    if (abbv) {
  ------------------
  |  Branch (1597:9): [True: 266, False: 134]
  ------------------
 1598|    266|      scw.clear();
 1599|  4.27k|      for (wl = 0; wl < abbv; wl++)
  ------------------
  |  Branch (1599:20): [True: 4.00k, False: 266]
  ------------------
 1600|  4.00k|        scw.push_back('.');
 1601|    266|      abbv = 0;
 1602|    266|    } else
 1603|    134|      return slst;
 1604|    400|  }
 1605|       |
 1606|  5.73k|  std::string result;
 1607|       |
 1608|  5.73k|  size_t n = 0;
 1609|       |  // test numbers
 1610|       |  // LANG_hu section: set dash information for suggestions
 1611|  5.73k|  if (langnum == LANG_hu) {
  ------------------
  |  Branch (1611:7): [True: 308, False: 5.42k]
  ------------------
 1612|    308|    size_t n2 = 0;
 1613|    308|    size_t n3 = 0;
 1614|       |
 1615|    454|    while ((n < wl) && (((scw[n] <= '9') && (scw[n] >= '0')) ||
  ------------------
  |  Branch (1615:12): [True: 427, False: 27]
  |  Branch (1615:26): [True: 241, False: 186]
  |  Branch (1615:45): [True: 146, False: 95]
  ------------------
 1616|    281|                        (((scw[n] == '.') || (scw[n] == ',')) && (n > 0)))) {
  ------------------
  |  Branch (1616:27): [True: 20, False: 261]
  |  Branch (1616:46): [True: 0, False: 261]
  |  Branch (1616:66): [True: 0, False: 20]
  ------------------
 1617|    146|      n++;
 1618|    146|      if ((scw[n] == '.') || (scw[n] == ',')) {
  ------------------
  |  Branch (1618:11): [True: 0, False: 146]
  |  Branch (1618:30): [True: 0, False: 146]
  ------------------
 1619|      0|        if (((n2 == 0) && (n > 3)) ||
  ------------------
  |  Branch (1619:14): [True: 0, False: 0]
  |  Branch (1619:27): [True: 0, False: 0]
  ------------------
 1620|      0|            ((n2 > 0) && ((scw[n - 1] == '.') || (scw[n - 1] == ','))))
  ------------------
  |  Branch (1620:14): [True: 0, False: 0]
  |  Branch (1620:27): [True: 0, False: 0]
  |  Branch (1620:50): [True: 0, False: 0]
  ------------------
 1621|      0|          break;
 1622|      0|        n2++;
 1623|      0|        n3 = n;
 1624|      0|      }
 1625|    146|    }
 1626|       |
 1627|    308|    if ((n == wl) && (n3 > 0) && (n - n3 > 3))
  ------------------
  |  Branch (1627:9): [True: 27, False: 281]
  |  Branch (1627:22): [True: 0, False: 27]
  |  Branch (1627:34): [True: 0, False: 0]
  ------------------
 1628|      0|      return slst;
 1629|    308|    if ((n == wl) || ((n > 0) && ((scw[n] == '%') || (scw[n] == '\xB0')) && checkword(scw.substr(n), nullptr, nullptr))) {
  ------------------
  |  Branch (1629:9): [True: 27, False: 281]
  |  Branch (1629:9): [True: 27, False: 281]
  |  Branch (1629:23): [True: 4, False: 277]
  |  Branch (1629:35): [True: 0, False: 4]
  |  Branch (1629:54): [True: 0, False: 4]
  |  Branch (1629:77): [True: 0, False: 0]
  ------------------
 1630|     27|      result.append(scw);
 1631|     27|      result.resize(n - 1);
 1632|     27|      if (n == wl)
  ------------------
  |  Branch (1632:11): [True: 27, False: 0]
  ------------------
 1633|     27|        cat_result(result, pSMgr->suggest_morph(scw.substr(n - 1)));
 1634|      0|      else {
 1635|      0|        std::string chunk = scw.substr(n - 1, 1);
 1636|      0|        cat_result(result, pSMgr->suggest_morph(chunk));
 1637|      0|        result.push_back('+');  // XXX SPEC. MORPHCODE
 1638|      0|        cat_result(result, pSMgr->suggest_morph(scw.substr(n)));
 1639|      0|      }
 1640|     27|      return line_tok(result, MSEP_REC);
  ------------------
  |  |  122|     27|#define MSEP_REC '\n'
  ------------------
 1641|     27|    }
 1642|    308|  }
 1643|       |  // END OF LANG_hu section
 1644|       |
 1645|  5.70k|  switch (captype) {
  ------------------
  |  Branch (1645:11): [True: 5.70k, False: 0]
  ------------------
 1646|    623|    case HUHCAP:
  ------------------
  |  |   95|    623|#define HUHCAP 3
  ------------------
  |  Branch (1646:5): [True: 623, False: 5.08k]
  ------------------
 1647|    902|    case HUHINITCAP:
  ------------------
  |  |   96|    902|#define HUHINITCAP 4
  ------------------
  |  Branch (1647:5): [True: 279, False: 5.43k]
  ------------------
 1648|  2.97k|    case NOCAP: {
  ------------------
  |  |   92|  2.97k|#define NOCAP 0
  ------------------
  |  Branch (1648:5): [True: 2.07k, False: 3.63k]
  ------------------
 1649|  2.97k|      cat_result(result, pSMgr->suggest_morph(scw));
 1650|  2.97k|      if (abbv) {
  ------------------
  |  Branch (1650:11): [True: 319, False: 2.65k]
  ------------------
 1651|    319|        std::string u8buffer(scw);
 1652|    319|        u8buffer.push_back('.');
 1653|    319|        cat_result(result, pSMgr->suggest_morph(u8buffer));
 1654|    319|      }
 1655|  2.97k|      break;
 1656|    902|    }
 1657|  1.78k|    case INITCAP: {
  ------------------
  |  |   93|  1.78k|#define INITCAP 1
  ------------------
  |  Branch (1657:5): [True: 1.78k, False: 3.92k]
  ------------------
 1658|  1.78k|      mkallsmall2(scw, sunicw);
 1659|  1.78k|      std::string u8buffer(scw);
 1660|  1.78k|      mkinitcap2(scw, sunicw);
 1661|  1.78k|      cat_result(result, pSMgr->suggest_morph(u8buffer));
 1662|  1.78k|      cat_result(result, pSMgr->suggest_morph(scw));
 1663|  1.78k|      if (abbv) {
  ------------------
  |  Branch (1663:11): [True: 286, False: 1.49k]
  ------------------
 1664|    286|        u8buffer.push_back('.');
 1665|    286|        cat_result(result, pSMgr->suggest_morph(u8buffer));
 1666|       |
 1667|    286|        u8buffer = scw;
 1668|    286|        u8buffer.push_back('.');
 1669|       |
 1670|    286|        cat_result(result, pSMgr->suggest_morph(u8buffer));
 1671|    286|      }
 1672|  1.78k|      break;
 1673|    902|    }
 1674|    955|    case ALLCAP: {
  ------------------
  |  |   94|    955|#define ALLCAP 2
  ------------------
  |  Branch (1674:5): [True: 955, False: 4.75k]
  ------------------
 1675|    955|      cat_result(result, pSMgr->suggest_morph(scw));
 1676|    955|      if (abbv) {
  ------------------
  |  Branch (1676:11): [True: 127, False: 828]
  ------------------
 1677|    127|        std::string u8buffer(scw);
 1678|    127|        u8buffer.push_back('.');
 1679|    127|        cat_result(result, pSMgr->suggest_morph(u8buffer));
 1680|    127|      }
 1681|    955|      mkallsmall2(scw, sunicw);
 1682|    955|      std::string u8buffer(scw);
 1683|    955|      mkinitcap2(scw, sunicw);
 1684|       |
 1685|    955|      cat_result(result, pSMgr->suggest_morph(u8buffer));
 1686|    955|      cat_result(result, pSMgr->suggest_morph(scw));
 1687|    955|      if (abbv) {
  ------------------
  |  Branch (1687:11): [True: 127, False: 828]
  ------------------
 1688|    127|        u8buffer.push_back('.');
 1689|    127|        cat_result(result, pSMgr->suggest_morph(u8buffer));
 1690|       |
 1691|    127|        u8buffer = scw;
 1692|    127|        u8buffer.push_back('.');
 1693|       |
 1694|    127|        cat_result(result, pSMgr->suggest_morph(u8buffer));
 1695|    127|      }
 1696|    955|      break;
 1697|    902|    }
 1698|  5.70k|  }
 1699|       |
 1700|  5.70k|  if (!result.empty()) {
  ------------------
  |  Branch (1700:7): [True: 1.66k, False: 4.04k]
  ------------------
 1701|       |    // word reversing wrapper for complex prefixes
 1702|  1.66k|    if (complexprefixes) {
  ------------------
  |  Branch (1702:9): [True: 85, False: 1.57k]
  ------------------
 1703|     85|      if (utf8)
  ------------------
  |  Branch (1703:11): [True: 0, False: 85]
  ------------------
 1704|      0|        reverseword_utf(result);
 1705|     85|      else
 1706|     85|        reverseword(result);
 1707|     85|    }
 1708|  1.66k|    return line_tok(result, MSEP_REC);
  ------------------
  |  |  122|  1.66k|#define MSEP_REC '\n'
  ------------------
 1709|  1.66k|  }
 1710|       |
 1711|       |  // compound word with dash (HU) I18n
 1712|       |  // LANG_hu section: set dash information for suggestions
 1713|       |
 1714|  4.04k|  size_t dash_pos = langnum == LANG_hu ? scw.find('-') : std::string::npos;
  ------------------
  |  Branch (1714:21): [True: 231, False: 3.81k]
  ------------------
 1715|  4.04k|  if (dash_pos != std::string::npos) {
  ------------------
  |  Branch (1715:7): [True: 25, False: 4.02k]
  ------------------
 1716|     25|    int nresult = 0;
 1717|       |
 1718|     25|    std::string part1 = scw.substr(0, dash_pos), part2 = scw.substr(dash_pos + 1);
 1719|       |
 1720|       |    // examine 2 sides of the dash
 1721|     25|    if (part2.empty()) {  // base word ending with dash
  ------------------
  |  Branch (1721:9): [True: 8, False: 17]
  ------------------
 1722|      8|      if (spell(part1, candidate_stack)) {
  ------------------
  |  Branch (1722:11): [True: 1, False: 7]
  ------------------
 1723|      1|        std::string p = pSMgr->suggest_morph(part1);
 1724|      1|        if (!p.empty()) {
  ------------------
  |  Branch (1724:13): [True: 0, False: 1]
  ------------------
 1725|      0|          slst = line_tok(p, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1726|      0|          return slst;
 1727|      0|        }
 1728|      1|      }
 1729|     17|    } else if (part2.size() == 1 && part2[0] == 'e') {  // XXX (HU) -e hat.
  ------------------
  |  Branch (1729:16): [True: 0, False: 17]
  |  Branch (1729:37): [True: 0, False: 0]
  ------------------
 1730|      0|      if (spell(part1, candidate_stack) && (spell("-e", candidate_stack))) {
  ------------------
  |  Branch (1730:11): [True: 0, False: 0]
  |  Branch (1730:11): [True: 0, False: 0]
  |  Branch (1730:44): [True: 0, False: 0]
  ------------------
 1731|      0|        std::string st = pSMgr->suggest_morph(part1);
 1732|      0|        if (!st.empty()) {
  ------------------
  |  Branch (1732:13): [True: 0, False: 0]
  ------------------
 1733|      0|          result.append(st);
 1734|      0|        }
 1735|      0|        result.push_back('+');  // XXX spec. separator in MORPHCODE
 1736|      0|        st = pSMgr->suggest_morph("-e");
 1737|      0|        if (!st.empty()) {
  ------------------
  |  Branch (1737:13): [True: 0, False: 0]
  ------------------
 1738|      0|          result.append(st);
 1739|      0|        }
 1740|      0|        return line_tok(result, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1741|      0|      }
 1742|     17|    } else {
 1743|       |      // first word ending with dash: word- XXX ???
 1744|     17|      part1.push_back(' ');
 1745|     17|      nresult = spell(part1, candidate_stack);
 1746|     17|      part1.erase(part1.size() - 1);
 1747|     17|      if (nresult && spell(part2, candidate_stack) &&
  ------------------
  |  Branch (1747:11): [True: 1, False: 16]
  |  Branch (1747:22): [True: 0, False: 1]
  ------------------
 1748|      0|          ((part2.size() > 1) || ((part2[0] > '0') && (part2[0] < '9')))) {
  ------------------
  |  Branch (1748:12): [True: 0, False: 0]
  |  Branch (1748:35): [True: 0, False: 0]
  |  Branch (1748:55): [True: 0, False: 0]
  ------------------
 1749|      0|        std::string st = pSMgr->suggest_morph(part1);
 1750|      0|        if (!st.empty()) {
  ------------------
  |  Branch (1750:13): [True: 0, False: 0]
  ------------------
 1751|      0|          result.append(st);
 1752|      0|          result.push_back('+');  // XXX spec. separator in MORPHCODE
 1753|      0|        }
 1754|      0|        st = pSMgr->suggest_morph(part2);
 1755|      0|        if (!st.empty()) {
  ------------------
  |  Branch (1755:13): [True: 0, False: 0]
  ------------------
 1756|      0|          result.append(st);
 1757|      0|        }
 1758|      0|        return line_tok(result, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1759|      0|      }
 1760|     17|    }
 1761|       |    // affixed number in correct word
 1762|     25|    if (nresult && (dash_pos > 0) &&
  ------------------
  |  Branch (1762:9): [True: 1, False: 24]
  |  Branch (1762:20): [True: 0, False: 1]
  ------------------
 1763|      0|        (((scw[dash_pos - 1] <= '9') && (scw[dash_pos - 1] >= '0')) ||
  ------------------
  |  Branch (1763:11): [True: 0, False: 0]
  |  Branch (1763:41): [True: 0, False: 0]
  ------------------
 1764|      0|         (scw[dash_pos - 1] == '.'))) {
  ------------------
  |  Branch (1764:10): [True: 0, False: 0]
  ------------------
 1765|      0|      n = 1;
 1766|      0|      if (scw[dash_pos - n] == '.')
  ------------------
  |  Branch (1766:11): [True: 0, False: 0]
  ------------------
 1767|      0|        n++;
 1768|       |      // search first not a number character to left from dash
 1769|      0|      while ((dash_pos >= n) && ((scw[dash_pos - n] == '0') || (n < 3)) &&
  ------------------
  |  Branch (1769:14): [True: 0, False: 0]
  |  Branch (1769:34): [True: 0, False: 0]
  |  Branch (1769:64): [True: 0, False: 0]
  ------------------
 1770|      0|             (n < 6)) {
  ------------------
  |  Branch (1770:14): [True: 0, False: 0]
  ------------------
 1771|      0|        n++;
 1772|      0|      }
 1773|      0|      if (dash_pos < n)
  ------------------
  |  Branch (1773:11): [True: 0, False: 0]
  ------------------
 1774|      0|        n--;
 1775|       |      // numbers: valami1000000-hoz
 1776|       |      // examine 100000-hoz, 10000-hoz 1000-hoz, 10-hoz,
 1777|       |      // 56-hoz, 6-hoz
 1778|      0|      for (; n >= 1; n--) {
  ------------------
  |  Branch (1778:14): [True: 0, False: 0]
  ------------------
 1779|      0|        if (scw[dash_pos - n] < '0' || scw[dash_pos - n] > '9') {
  ------------------
  |  Branch (1779:13): [True: 0, False: 0]
  |  Branch (1779:40): [True: 0, False: 0]
  ------------------
 1780|      0|            continue;
 1781|      0|        }
 1782|      0|        std::string chunk = scw.substr(dash_pos - n);
 1783|      0|        if (checkword(chunk, nullptr, nullptr)) {
  ------------------
  |  Branch (1783:13): [True: 0, False: 0]
  ------------------
 1784|      0|          result.append(chunk);
 1785|      0|          std::string st = pSMgr->suggest_morph(chunk);
 1786|      0|          if (!st.empty()) {
  ------------------
  |  Branch (1786:15): [True: 0, False: 0]
  ------------------
 1787|      0|            result.append(st);
 1788|      0|          }
 1789|      0|          return line_tok(result, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1790|      0|        }
 1791|      0|      }
 1792|      0|    }
 1793|     25|  }
 1794|  4.04k|  return slst;
 1795|  4.04k|}
_ZN12HunspellImpl8generateERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKNS0_6vectorIS6_NS4_IS6_EEEE:
 1797|  5.66k|std::vector<std::string> HunspellImpl::generate(const std::string& word, const std::vector<std::string>& pl) {
 1798|  5.66k|  std::vector<std::string> slst;
 1799|  5.66k|  if (!pSMgr || pl.empty())
  ------------------
  |  Branch (1799:7): [True: 0, False: 5.66k]
  |  Branch (1799:17): [True: 697, False: 4.96k]
  ------------------
 1800|    697|    return slst;
 1801|  4.96k|  std::vector<std::string> pl2 = analyze(word);
 1802|  4.96k|  int captype = NOCAP, abbv = 0;
  ------------------
  |  |   92|  4.96k|#define NOCAP 0
  ------------------
 1803|  4.96k|  std::string cw;
 1804|  4.96k|  cleanword(cw, word, &captype, &abbv);
 1805|  4.96k|  std::string result;
 1806|       |
 1807|  4.96k|  auto suggest_start = std::chrono::steady_clock::now();
 1808|  7.75M|  for (const auto& i : pl) {
  ------------------
  |  Branch (1808:22): [True: 7.75M, False: 4.96k]
  ------------------
 1809|  7.75M|    cat_result(result, pSMgr->suggest_gen(pl2, i, suggest_start));
 1810|  7.75M|  }
 1811|       |
 1812|  4.96k|  if (!result.empty()) {
  ------------------
  |  Branch (1812:7): [True: 0, False: 4.96k]
  ------------------
 1813|       |    // allcap
 1814|      0|    if (captype == ALLCAP)
  ------------------
  |  |   94|      0|#define ALLCAP 2
  ------------------
  |  Branch (1814:9): [True: 0, False: 0]
  ------------------
 1815|      0|      mkallcap(result);
 1816|       |
 1817|       |    // line split
 1818|      0|    slst = line_tok(result, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1819|       |
 1820|       |    // capitalize
 1821|      0|    if (captype == INITCAP || captype == HUHINITCAP) {
  ------------------
  |  |   93|      0|#define INITCAP 1
  ------------------
                  if (captype == INITCAP || captype == HUHINITCAP) {
  ------------------
  |  |   96|      0|#define HUHINITCAP 4
  ------------------
  |  Branch (1821:9): [True: 0, False: 0]
  |  Branch (1821:31): [True: 0, False: 0]
  ------------------
 1822|      0|      for (auto& str : slst) {
  ------------------
  |  Branch (1822:22): [True: 0, False: 0]
  ------------------
 1823|      0|        mkinitcap(str);
 1824|      0|      }
 1825|      0|    }
 1826|       |
 1827|       |    // temporary filtering of prefix related errors (eg.
 1828|       |    // generate("undrinkable", "eats") --> "undrinkables" and "*undrinks")
 1829|      0|    auto it = slst.begin();
 1830|      0|    while (it != slst.end()) {
  ------------------
  |  Branch (1830:12): [True: 0, False: 0]
  ------------------
 1831|      0|      if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|      0|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1831:11): [True: 0, False: 0]
  ------------------
 1832|      0|        break;
 1833|      0|      std::vector<std::string> candidate_stack;
 1834|      0|      if (!spell(*it, candidate_stack, nullptr, nullptr, suggest_start)) {
  ------------------
  |  Branch (1834:11): [True: 0, False: 0]
  ------------------
 1835|      0|        it = slst.erase(it);
 1836|      0|      } else  {
 1837|      0|        ++it;
 1838|      0|      }
 1839|      0|    }
 1840|      0|  }
 1841|  4.96k|  return slst;
 1842|  5.66k|}
_ZN12HunspellImpl8generateERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_:
 1844|    893|std::vector<std::string> HunspellImpl::generate(const std::string& word, const std::string& pattern) {
 1845|    893|  std::vector<std::string> pl = analyze(pattern);
 1846|    893|  std::vector<std::string> slst = generate(word, pl);
 1847|    893|  uniqlist(slst);
 1848|    893|  return slst;
 1849|    893|}
_ZN12HunspellImpl11get_xml_parERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
 1852|  7.83M|std::string HunspellImpl::get_xml_par(const std::string& in_par, std::string::size_type pos) {
 1853|  7.83M|  std::string dest;
 1854|  7.83M|  if (pos == std::string::npos)
  ------------------
  |  Branch (1854:7): [True: 6.93k, False: 7.83M]
  ------------------
 1855|  6.93k|    return dest;
 1856|  7.83M|  const char* par = in_par.c_str() + pos;
 1857|  7.83M|  char end = *par;
 1858|  7.83M|  if (end == '>')
  ------------------
  |  Branch (1858:7): [True: 7.82M, False: 4.69k]
  ------------------
 1859|  7.82M|    end = '<';
 1860|  4.69k|  else if (end != '\'' && end != '"')
  ------------------
  |  Branch (1860:12): [True: 3.62k, False: 1.06k]
  |  Branch (1860:27): [True: 1.44k, False: 2.18k]
  ------------------
 1861|  1.44k|    return dest;  // bad XML
 1862|   244M|  for (par++; *par != '\0' && *par != end; ++par) {
  ------------------
  |  Branch (1862:15): [True: 244M, False: 31.4k]
  |  Branch (1862:31): [True: 237M, False: 7.80M]
  ------------------
 1863|   237M|    dest.push_back(*par);
 1864|   237M|  }
 1865|  7.83M|  mystrrep(dest, "&lt;", "<");
 1866|  7.83M|  mystrrep(dest, "&amp;", "&");
 1867|  7.83M|  return dest;
 1868|  7.83M|}
_ZN12HunspellImpl11get_xml_posERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEmPKc:
 1884|  65.8k|std::string::size_type HunspellImpl::get_xml_pos(const std::string& s, std::string::size_type pos, const char* attr) {
 1885|  65.8k|  if (pos == std::string::npos)
  ------------------
  |  Branch (1885:7): [True: 0, False: 65.8k]
  ------------------
 1886|      0|    return std::string::npos;
 1887|       |
 1888|  65.8k|  std::string::size_type endpos = s.find('>', pos);
 1889|  65.8k|  if (attr == nullptr)
  ------------------
  |  Branch (1889:7): [True: 0, False: 65.8k]
  ------------------
 1890|      0|    return endpos;
 1891|   300k|  while (true) {
  ------------------
  |  Branch (1891:10): [True: 300k, Folded]
  ------------------
 1892|   300k|    pos = s.find(attr, pos);
 1893|   300k|    if (pos == std::string::npos || pos >= endpos)
  ------------------
  |  Branch (1893:9): [True: 3.19k, False: 297k]
  |  Branch (1893:37): [True: 2.20k, False: 295k]
  ------------------
 1894|  5.39k|      return std::string::npos;
 1895|   295k|    if (pos == 0 || s[pos - 1] == ' ' || s[pos - 1] == '\n')
  ------------------
  |  Branch (1895:9): [True: 0, False: 295k]
  |  Branch (1895:21): [True: 2.29k, False: 293k]
  |  Branch (1895:42): [True: 58.1k, False: 234k]
  ------------------
 1896|  60.4k|      break;
 1897|   234k|    pos += strlen(attr);
 1898|   234k|  }
 1899|  60.4k|  return pos + strlen(attr);
 1900|  65.8k|}
_ZN12HunspellImpl13check_xml_parERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEmPKcSA_:
 1904|  65.8k|                                const char* value) {
 1905|  65.8k|  const std::string cw = get_xml_par(q, get_xml_pos(q, pos, attr));
 1906|  65.8k|  return cw == value ? 1 : 0;
  ------------------
  |  Branch (1906:10): [True: 15.8k, False: 50.0k]
  ------------------
 1907|  65.8k|}
_ZN12HunspellImpl12get_xml_listERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEmPKc:
 1909|  5.45k|std::vector<std::string> HunspellImpl::get_xml_list(const std::string& list, std::string::size_type pos, const char* tag) {
 1910|  5.45k|  std::vector<std::string> slst;
 1911|  5.45k|  if (pos == std::string::npos)
  ------------------
  |  Branch (1911:7): [True: 19, False: 5.43k]
  ------------------
 1912|     19|    return slst;
 1913|  7.75M|  while (true) {
  ------------------
  |  Branch (1913:10): [True: 7.75M, Folded]
  ------------------
 1914|  7.75M|    pos = list.find(tag, pos);
 1915|  7.75M|    if (pos == std::string::npos)
  ------------------
  |  Branch (1915:9): [True: 4.06k, False: 7.75M]
  ------------------
 1916|  4.06k|        break;
 1917|  7.75M|    std::string cw = get_xml_par(list, pos + strlen(tag) - 1);
 1918|  7.75M|    if (cw.empty()) {
  ------------------
  |  Branch (1918:9): [True: 1.36k, False: 7.75M]
  ------------------
 1919|  1.36k|      break;
 1920|  1.36k|    }
 1921|  7.75M|    slst.push_back(std::move(cw));
 1922|  7.75M|    ++pos;
 1923|  7.75M|  }
 1924|  5.43k|  return slst;
 1925|  5.45k|}
_ZN12HunspellImpl7spellmlERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1927|  20.4k|std::vector<std::string> HunspellImpl::spellml(const std::string& in_word) {
 1928|  20.4k|  std::vector<std::string> slst;
 1929|       |
 1930|  20.4k|  std::string::size_type qpos = in_word.find("<query");
 1931|  20.4k|  if (qpos == std::string::npos)
  ------------------
  |  Branch (1931:7): [True: 364, False: 20.1k]
  ------------------
 1932|    364|    return slst;  // bad XML input
 1933|       |
 1934|  20.1k|  std::string::size_type q2pos = in_word.find('>', qpos);
 1935|  20.1k|  if (q2pos == std::string::npos)
  ------------------
  |  Branch (1935:7): [True: 171, False: 19.9k]
  ------------------
 1936|    171|    return slst;  // bad XML input
 1937|       |
 1938|  19.9k|  q2pos = in_word.find("<word", q2pos);
 1939|  19.9k|  if (q2pos == std::string::npos)
  ------------------
  |  Branch (1939:7): [True: 456, False: 19.4k]
  ------------------
 1940|    456|    return slst;  // bad XML input
 1941|       |
 1942|  19.4k|  if (check_xml_par(in_word, qpos, "type=", "analyze")) {
  ------------------
  |  Branch (1942:7): [True: 779, False: 18.7k]
  ------------------
 1943|    779|    std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
 1944|    779|    if (!cw.empty())
  ------------------
  |  Branch (1944:9): [True: 323, False: 456]
  ------------------
 1945|    323|      slst = analyze(cw);
 1946|    779|    if (slst.empty())
  ------------------
  |  Branch (1946:9): [True: 739, False: 40]
  ------------------
 1947|    739|      return slst;
 1948|       |    // convert the result to <code><a>ana1</a><a>ana2</a></code> format
 1949|     40|    std::string r;
 1950|     40|    r.append("<code>");
 1951|     40|    for (auto entry : slst) {
  ------------------
  |  Branch (1951:21): [True: 40, False: 40]
  ------------------
 1952|     40|      r.append("<a>");
 1953|       |
 1954|     40|      mystrrep(entry, "\t", " ");
 1955|     40|      mystrrep(entry, "&", "&amp;");
 1956|     40|      mystrrep(entry, "<", "&lt;");
 1957|     40|      r.append(entry);
 1958|       |
 1959|     40|      r.append("</a>");
 1960|     40|    }
 1961|     40|    r.append("</code>");
 1962|     40|    slst.clear();
 1963|     40|    slst.push_back(std::move(r));
 1964|     40|    return slst;
 1965|  18.7k|  } else if (check_xml_par(in_word, qpos, "type=", "stem")) {
  ------------------
  |  Branch (1965:14): [True: 1.40k, False: 17.3k]
  ------------------
 1966|  1.40k|    std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
 1967|  1.40k|    if (!cw.empty())
  ------------------
  |  Branch (1967:9): [True: 1.10k, False: 304]
  ------------------
 1968|  1.10k|      return stem(cw);
 1969|  17.3k|  } else if (check_xml_par(in_word, qpos, "type=", "generate")) {
  ------------------
  |  Branch (1969:14): [True: 6.93k, False: 10.3k]
  ------------------
 1970|  6.93k|    std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
 1971|  6.93k|    if (cw.empty())
  ------------------
  |  Branch (1971:9): [True: 323, False: 6.61k]
  ------------------
 1972|    323|      return slst;
 1973|  6.61k|    std::string::size_type q3pos = in_word.find("<word", q2pos + 1);
 1974|  6.61k|    if (q3pos != std::string::npos) {
  ------------------
  |  Branch (1974:9): [True: 1.04k, False: 5.56k]
  ------------------
 1975|  1.04k|      std::string cw2 = get_xml_par(in_word, in_word.find('>', q3pos));
 1976|  1.04k|      if (!cw2.empty()) {
  ------------------
  |  Branch (1976:11): [True: 893, False: 152]
  ------------------
 1977|    893|        return generate(cw, cw2);
 1978|    893|      }
 1979|  5.56k|    } else {
 1980|  5.56k|      q2pos = in_word.find("<code", q2pos + 1);
 1981|  5.56k|      if (q2pos != std::string::npos) {
  ------------------
  |  Branch (1981:11): [True: 5.45k, False: 114]
  ------------------
 1982|  5.45k|        std::vector<std::string> slst2 = get_xml_list(in_word, in_word.find('>', q2pos), "<a>");
 1983|  5.45k|        if (!slst2.empty()) {
  ------------------
  |  Branch (1983:13): [True: 4.76k, False: 684]
  ------------------
 1984|  4.76k|          slst = generate(cw, slst2);
 1985|  4.76k|          uniqlist(slst);
 1986|  4.76k|          return slst;
 1987|  4.76k|        }
 1988|  5.45k|      }
 1989|  5.56k|    }
 1990|  10.3k|  } else if (check_xml_par(in_word, qpos, "type=", "add")) {
  ------------------
  |  Branch (1990:14): [True: 6.68k, False: 3.68k]
  ------------------
 1991|  6.68k|    std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
 1992|  6.68k|    if (cw.empty())
  ------------------
  |  Branch (1992:9): [True: 114, False: 6.57k]
  ------------------
 1993|    114|      return slst;
 1994|  6.57k|    std::string::size_type q3pos = in_word.find("<word", q2pos + 1);
 1995|  6.57k|    if (q3pos != std::string::npos) {
  ------------------
  |  Branch (1995:9): [True: 1.86k, False: 4.71k]
  ------------------
 1996|  1.86k|      std::string cw2 = get_xml_par(in_word, in_word.find('>', q3pos));
 1997|  1.86k|      if (!cw2.empty()) {
  ------------------
  |  Branch (1997:11): [True: 1.46k, False: 399]
  ------------------
 1998|  1.46k|        add_with_affix(cw, cw2);
 1999|  1.46k|      } else {
 2000|    399|        add(cw);
 2001|    399|      }
 2002|  4.71k|    } else {
 2003|  4.71k|        add(cw);
 2004|  4.71k|    }
 2005|  6.57k|  }
 2006|  11.5k|  return slst;
 2007|  19.4k|}
_ZN8HunspellC2EPKcS1_S1_:
 2157|     38|  : m_Impl(new HunspellImpl(affpath, dpath, key)) {
 2158|     38|}
_ZN8Hunspell5spellERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPiPS6_:
 2169|  58.5k|bool Hunspell::spell(const std::string& word, int* info, std::string* root) {
 2170|  58.5k|  std::vector<std::string> candidate_stack;
 2171|  58.5k|  return m_Impl->spell(word, candidate_stack, info, root,
 2172|  58.5k|                       std::chrono::steady_clock::now());
 2173|  58.5k|}
_ZN8Hunspell7suggestERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 2175|  58.1k|std::vector<std::string> Hunspell::suggest(const std::string& word) {
 2176|  58.1k|  return m_Impl->suggest(word);
 2177|  58.1k|}

_Z16init_phonet_hashR10phonetable:
   38|      2|void init_phonet_hash(phonetable& parms) {
   39|      2|  memset(parms.hash, 0xff, HASHSIZE * sizeof(int));
  ------------------
  |  |   33|      2|#define HASHSIZE 256
  ------------------
   40|       |
   41|    212|  for (int i = 0; parms.rules[i][0] != '\0'; i += 2) {
  ------------------
  |  Branch (41:19): [True: 210, False: 2]
  ------------------
   42|       |    /**  set hash value  **/
   43|    210|    int k = (unsigned char)parms.rules[i][0];
   44|       |
   45|    210|    if (parms.hash[k] < 0) {
  ------------------
  |  Branch (45:9): [True: 54, False: 156]
  ------------------
   46|     54|      parms.hash[k] = i;
   47|     54|    }
   48|    210|  }
   49|      2|}
_Z6phonetRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEER10phonetable:
   69|  10.4k|std::string phonet(const std::string& inword, phonetable& parms) {
   70|       |
   71|  10.4k|  int i, k = 0, p, z, k0, n0, p0 = -333;
   72|  10.4k|  char c;
   73|  10.4k|  using uchar = unsigned char;
   74|       |
   75|  10.4k|  size_t len = inword.size();
   76|  10.4k|  if (len > MAXPHONETUTF8LEN)
  ------------------
  |  |   35|  10.4k|#define MAXPHONETUTF8LEN (MAXPHONETLEN * 4)
  |  |  ------------------
  |  |  |  |   34|  10.4k|#define MAXPHONETLEN 256
  |  |  ------------------
  ------------------
  |  Branch (76:7): [True: 0, False: 10.4k]
  ------------------
   77|      0|    return {};
   78|  10.4k|  char word[MAXPHONETUTF8LEN + 1];
   79|  10.4k|  strncpy(word, inword.c_str(), MAXPHONETUTF8LEN);
  ------------------
  |  |   35|  10.4k|#define MAXPHONETUTF8LEN (MAXPHONETLEN * 4)
  |  |  ------------------
  |  |  |  |   34|  10.4k|#define MAXPHONETLEN 256
  |  |  ------------------
  ------------------
   80|  10.4k|  word[MAXPHONETUTF8LEN] = '\0';
  ------------------
  |  |   35|  10.4k|#define MAXPHONETUTF8LEN (MAXPHONETLEN * 4)
  |  |  ------------------
  |  |  |  |   34|  10.4k|#define MAXPHONETLEN 256
  |  |  ------------------
  ------------------
   81|       |
   82|  10.4k|  std::string target;
   83|       |  /**  check word  **/
   84|  10.4k|  i = z = 0;
   85|  91.0k|  while ((c = word[i]) != '\0') {
  ------------------
  |  Branch (85:10): [True: 80.5k, False: 10.4k]
  ------------------
   86|  80.5k|    int n = parms.hash[(uchar)c];
   87|  80.5k|    int z0 = 0;
   88|       |
   89|  80.5k|    if (n >= 0 && !parms.rules[n].empty()) {
  ------------------
  |  Branch (89:9): [True: 23.5k, False: 57.0k]
  |  Branch (89:19): [True: 23.5k, False: 0]
  ------------------
   90|       |      /**  check all rules for the same letter  **/
   91|  54.6k|      while (parms.rules[n][0] == c) {
  ------------------
  |  Branch (91:14): [True: 53.2k, False: 1.42k]
  ------------------
   92|       |        /**  check whole string  **/
   93|  53.2k|        k = 1; /** number of found letters  **/
   94|  53.2k|        p = 5; /** default priority  **/
   95|  53.2k|        const char*s = parms.rules[n].c_str();
   96|  53.2k|        s++; /**  important for (see below)  "*(s-1)"  **/
   97|       |
   98|  54.7k|        while (*s != '\0' && word[i + k] == *s && !isdigit((unsigned char)*s) && strchr("(-<^$", *s) == nullptr) {
  ------------------
  |  Branch (98:16): [True: 33.8k, False: 20.8k]
  |  Branch (98:30): [True: 1.46k, False: 32.4k]
  |  Branch (98:51): [True: 1.46k, False: 0]
  |  Branch (98:82): [True: 1.43k, False: 32]
  ------------------
   99|  1.43k|          k++;
  100|  1.43k|          s++;
  101|  1.43k|        }
  102|  53.2k|        if (*s == '(') {
  ------------------
  |  Branch (102:13): [True: 2.81k, False: 50.4k]
  ------------------
  103|       |          /**  check letters in "(..)"  **/
  104|  2.81k|          if (myisalpha(word[i + k])  // ...could be implied?
  ------------------
  |  Branch (104:15): [True: 1.77k, False: 1.03k]
  ------------------
  105|  1.77k|              && strchr(s + 1, word[i + k]) != nullptr) {
  ------------------
  |  Branch (105:18): [True: 179, False: 1.59k]
  ------------------
  106|    179|            k++;
  107|  1.01k|            while (*s && *s != ')')
  ------------------
  |  Branch (107:20): [True: 1.01k, False: 0]
  |  Branch (107:26): [True: 831, False: 179]
  ------------------
  108|    831|              s++;
  109|    179|            if (*s == ')')
  ------------------
  |  Branch (109:17): [True: 179, False: 0]
  ------------------
  110|    179|              s++;
  111|    179|          }
  112|  2.81k|        }
  113|  53.2k|        p0 = (int)*s;
  114|  53.2k|        k0 = k;
  115|  54.1k|        while (*s == '-' && k > 1) {
  ------------------
  |  Branch (115:16): [True: 909, False: 53.2k]
  |  Branch (115:29): [True: 909, False: 0]
  ------------------
  116|    909|          k--;
  117|    909|          s++;
  118|    909|        }
  119|  53.2k|        if (*s == '<')
  ------------------
  |  Branch (119:13): [True: 95, False: 53.1k]
  ------------------
  120|     95|          s++;
  121|  53.2k|        if (isdigit((unsigned char)*s)) {
  ------------------
  |  Branch (121:13): [True: 0, False: 53.2k]
  ------------------
  122|       |          /**  determine priority  **/
  123|      0|          p = *s - '0';
  124|      0|          s++;
  125|      0|        }
  126|  53.2k|        if (*s == '^' && *(s + 1) == '^')
  ------------------
  |  Branch (126:13): [True: 1.94k, False: 51.3k]
  |  Branch (126:26): [True: 0, False: 1.94k]
  ------------------
  127|      0|          s++;
  128|       |
  129|  53.2k|        if (*s == '\0' || (*s == '^' && (i == 0 || !myisalpha(word[i - 1])) &&
  ------------------
  |  Branch (129:13): [True: 21.8k, False: 31.4k]
  |  Branch (129:28): [True: 1.94k, False: 29.5k]
  |  Branch (129:42): [True: 114, False: 1.82k]
  |  Branch (129:52): [True: 531, False: 1.29k]
  ------------------
  130|    645|                           (*(s + 1) != '$' || (!myisalpha(word[i + k0])))) ||
  ------------------
  |  Branch (130:29): [True: 645, False: 0]
  |  Branch (130:48): [True: 0, False: 0]
  ------------------
  131|  30.8k|            (*s == '$' && i > 0 && myisalpha(word[i - 1]) &&
  ------------------
  |  Branch (131:14): [True: 0, False: 30.8k]
  |  Branch (131:27): [True: 0, False: 0]
  |  Branch (131:36): [True: 0, False: 0]
  ------------------
  132|  22.4k|             (!myisalpha(word[i + k0])))) {
  ------------------
  |  Branch (132:14): [True: 0, False: 0]
  ------------------
  133|       |          /**  search for followup rules, if:     **/
  134|       |          /**  parms.followup and k > 1  and  NO '-' in searchstring **/
  135|  22.4k|          char c0 = word[i + k - 1];
  136|  22.4k|          n0 = parms.hash[(uchar)c0];
  137|       |
  138|       |          //            if (parms.followup  &&  k > 1  &&  n0 >= 0
  139|  22.4k|          if (k > 1 && n0 >= 0 && p0 != (int)'-' && word[i + k] != '\0' && !parms.rules[n0].empty()) {
  ------------------
  |  Branch (139:15): [True: 532, False: 21.9k]
  |  Branch (139:24): [True: 532, False: 0]
  |  Branch (139:35): [True: 506, False: 26]
  |  Branch (139:53): [True: 468, False: 38]
  |  Branch (139:76): [True: 468, False: 0]
  ------------------
  140|       |            /**  test follow-up rule for "word[i+k]"  **/
  141|  1.25k|            while (parms.rules[n0][0] == c0) {
  ------------------
  |  Branch (141:20): [True: 1.17k, False: 85]
  ------------------
  142|       |              /**  check whole string  **/
  143|  1.17k|              k0 = k;
  144|  1.17k|              p0 = 5;
  145|  1.17k|              s = parms.rules[n0].c_str();
  146|  1.17k|              s++;
  147|  1.55k|              while (*s != '\0' && word[i + k0] == *s && !isdigit((unsigned char)*s) && strchr("(-<^$", *s) == nullptr) {
  ------------------
  |  Branch (147:22): [True: 1.11k, False: 440]
  |  Branch (147:36): [True: 383, False: 733]
  |  Branch (147:58): [True: 383, False: 0]
  |  Branch (147:89): [True: 383, False: 0]
  ------------------
  148|    383|                k0++;
  149|    383|                s++;
  150|    383|              }
  151|  1.17k|              if (*s == '(') {
  ------------------
  |  Branch (151:19): [True: 28, False: 1.14k]
  ------------------
  152|       |                /**  check letters  **/
  153|     28|                if (myisalpha(word[i + k0]) && strchr(s + 1, word[i + k0]) != nullptr) {
  ------------------
  |  Branch (153:21): [True: 28, False: 0]
  |  Branch (153:48): [True: 0, False: 28]
  ------------------
  154|      0|                  k0++;
  155|      0|                  while (*s != ')' && *s != '\0')
  ------------------
  |  Branch (155:26): [True: 0, False: 0]
  |  Branch (155:39): [True: 0, False: 0]
  ------------------
  156|      0|                    s++;
  157|      0|                  if (*s == ')')
  ------------------
  |  Branch (157:23): [True: 0, False: 0]
  ------------------
  158|      0|                    s++;
  159|      0|                }
  160|     28|              }
  161|  1.17k|              while (*s == '-') {
  ------------------
  |  Branch (161:22): [True: 0, False: 1.17k]
  ------------------
  162|       |                /**  "k0" gets NOT reduced   **/
  163|       |                /**  because "if (k0 == k)"  **/
  164|      0|                s++;
  165|      0|              }
  166|  1.17k|              if (*s == '<')
  ------------------
  |  Branch (166:19): [True: 28, False: 1.14k]
  ------------------
  167|     28|                s++;
  168|  1.17k|              if (isdigit((unsigned char)*s)) {
  ------------------
  |  Branch (168:19): [True: 0, False: 1.17k]
  ------------------
  169|      0|                p0 = *s - '0';
  170|      0|                s++;
  171|      0|              }
  172|       |
  173|  1.17k|              if (*s == '\0'
  ------------------
  |  Branch (173:19): [True: 468, False: 705]
  ------------------
  174|       |                  /**  *s == '^' cuts  **/
  175|    705|                  || (*s == '$' && !myisalpha(word[i + k0]))) {
  ------------------
  |  Branch (175:23): [True: 0, False: 705]
  |  Branch (175:36): [True: 0, False: 0]
  ------------------
  176|    468|                if (k0 == k) {
  ------------------
  |  Branch (176:21): [True: 85, False: 383]
  ------------------
  177|       |                  /**  this is just a piece of the string  **/
  178|     85|                  n0 += 2;
  179|     85|                  continue;
  180|     85|                }
  181|       |
  182|    383|                if (p0 < p) {
  ------------------
  |  Branch (182:21): [True: 0, False: 383]
  ------------------
  183|       |                  /**  priority too low  **/
  184|      0|                  n0 += 2;
  185|      0|                  continue;
  186|      0|                }
  187|       |                /**  rule fits; stop search  **/
  188|    383|                break;
  189|    383|              }
  190|    705|              n0 += 2;
  191|    705|            } /**  End of "while (parms.rules[n0][0] == c0)"  **/
  192|       |
  193|    468|            if (p0 >= p && parms.rules[n0][0] == c0) {
  ------------------
  |  Branch (193:17): [True: 468, False: 0]
  |  Branch (193:28): [True: 383, False: 85]
  ------------------
  194|    383|              n += 2;
  195|    383|              continue;
  196|    383|            }
  197|    468|          } /** end of follow-up stuff **/
  198|       |
  199|       |          /**  replace string  **/
  200|  22.0k|          s = parms.rules[n + 1].c_str();
  201|  22.0k|          p0 = (!parms.rules[n].empty() && strchr(parms.rules[n].c_str() + 1, '<') != nullptr) ? 1 : 0;
  ------------------
  |  Branch (201:17): [True: 22.0k, False: 0]
  |  Branch (201:44): [True: 67, False: 22.0k]
  ------------------
  202|  22.0k|          if (p0 == 1 && z == 0) {
  ------------------
  |  Branch (202:15): [True: 67, False: 22.0k]
  |  Branch (202:26): [True: 67, False: 0]
  ------------------
  203|       |            /**  rule with '<' is used  **/
  204|     67|            if (!target.empty() && *s != '\0' &&
  ------------------
  |  Branch (204:17): [True: 52, False: 15]
  |  Branch (204:36): [True: 52, False: 0]
  ------------------
  205|     52|                (target[target.size()-1] == c || target[target.size()-1] == *s)) {
  ------------------
  |  Branch (205:18): [True: 0, False: 52]
  |  Branch (205:50): [True: 0, False: 52]
  ------------------
  206|      0|              target.erase(target.size() - 1);
  207|      0|            }
  208|     67|            z0 = 1;
  209|     67|            z = 1;
  210|     67|            k0 = 0;
  211|    134|            while (*s != '\0' && word[i + k0] != '\0') {
  ------------------
  |  Branch (211:20): [True: 67, False: 67]
  |  Branch (211:34): [True: 67, False: 0]
  ------------------
  212|     67|              word[i + k0] = *s;
  213|     67|              k0++;
  214|     67|              s++;
  215|     67|            }
  216|     67|            if (k > k0)
  ------------------
  |  Branch (216:17): [True: 4, False: 63]
  ------------------
  217|      4|              strmove(&word[0] + i + k0, &word[0] + i + k);
  218|       |
  219|       |            /**  new "actual letter"  **/
  220|     67|            c = word[i];
  221|  22.0k|          } else { /** no '<' rule used **/
  222|  22.0k|            i += k - 1;
  223|  22.0k|            z = 0;
  224|  22.3k|            while (*s != '\0' && *(s + 1) != '\0' && target.size() < len) {
  ------------------
  |  Branch (224:20): [True: 21.5k, False: 845]
  |  Branch (224:34): [True: 393, False: 21.1k]
  |  Branch (224:54): [True: 331, False: 62]
  ------------------
  225|    331|              if (target.empty() || target[target.size()-1] != *s) {
  ------------------
  |  Branch (225:19): [True: 5, False: 326]
  |  Branch (225:37): [True: 113, False: 213]
  ------------------
  226|    118|                target.push_back(*s);
  227|    118|              }
  228|    331|              s++;
  229|    331|            }
  230|       |            /**  new "actual letter"  **/
  231|  22.0k|            c = *s;
  232|  22.0k|            if (!parms.rules[n].empty() && strstr(parms.rules[n].c_str() + 1, "^^") != nullptr) {
  ------------------
  |  Branch (232:17): [True: 22.0k, False: 0]
  |  Branch (232:44): [True: 0, False: 22.0k]
  ------------------
  233|      0|              if (c != '\0') {
  ------------------
  |  Branch (233:19): [True: 0, False: 0]
  ------------------
  234|      0|                target.push_back(c);
  235|      0|              }
  236|      0|              strmove(&word[0], &word[0] + i + 1);
  237|      0|              i = 0;
  238|      0|              z0 = 1;
  239|      0|            }
  240|  22.0k|          }
  241|  22.0k|          break;
  242|  22.4k|        } /** end of follow-up stuff **/
  243|  30.8k|        n += 2;
  244|  30.8k|      } /**  end of while (parms.rules[n][0] == c)  **/
  245|  23.5k|    }   /**  end of if (n >= 0)  **/
  246|  80.5k|    if (z0 == 0) {
  ------------------
  |  Branch (246:9): [True: 80.4k, False: 67]
  ------------------
  247|  80.4k|      if (k && !p0 && target.size() < len && c != '\0') {
  ------------------
  |  Branch (247:11): [True: 23.4k, False: 57.0k]
  |  Branch (247:16): [True: 22.0k, False: 1.42k]
  |  Branch (247:23): [True: 21.9k, False: 69]
  |  Branch (247:46): [True: 21.1k, False: 845]
  ------------------
  248|       |        /**  condense only double letters  **/
  249|  21.1k|        target.push_back(c);
  250|       |        /// printf("\n setting \n");
  251|  21.1k|      }
  252|       |
  253|  80.4k|      i++;
  254|  80.4k|      z = 0;
  255|  80.4k|      k = 0;
  256|  80.4k|    }
  257|  80.5k|  } /**  end of   while ((c = word[i]) != '\0')  **/
  258|       |
  259|  10.4k|  return target;
  260|  10.4k|} /**  end of function "phonet"  **/
phonet.cxx:_ZL9myisalphac:
   59|  4.67k|static int myisalpha(char ch) {
   60|  4.67k|  if ((unsigned char)ch < 128)
  ------------------
  |  Branch (60:7): [True: 4.27k, False: 398]
  ------------------
   61|  4.27k|    return isalpha(ch);
   62|    398|  return 1;
   63|  4.67k|}
phonet.cxx:_ZL7strmovePcS_:
   53|      4|static inline void strmove(char* dest, char* src) {
   54|      4|  while (*src)
  ------------------
  |  Branch (54:10): [True: 0, False: 4]
  ------------------
   55|      0|    *dest++ = *src++;
   56|      4|  *dest = '\0';
   57|      4|}

_ZN7RepListC2Ei:
   79|      4|RepList::RepList(int n) {
   80|      4|  dat.reserve(std::min(n, 16384));
   81|      4|}
_ZN7RepList4findEPKc:
   89|  2.29M|int RepList::find(const char* word) {
   90|  2.29M|  int p1 = 0;
   91|  2.29M|  int p2 = dat.size() - 1;
   92|  2.29M|  int ret = -1;
   93|  7.21M|  while (p1 <= p2) {
  ------------------
  |  Branch (93:10): [True: 4.91M, False: 2.29M]
  ------------------
   94|  4.91M|    int m = ((unsigned)p1 + (unsigned)p2) >> 1;
   95|  4.91M|    int c = strncmp(word, dat[m]->pattern.c_str(), dat[m]->pattern.size());
   96|  4.91M|    if (c < 0)
  ------------------
  |  Branch (96:9): [True: 3.99M, False: 922k]
  ------------------
   97|  3.99M|      p2 = m - 1;
   98|   922k|    else if (c > 0)
  ------------------
  |  Branch (98:14): [True: 921k, False: 398]
  ------------------
   99|   921k|      p1 = m + 1;
  100|    398|    else {      // scan in the right half for a longer match
  101|    398|      ret = m;
  102|    398|      p1 = m + 1;
  103|    398|    }
  104|  4.91M|  }
  105|  2.29M|  return ret;
  106|  2.29M|}
_ZN7RepList7replaceEmib:
  108|    398|std::string RepList::replace(const size_t wordlen, int ind, bool atstart) {
  109|    398|  int type = atstart ? 1 : 0;
  ------------------
  |  Branch (109:14): [True: 8, False: 390]
  ------------------
  110|    398|  if (wordlen == dat[ind]->pattern.size())
  ------------------
  |  Branch (110:7): [True: 101, False: 297]
  ------------------
  111|    101|    type = atstart ? 3 : 2;
  ------------------
  |  Branch (111:12): [True: 0, False: 101]
  ------------------
  112|    507|  while (type && dat[ind]->outstrings[type].empty())
  ------------------
  |  Branch (112:10): [True: 109, False: 398]
  |  Branch (112:18): [True: 109, False: 0]
  ------------------
  113|    109|    type = (type == 2 && !atstart) ? 0 : type - 1;
  ------------------
  |  Branch (113:13): [True: 101, False: 8]
  |  Branch (113:26): [True: 101, False: 0]
  ------------------
  114|    398|  return dat[ind]->outstrings[type];
  115|    398|}
_ZN7RepList3addERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_:
  117|     22|int RepList::add(const std::string& in_pat1, const std::string& pat2) {
  118|     22|  if (in_pat1.empty() || pat2.empty()) {
  ------------------
  |  Branch (118:7): [True: 0, False: 22]
  |  Branch (118:26): [True: 0, False: 22]
  ------------------
  119|      0|    return 1;
  120|      0|  }
  121|       |  // analyse word context
  122|     22|  int type = 0;
  123|     22|  std::string pat1(in_pat1);
  124|     22|  if (pat1[0] == '_') {
  ------------------
  |  Branch (124:7): [True: 0, False: 22]
  ------------------
  125|      0|    pat1.erase(0, 1);
  126|      0|    type = 1;
  127|      0|  }
  128|     22|  if (!pat1.empty() && pat1[pat1.size() - 1] == '_') {
  ------------------
  |  Branch (128:7): [True: 22, False: 0]
  |  Branch (128:24): [True: 0, False: 22]
  ------------------
  129|      0|    type = type + 2;
  130|      0|    pat1.erase(pat1.size() - 1);
  131|      0|  }
  132|     22|  mystrrep(pat1, "_", " ");
  133|       |
  134|       |  // find existing entry
  135|     22|  int m = find(pat1.c_str());
  136|     22|  if (m >= 0 && dat[m]->pattern == pat1) {
  ------------------
  |  Branch (136:7): [True: 0, False: 22]
  |  Branch (136:17): [True: 0, False: 0]
  ------------------
  137|       |    // since already used
  138|      0|    dat[m]->outstrings[type] = pat2;
  139|      0|    mystrrep(dat[m]->outstrings[type], "_", " ");
  140|      0|    return 0;
  141|      0|  }
  142|       |
  143|       |  // make a new entry if none exists
  144|     22|  replentry* r = new replentry;
  145|     22|  r->pattern = std::move(pat1);
  146|     22|  r->outstrings[type] = pat2;
  147|     22|  mystrrep(r->outstrings[type], "_", " ");
  148|     22|  dat.push_back(r);
  149|       |  // sort to the right place in the list
  150|     22|  size_t i;
  151|     36|  for (i = dat.size() - 1; i > 0; --i) {
  ------------------
  |  Branch (151:28): [True: 30, False: 6]
  ------------------
  152|     30|    if (strcmp(r->pattern.c_str(), dat[i - 1]->pattern.c_str()) < 0) {
  ------------------
  |  Branch (152:9): [True: 14, False: 16]
  ------------------
  153|     14|      dat[i] = dat[i - 1];
  154|     14|    } else
  155|     16|      break;
  156|     30|  }
  157|     22|  dat[i] = r;
  158|     22|  return 0;
  159|     22|}
_ZN7RepList4convERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERS6_:
  161|   255k|bool RepList::conv(const std::string& in_word, std::string& dest) {
  162|   255k|  dest.clear();
  163|       |
  164|   255k|  const size_t wordlen = in_word.size();
  165|   255k|  const char* word = in_word.c_str();
  166|       |
  167|   255k|  bool change = false;
  168|  2.55M|  for (size_t i = 0; i < wordlen; ++i) {
  ------------------
  |  Branch (168:22): [True: 2.29M, False: 255k]
  ------------------
  169|  2.29M|    int n = find(word + i);
  170|       |
  171|  2.29M|    bool empty = n < 0;
  172|  2.29M|    if (empty) {
  ------------------
  |  Branch (172:9): [True: 2.29M, False: 398]
  ------------------
  173|  2.29M|      dest.push_back(word[i]);
  174|  2.29M|      continue;
  175|  2.29M|    }
  176|       |
  177|    398|    std::string l = replace(wordlen - i, n, i == 0);
  178|    398|    if (l.empty()) {
  ------------------
  |  Branch (178:9): [True: 0, False: 398]
  ------------------
  179|      0|      dest.push_back(word[i]);
  180|      0|      continue;
  181|      0|    }
  182|       |
  183|    398|    dest.append(l);
  184|    398|    if (!dat[n]->pattern.empty()) {
  ------------------
  |  Branch (184:9): [True: 398, False: 0]
  ------------------
  185|    398|      i += dat[n]->pattern.size() - 1;
  186|    398|    }
  187|    398|    change = true;
  188|    398|  }
  189|       |
  190|   255k|  return change;
  191|   255k|}
_ZNK7RepList24check_against_breaktableERKNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEE:
  193|      2|bool RepList::check_against_breaktable(const std::vector<std::string>& breaktable) const {
  194|      8|  for (const auto i : dat) {
  ------------------
  |  Branch (194:21): [True: 8, False: 2]
  ------------------
  195|     32|    for (auto& outstring : i->outstrings) {
  ------------------
  |  Branch (195:26): [True: 32, False: 8]
  ------------------
  196|     96|      for (const auto& str : breaktable) {
  ------------------
  |  Branch (196:28): [True: 96, False: 32]
  ------------------
  197|     96|        if (outstring.find(str) != std::string::npos) {
  ------------------
  |  Branch (197:13): [True: 0, False: 96]
  ------------------
  198|      0|          return false;
  199|      0|        }
  200|     96|      }
  201|     32|    }
  202|      8|  }
  203|       |
  204|      2|  return true;
  205|      2|}

_ZN10SuggestMgrC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEjP8AffixMgr:
   87|     38|SuggestMgr::SuggestMgr(const std::string& tryme, unsigned int maxn, AffixMgr* aptr) {
   88|       |  // register affix manager and check in string of chars to
   89|       |  // try when building candidate suggestions
   90|     38|  pAMgr = aptr;
   91|       |
   92|     38|  csconv = nullptr;
   93|       |
   94|     38|  ckeyl = 0;
   95|       |
   96|     38|  ctryl = 0;
   97|       |
   98|     38|  utf8 = 0;
   99|     38|  langnum = 0;
  100|     38|  complexprefixes = 0;
  101|       |
  102|     38|  maxSug = maxn;
  103|     38|  nosplitsugs = 0;
  104|     38|  maxngramsugs = MAXNGRAMSUGS;
  ------------------
  |  |   77|     38|#define MAXNGRAMSUGS 4
  ------------------
  105|     38|  maxcpdsugs = MAXCOMPOUNDSUGS;
  ------------------
  |  |   79|     38|#define MAXCOMPOUNDSUGS 3
  ------------------
  106|       |
  107|     38|  if (pAMgr) {
  ------------------
  |  Branch (107:7): [True: 38, False: 0]
  ------------------
  108|     38|    langnum = pAMgr->get_langnum();
  109|     38|    ckey = pAMgr->get_key_string();
  110|     38|    nosplitsugs = pAMgr->get_nosplitsugs();
  111|     38|    if (pAMgr->get_maxngramsugs() >= 0)
  ------------------
  |  Branch (111:9): [True: 4, False: 34]
  ------------------
  112|      4|      maxngramsugs = pAMgr->get_maxngramsugs();
  113|     38|    utf8 = pAMgr->get_utf8();
  114|     38|    if (pAMgr->get_maxcpdsugs() >= 0)
  ------------------
  |  Branch (114:9): [True: 0, False: 38]
  ------------------
  115|      0|      maxcpdsugs = pAMgr->get_maxcpdsugs();
  116|     38|    if (!utf8) {
  ------------------
  |  Branch (116:9): [True: 20, False: 18]
  ------------------
  117|     20|      csconv = get_current_cs(pAMgr->get_encoding());
  118|     20|    }
  119|     38|    complexprefixes = pAMgr->get_complexprefixes();
  120|     38|  }
  121|       |
  122|     38|  if (!ckey.empty()) {
  ------------------
  |  Branch (122:7): [True: 38, False: 0]
  ------------------
  123|     38|    if (utf8) {
  ------------------
  |  Branch (123:9): [True: 18, False: 20]
  ------------------
  124|     18|      int len = u8_u16(ckey_utf, ckey);
  125|     18|      if (len != -1) {
  ------------------
  |  Branch (125:11): [True: 18, False: 0]
  ------------------
  126|     18|        ckeyl = len;
  127|     18|      }
  128|     20|    } else {
  129|     20|      ckeyl = ckey.size();
  130|     20|    }
  131|     38|  }
  132|       |
  133|     38|  ctry = tryme;
  134|     38|  if (!ctry.empty()) {
  ------------------
  |  Branch (134:7): [True: 2, False: 36]
  ------------------
  135|      2|    if (utf8) {
  ------------------
  |  Branch (135:9): [True: 2, False: 0]
  ------------------
  136|      2|      int len = u8_u16(ctry_utf, ctry);
  137|      2|      if (len != -1) {
  ------------------
  |  Branch (137:11): [True: 2, False: 0]
  ------------------
  138|      2|        ctryl = len;
  139|      2|      }
  140|      2|    } else {
  141|      0|      ctryl = ctry.size();
  142|      0|    }
  143|      2|  }
  144|       |
  145|       |  // language with possible dash usage
  146|       |  // (latin letters or dash in TRY characters)
  147|     38|  lang_with_dash_usage = ctry.find('-') != std::string::npos ||
  ------------------
  |  Branch (147:26): [True: 0, False: 38]
  ------------------
  148|     38|                         ctry.find('a') != std::string::npos;
  ------------------
  |  Branch (148:26): [True: 0, False: 38]
  ------------------
  149|     38|}
_ZN10SuggestMgr7testsugERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iPiPNS0_6chrono10time_pointINSE_12steady_clockENSE_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEERi:
  166|  78.7M|                        int& info) {
  167|  78.7M|  if (wlst.size() == maxSug)
  ------------------
  |  Branch (167:7): [True: 0, False: 78.7M]
  ------------------
  168|      0|    return;
  169|       |
  170|  78.7M|  const int cwrd = std::find(wlst.begin(), wlst.end(), candidate) != wlst.end() ? 0 : 1;
  ------------------
  |  Branch (170:20): [True: 22.4k, False: 78.6M]
  ------------------
  171|       |
  172|  78.7M|  if (cwrd) {
  ------------------
  |  Branch (172:7): [True: 78.6M, False: 22.4k]
  ------------------
  173|  78.6M|    if (int result = checkword(candidate, cpdsuggest, timer, timelimit)) {
  ------------------
  |  Branch (173:13): [True: 933, False: 78.6M]
  ------------------
  174|       |      // compound word in the dictionary
  175|    933|      if (cpdsuggest == 0 && result >= 2)
  ------------------
  |  Branch (175:11): [True: 933, False: 0]
  |  Branch (175:30): [True: 2, False: 931]
  ------------------
  176|      2|          info |= SPELL_COMPOUND;
  ------------------
  |  |   78|      2|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  177|    933|      wlst.push_back(candidate);
  178|    933|    }
  179|  78.6M|  }
  180|  78.7M|}
_ZN10SuggestMgr7suggestERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_Pib:
  190|   139k|                        int* onlycompoundsug, bool test_simplesug) {
  191|   139k|  int nocompoundtwowords = 0; // no second or third loops, see below
  192|   139k|  std::vector<w_char> word_utf;
  193|   139k|  size_t nsugorig = slst.size(), oldSug = 0;
  194|   139k|  std::string w2;
  195|   139k|  bool good_suggestion = false;
  196|       |
  197|       |  // word reversing wrapper for complex prefixes
  198|   139k|  if (complexprefixes) {
  ------------------
  |  Branch (198:7): [True: 8.10k, False: 131k]
  ------------------
  199|  8.10k|    w2.assign(w);
  200|  8.10k|    if (utf8)
  ------------------
  |  Branch (200:9): [True: 0, False: 8.10k]
  ------------------
  201|      0|      reverseword_utf(w2);
  202|  8.10k|    else
  203|  8.10k|      reverseword(w2);
  204|  8.10k|  }
  205|       |
  206|   139k|  const std::string& word = complexprefixes ? w2 : w;
  ------------------
  |  Branch (206:29): [True: 8.10k, False: 131k]
  ------------------
  207|       |
  208|   139k|  suggest_start = std::chrono::steady_clock::now();
  209|       |
  210|   139k|  if (utf8) {
  ------------------
  |  Branch (210:7): [True: 58.1k, False: 81.6k]
  ------------------
  211|  58.1k|    int wl = u8_u16(word_utf, word);
  212|  58.1k|    if (wl == -1) {
  ------------------
  |  Branch (212:9): [True: 9.97k, False: 48.1k]
  ------------------
  213|  9.97k|      return false;
  214|  9.97k|    }
  215|  58.1k|  }
  216|       |
  217|       |  // three loops:
  218|       |  // - the first without compounding,
  219|       |  // - the second one with 2-word compounding,
  220|       |  // - the third one with 3-or-more-word compounding
  221|       |  // Run second and third loops only if:
  222|       |  // - no ~good suggestion in the first loop
  223|       |  // - not for testing compound words with 3 or more words (test_simplesug == false)
  224|   129k|  int info = 0;
  225|   519k|  for (int cpdsuggest = 0; cpdsuggest < 3 && nocompoundtwowords == 0; cpdsuggest++) {
  ------------------
  |  Branch (225:28): [True: 389k, False: 129k]
  |  Branch (225:46): [True: 389k, False: 35]
  ------------------
  226|       |
  227|       |    // limit compound suggestion
  228|   389k|    if (cpdsuggest > 0)
  ------------------
  |  Branch (228:9): [True: 259k, False: 129k]
  ------------------
  229|   259k|      oldSug = slst.size();
  230|       |
  231|       |    // suggestions for an uppercase word (html -> HTML)
  232|   389k|    if (slst.size() < maxSug) {
  ------------------
  |  Branch (232:9): [True: 389k, False: 17]
  ------------------
  233|   389k|      size_t i = slst.size();
  234|   389k|      if (utf8)
  ------------------
  |  Branch (234:11): [True: 144k, False: 244k]
  ------------------
  235|   144k|        capchars_utf(slst, word_utf, cpdsuggest, info);
  236|   244k|      else
  237|   244k|        capchars(slst, word, cpdsuggest, info);
  238|   389k|      if (slst.size() > i)
  ------------------
  |  Branch (238:11): [True: 33, False: 389k]
  ------------------
  239|     33|        good_suggestion = true;
  240|   389k|    }
  241|       |
  242|       |    // perhaps we made a typical fault of spelling
  243|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (243:9): [True: 389k, False: 17]
  |  Branch (243:36): [True: 129k, False: 259k]
  |  Branch (243:51): [True: 259k, False: 0]
  ------------------
  244|   389k|      size_t i = slst.size();
  245|   389k|      replchars(slst, word, cpdsuggest, info);
  246|   389k|      if (slst.size() > i) {
  ------------------
  |  Branch (246:11): [True: 0, False: 389k]
  ------------------
  247|      0|        good_suggestion = true;
  248|      0|        if (info & SPELL_BEST_SUG)
  ------------------
  |  |   86|      0|#define SPELL_BEST_SUG (1 << 8)    // limit suggestions for the best ones, i.e. ph:
  ------------------
  |  Branch (248:13): [True: 0, False: 0]
  ------------------
  249|      0|          return true;
  250|      0|      }
  251|   389k|    }
  252|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (252:9): [True: 0, False: 389k]
  ------------------
  253|      0|      return good_suggestion;
  254|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (254:9): [True: 0, False: 389k]
  |  Branch (254:27): [True: 0, False: 0]
  ------------------
  255|      0|      return true;
  256|       |
  257|       |    // perhaps we made chose the wrong char from a related set
  258|   389k|    if ((slst.size() < maxSug) &&
  ------------------
  |  Branch (258:9): [True: 389k, False: 17]
  ------------------
  259|   389k|        (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (259:10): [True: 129k, False: 259k]
  |  Branch (259:25): [True: 259k, False: 0]
  ------------------
  260|   389k|      mapchars(slst, word, cpdsuggest, info);
  261|   389k|    }
  262|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (262:9): [True: 9, False: 389k]
  ------------------
  263|      9|      return good_suggestion;
  264|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (264:9): [True: 0, False: 389k]
  |  Branch (264:27): [True: 0, False: 0]
  ------------------
  265|      0|      return true;
  266|       |
  267|       |    // only suggest compound words when no other ~good suggestion
  268|   389k|    if ((cpdsuggest == 0) && (slst.size() > nsugorig))
  ------------------
  |  Branch (268:9): [True: 129k, False: 259k]
  |  Branch (268:30): [True: 33, False: 129k]
  ------------------
  269|     33|      nocompoundtwowords = 1;
  270|       |
  271|       |    // did we swap the order of chars by mistake
  272|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (272:9): [True: 389k, False: 17]
  |  Branch (272:36): [True: 129k, False: 259k]
  |  Branch (272:51): [True: 259k, False: 0]
  ------------------
  273|   389k|      if (utf8)
  ------------------
  |  Branch (273:11): [True: 144k, False: 244k]
  ------------------
  274|   144k|        swapchar_utf(slst, word_utf, cpdsuggest, info);
  275|   244k|      else
  276|   244k|        swapchar(slst, word, cpdsuggest, info);
  277|   389k|    }
  278|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (278:9): [True: 0, False: 389k]
  ------------------
  279|      0|      return good_suggestion;
  280|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (280:9): [True: 0, False: 389k]
  |  Branch (280:27): [True: 0, False: 0]
  ------------------
  281|      0|      return true;
  282|       |
  283|       |    // did we swap the order of non adjacent chars by mistake
  284|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (284:9): [True: 389k, False: 17]
  |  Branch (284:36): [True: 129k, False: 259k]
  |  Branch (284:51): [True: 259k, False: 0]
  ------------------
  285|   389k|      if (utf8)
  ------------------
  |  Branch (285:11): [True: 144k, False: 244k]
  ------------------
  286|   144k|        longswapchar_utf(slst, word_utf, cpdsuggest, info);
  287|   244k|      else
  288|   244k|        longswapchar(slst, word, cpdsuggest, info);
  289|   389k|    }
  290|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (290:9): [True: 0, False: 389k]
  ------------------
  291|      0|      return good_suggestion;
  292|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (292:9): [True: 0, False: 389k]
  |  Branch (292:27): [True: 0, False: 0]
  ------------------
  293|      0|      return true;
  294|       |
  295|       |    // did we just hit the wrong key in place of a good char (case and keyboard)
  296|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (296:9): [True: 389k, False: 17]
  |  Branch (296:36): [True: 129k, False: 259k]
  |  Branch (296:51): [True: 259k, False: 0]
  ------------------
  297|   389k|      if (utf8)
  ------------------
  |  Branch (297:11): [True: 144k, False: 244k]
  ------------------
  298|   144k|        badcharkey_utf(slst, word_utf, cpdsuggest, info);
  299|   244k|      else
  300|   244k|        badcharkey(slst, word, cpdsuggest, info);
  301|   389k|    }
  302|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (302:9): [True: 0, False: 389k]
  ------------------
  303|      0|      return good_suggestion;
  304|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (304:9): [True: 0, False: 389k]
  |  Branch (304:27): [True: 0, False: 0]
  ------------------
  305|      0|      return true;
  306|       |
  307|       |    // did we add a char that should not be there
  308|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (308:9): [True: 389k, False: 17]
  |  Branch (308:36): [True: 129k, False: 259k]
  |  Branch (308:51): [True: 259k, False: 0]
  ------------------
  309|   389k|      if (utf8)
  ------------------
  |  Branch (309:11): [True: 144k, False: 244k]
  ------------------
  310|   144k|        extrachar_utf(slst, word_utf, cpdsuggest, info);
  311|   244k|      else
  312|   244k|        extrachar(slst, word, cpdsuggest, info);
  313|   389k|    }
  314|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (314:9): [True: 0, False: 389k]
  ------------------
  315|      0|      return good_suggestion;
  316|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (316:9): [True: 0, False: 389k]
  |  Branch (316:27): [True: 0, False: 0]
  ------------------
  317|      0|      return true;
  318|       |
  319|       |    // did we forgot a char
  320|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (320:9): [True: 389k, False: 17]
  |  Branch (320:36): [True: 129k, False: 259k]
  |  Branch (320:51): [True: 259k, False: 0]
  ------------------
  321|   389k|      if (utf8)
  ------------------
  |  Branch (321:11): [True: 144k, False: 244k]
  ------------------
  322|   144k|        forgotchar_utf(slst, word_utf, cpdsuggest, info);
  323|   244k|      else
  324|   244k|        forgotchar(slst, word, cpdsuggest, info);
  325|   389k|    }
  326|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (326:9): [True: 0, False: 389k]
  ------------------
  327|      0|      return good_suggestion;
  328|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (328:9): [True: 0, False: 389k]
  |  Branch (328:27): [True: 0, False: 0]
  ------------------
  329|      0|      return true;
  330|       |
  331|       |    // did we move a char
  332|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (332:9): [True: 389k, False: 17]
  |  Branch (332:36): [True: 129k, False: 259k]
  |  Branch (332:51): [True: 259k, False: 0]
  ------------------
  333|   389k|      if (utf8)
  ------------------
  |  Branch (333:11): [True: 144k, False: 244k]
  ------------------
  334|   144k|        movechar_utf(slst, word_utf, cpdsuggest, info);
  335|   244k|      else
  336|   244k|        movechar(slst, word, cpdsuggest, info);
  337|   389k|    }
  338|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (338:9): [True: 0, False: 389k]
  ------------------
  339|      0|      return good_suggestion;
  340|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (340:9): [True: 0, False: 389k]
  |  Branch (340:27): [True: 0, False: 0]
  ------------------
  341|      0|      return true;
  342|       |
  343|       |    // did we just hit the wrong key in place of a good char
  344|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (344:9): [True: 389k, False: 17]
  |  Branch (344:36): [True: 129k, False: 259k]
  |  Branch (344:51): [True: 259k, False: 0]
  ------------------
  345|   389k|      if (utf8)
  ------------------
  |  Branch (345:11): [True: 144k, False: 244k]
  ------------------
  346|   144k|        badchar_utf(slst, word_utf, cpdsuggest, info);
  347|   244k|      else
  348|   244k|        badchar(slst, word, cpdsuggest, info);
  349|   389k|    }
  350|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (350:9): [True: 0, False: 389k]
  ------------------
  351|      0|      return good_suggestion;
  352|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (352:9): [True: 0, False: 389k]
  |  Branch (352:27): [True: 0, False: 0]
  ------------------
  353|      0|      return true;
  354|       |
  355|       |    // did we double two characters
  356|   389k|    if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
  ------------------
  |  Branch (356:9): [True: 389k, False: 17]
  |  Branch (356:36): [True: 129k, False: 259k]
  |  Branch (356:51): [True: 259k, False: 0]
  ------------------
  357|   389k|      if (utf8)
  ------------------
  |  Branch (357:11): [True: 144k, False: 244k]
  ------------------
  358|   144k|        doubletwochars_utf(slst, word_utf, cpdsuggest, info);
  359|   244k|      else
  360|   244k|        doubletwochars(slst, word, cpdsuggest, info);
  361|   389k|    }
  362|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (362:9): [True: 0, False: 389k]
  ------------------
  363|      0|      return good_suggestion;
  364|   389k|    if (test_simplesug && slst.size())
  ------------------
  |  Branch (364:9): [True: 0, False: 389k]
  |  Branch (364:27): [True: 0, False: 0]
  ------------------
  365|      0|      return true;
  366|       |
  367|       |    // perhaps we forgot to hit space and two words ran together
  368|       |    // (dictionary word pairs have top priority here, so
  369|       |    // we always suggest them, in despite of nosplitsugs, and
  370|       |    // drop compound word and other suggestions)
  371|   389k|    if (!cpdsuggest || (!nosplitsugs && slst.size() < oldSug + maxcpdsugs)) {
  ------------------
  |  Branch (371:9): [True: 129k, False: 259k]
  |  Branch (371:25): [True: 259k, False: 0]
  |  Branch (371:41): [True: 259k, False: 0]
  ------------------
  372|   389k|      good_suggestion = twowords(slst, word, cpdsuggest, good_suggestion, info);
  373|       |
  374|   389k|      if (info & SPELL_BEST_SUG)
  ------------------
  |  |   86|   389k|#define SPELL_BEST_SUG (1 << 8)    // limit suggestions for the best ones, i.e. ph:
  ------------------
  |  Branch (374:11): [True: 126, False: 389k]
  ------------------
  375|    126|        return true;
  376|   389k|    }
  377|   389k|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|   389k|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (377:9): [True: 0, False: 389k]
  ------------------
  378|      0|      return good_suggestion;
  379|       |
  380|       |    // testing returns after the first loop
  381|   389k|    if (test_simplesug)
  ------------------
  |  Branch (381:9): [True: 0, False: 389k]
  ------------------
  382|      0|      return slst.size() > 0;
  383|       |
  384|       |    // don't need third loop, if the second loop was successful or
  385|       |    // the first loop found a dictionary-based compound word
  386|       |    // (we don't need more, likely worse and false 3-or-more-word compound words)
  387|   389k|    if (cpdsuggest == 1 && (slst.size() > oldSug || (info & SPELL_COMPOUND)))
  ------------------
  |  |   78|   129k|#define SPELL_COMPOUND (1 << 0)    // the result is a compound word
  ------------------
  |  Branch (387:9): [True: 129k, False: 259k]
  |  Branch (387:29): [True: 0, False: 129k]
  |  Branch (387:53): [True: 2, False: 129k]
  ------------------
  388|      2|       nocompoundtwowords = 1;
  389|       |
  390|   389k|  }  // repeating ``for'' statement compounding support
  391|       |
  392|   129k|  if (!nocompoundtwowords && (!slst.empty()) && onlycompoundsug)
  ------------------
  |  Branch (392:7): [True: 129k, False: 35]
  |  Branch (392:30): [True: 8.52k, False: 121k]
  |  Branch (392:49): [True: 8.52k, False: 0]
  ------------------
  393|  8.52k|    *onlycompoundsug = 1;
  394|       |
  395|   129k|  return good_suggestion;
  396|   129k|}
_ZN10SuggestMgr12capchars_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
  401|   144k|                              int cpdsuggest, int& info) {
  402|   144k|  std::vector<w_char> candidate_utf(word);
  403|   144k|  mkallcap_utf(candidate_utf, langnum);
  404|   144k|  std::string candidate;
  405|   144k|  u16_u8(candidate, candidate_utf);
  406|   144k|  testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  407|   144k|}
_ZN10SuggestMgr8capcharsERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  412|   244k|                          int cpdsuggest, int& info) {
  413|   244k|  std::string candidate(word);
  414|   244k|  mkallcap(candidate, csconv);
  415|   244k|  testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  416|   244k|}
_ZN10SuggestMgr8mapcharsERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  421|   389k|                         int cpdsuggest, int& info) {
  422|   389k|  std::string candidate;
  423|   389k|  std::chrono::steady_clock::time_point timelimit;
  424|   389k|  int timer;
  425|       |
  426|   389k|  if (word.size() < 2 || !pAMgr)
  ------------------
  |  Branch (426:7): [True: 29.4k, False: 359k]
  |  Branch (426:26): [True: 0, False: 359k]
  ------------------
  427|  29.4k|    return wlst.size();
  428|       |
  429|   359k|  const std::vector<mapentry>& maptable = pAMgr->get_maptable();
  430|   359k|  if (maptable.empty())
  ------------------
  |  Branch (430:7): [True: 345k, False: 14.3k]
  ------------------
  431|   345k|    return wlst.size();
  432|       |
  433|  14.3k|  timelimit = std::chrono::steady_clock::now();
  434|  14.3k|  timer = MINTIMER;
  ------------------
  |  |  107|  14.3k|#define MINTIMER 100
  ------------------
  435|  14.3k|  return map_related(word, candidate, 0, wlst, cpdsuggest,
  436|  14.3k|                     maptable, &timer, &timelimit, 0, info);
  437|   359k|}
_ZN10SuggestMgr11map_relatedERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERS6_mRNS0_6vectorIS6_NS4_IS6_EEEEiRKNSA_ISC_NS4_ISC_EEEEPiPNS0_6chrono10time_pointINSJ_12steady_clockENSJ_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEEiRi:
  447|  5.66M|                            int depth, int& info) {
  448|  5.66M|  if (word.size() == wn) {
  ------------------
  |  Branch (448:7): [True: 943k, False: 4.72M]
  ------------------
  449|   943k|    if (candidate == word)
  ------------------
  |  Branch (449:9): [True: 14.3k, False: 929k]
  ------------------
  450|  14.3k|      return wlst.size();
  451|   929k|    const int cwrd = std::find(wlst.begin(), wlst.end(), candidate) != wlst.end() ? 0 : 1;
  ------------------
  |  Branch (451:22): [True: 0, False: 929k]
  ------------------
  452|   929k|    if ((cwrd) && checkword(candidate, cpdsuggest, timer, timelimit)) {
  ------------------
  |  Branch (452:9): [True: 929k, False: 0]
  |  Branch (452:19): [True: 0, False: 929k]
  ------------------
  453|      0|      if (wlst.size() < maxSug) {
  ------------------
  |  Branch (453:11): [True: 0, False: 0]
  ------------------
  454|      0|        wlst.push_back(candidate);
  455|      0|      }
  456|      0|    }
  457|   929k|    return wlst.size();
  458|   943k|  }
  459|       |
  460|  4.72M|  if (depth > 0x3F00) {
  ------------------
  |  Branch (460:7): [True: 0, False: 4.72M]
  ------------------
  461|      0|    *timer = 0;
  462|      0|    return wlst.size();
  463|      0|  }
  464|       |
  465|  4.72M|  int in_map = 0;
  466|  18.8M|  for (size_t j = 0; j < maptable.size(); ++j) {
  ------------------
  |  Branch (466:22): [True: 14.1M, False: 4.72M]
  ------------------
  467|  51.9M|    for (size_t k = 0; k < maptable[j].size(); ++k) {
  ------------------
  |  Branch (467:24): [True: 37.7M, False: 14.1M]
  ------------------
  468|  37.7M|      size_t len = maptable[j][k].size();
  469|  37.7M|      if (len && word.compare(wn, len, maptable[j][k]) == 0) {
  ------------------
  |  Branch (469:11): [True: 37.7M, False: 0]
  |  Branch (469:18): [True: 464k, False: 37.3M]
  ------------------
  470|   464k|        in_map = 1;
  471|   464k|        size_t cn = candidate.size();
  472|  1.85M|        for (size_t l = 0; l < maptable[j].size(); ++l) {
  ------------------
  |  Branch (472:28): [True: 1.39M, False: 464k]
  ------------------
  473|  1.39M|          candidate.resize(cn);
  474|  1.39M|          candidate.append(maptable[j][l]);
  475|  1.39M|          map_related(word, candidate, wn + len, wlst,
  476|  1.39M|                           cpdsuggest, maptable, timer, timelimit, depth + 1, info);
  477|  1.39M|          if (!(*timer))
  ------------------
  |  Branch (477:15): [True: 340, False: 1.39M]
  ------------------
  478|    340|            return wlst.size();
  479|  1.39M|          if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS) {
  ------------------
  |  |  105|  1.39M|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (479:15): [True: 9, False: 1.39M]
  ------------------
  480|      9|            *timer = 0;
  481|      9|            return wlst.size();
  482|      9|          }
  483|  1.39M|        }
  484|   464k|      }
  485|  37.7M|    }
  486|  14.1M|  }
  487|  4.72M|  if (!in_map) {
  ------------------
  |  Branch (487:7): [True: 4.25M, False: 464k]
  ------------------
  488|  4.25M|    candidate.push_back(word[wn]);
  489|  4.25M|    map_related(word, candidate, wn + 1, wlst, cpdsuggest,
  490|  4.25M|                maptable, timer, timelimit, depth + 1, info);
  491|  4.25M|  }
  492|  4.72M|  return wlst.size();
  493|  4.72M|}
_ZN10SuggestMgr9replcharsERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  499|   389k|                          int cpdsuggest, int& info) {
  500|   389k|  std::string candidate;
  501|   389k|  int wl = word.size();
  502|   389k|  if (wl < 2 || !pAMgr)
  ------------------
  |  Branch (502:7): [True: 29.4k, False: 359k]
  |  Branch (502:17): [True: 0, False: 359k]
  ------------------
  503|  29.4k|    return wlst.size();
  504|   359k|  const std::vector<replentry>& reptable = pAMgr->get_reptable();
  505|   359k|  auto replchars_start = std::chrono::steady_clock::now();
  506|   359k|  for (const auto& entry : reptable) {
  ------------------
  |  Branch (506:26): [True: 74.1k, False: 359k]
  ------------------
  507|  74.1k|    size_t r = 0;
  508|       |    // search every occurence of the pattern in the word
  509|  74.7k|    while ((r = word.find(entry.pattern, r)) != std::string::npos) {
  ------------------
  |  Branch (509:12): [True: 579, False: 74.1k]
  ------------------
  510|    579|      if (std::chrono::steady_clock::now() - replchars_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|    579|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (510:11): [True: 0, False: 579]
  ------------------
  511|      0|        return wlst.size();
  512|    579|      int type = (r == 0) ? 1 : 0;
  ------------------
  |  Branch (512:18): [True: 0, False: 579]
  ------------------
  513|    579|      if (r + entry.pattern.size() == word.size())
  ------------------
  |  Branch (513:11): [True: 0, False: 579]
  ------------------
  514|      0|        type += 2;
  515|    579|      while (type && entry.outstrings[type].empty())
  ------------------
  |  Branch (515:14): [True: 0, False: 579]
  |  Branch (515:22): [True: 0, False: 0]
  ------------------
  516|      0|        type = (type == 2 && r != 0) ? 0 : type - 1;
  ------------------
  |  Branch (516:17): [True: 0, False: 0]
  |  Branch (516:30): [True: 0, False: 0]
  ------------------
  517|    579|      const std::string&out = entry.outstrings[type];
  518|    579|      if (out.empty()) {
  ------------------
  |  Branch (518:11): [True: 0, False: 579]
  ------------------
  519|      0|        ++r;
  520|      0|        continue;
  521|      0|      }
  522|    579|      candidate.assign(word, 0, r);
  523|    579|      candidate.append(entry.outstrings[type]);
  524|    579|      candidate.append(word, r + entry.pattern.size(), std::string::npos);
  525|    579|      size_t sp = candidate.find(' ');
  526|    579|      size_t oldns = wlst.size();
  527|    579|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  528|    579|      if (oldns < wlst.size()) {
  ------------------
  |  Branch (528:11): [True: 0, False: 579]
  ------------------
  529|       |        // REP suggestions are the best, don't search other type of suggestions
  530|      0|        info |= SPELL_BEST_SUG;
  ------------------
  |  |   86|      0|#define SPELL_BEST_SUG (1 << 8)    // limit suggestions for the best ones, i.e. ph:
  ------------------
  531|      0|      }
  532|       |
  533|       |      // check REP suggestions with space
  534|    579|      if (sp != std::string::npos) {
  ------------------
  |  Branch (534:11): [True: 0, False: 579]
  ------------------
  535|      0|        size_t prev = 0;
  536|      0|        while (sp != std::string::npos) {
  ------------------
  |  Branch (536:16): [True: 0, False: 0]
  ------------------
  537|      0|          std::string prev_chunk = candidate.substr(prev, sp - prev);
  538|      0|          if (checkword(prev_chunk, 0, nullptr, nullptr)) {
  ------------------
  |  Branch (538:15): [True: 0, False: 0]
  ------------------
  539|      0|            oldns = wlst.size();
  540|      0|            std::string post_chunk = candidate.substr(sp + 1);
  541|      0|            testsug(wlst, post_chunk, cpdsuggest, nullptr, nullptr, info);
  542|      0|            if (oldns < wlst.size()) {
  ------------------
  |  Branch (542:17): [True: 0, False: 0]
  ------------------
  543|      0|              wlst[wlst.size() - 1] = candidate;
  544|      0|            }
  545|      0|          }
  546|      0|          prev = sp + 1;
  547|      0|          sp = candidate.find(' ', prev);
  548|      0|        }
  549|      0|      }
  550|    579|      r++;  // search for the next letter
  551|    579|    }
  552|  74.1k|  }
  553|   359k|  return wlst.size();
  554|   359k|}
_ZN10SuggestMgr14doubletwocharsERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  563|   244k|                               int cpdsuggest, int& info) {
  564|   244k|  size_t wl = word.size();
  565|   244k|  if (wl < 5 || !pAMgr)
  ------------------
  |  Branch (565:7): [True: 55.4k, False: 189k]
  |  Branch (565:17): [True: 0, False: 189k]
  ------------------
  566|  55.4k|    return wlst.size();
  567|       |
  568|   189k|  int state = 0;
  569|  4.75M|  for (size_t i = 2; i < wl; ++i) {
  ------------------
  |  Branch (569:22): [True: 4.56M, False: 189k]
  ------------------
  570|  4.56M|    if (word[i] == word[i - 2]) {
  ------------------
  |  Branch (570:9): [True: 1.16M, False: 3.40M]
  ------------------
  571|  1.16M|      state++;
  572|  1.16M|      if (state == 3 || (state == 2 && i >= 4)) {
  ------------------
  |  Branch (572:11): [True: 7.40k, False: 1.15M]
  |  Branch (572:26): [True: 414k, False: 739k]
  |  Branch (572:40): [True: 404k, False: 10.1k]
  ------------------
  573|   411k|        auto word_iter = word.begin();
  574|   411k|        std::string candidate(word_iter, word_iter + i - 1);
  575|   411k|        candidate.insert(candidate.end(), word_iter + i + 1, word.end());
  576|   411k|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  577|   411k|        state = 0;
  578|   411k|      }
  579|  3.40M|    } else {
  580|  3.40M|      state = 0;
  581|  3.40M|    }
  582|  4.56M|  }
  583|   189k|  return wlst.size();
  584|   244k|}
_ZN10SuggestMgr18doubletwochars_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
  593|   144k|                                   int cpdsuggest, int& info) {
  594|   144k|  size_t wl = word.size();
  595|   144k|  int state = 0;
  596|   144k|  if (wl < 5 || !pAMgr)
  ------------------
  |  Branch (596:7): [True: 51.8k, False: 92.6k]
  |  Branch (596:17): [True: 0, False: 92.6k]
  ------------------
  597|  51.8k|    return wlst.size();
  598|  1.55M|  for (size_t i = 2; i < wl; ++i) {
  ------------------
  |  Branch (598:22): [True: 1.46M, False: 92.6k]
  ------------------
  599|  1.46M|    if (word[i] == word[i - 2]) {
  ------------------
  |  Branch (599:9): [True: 465k, False: 998k]
  ------------------
  600|   465k|      state++;
  601|   465k|      if (state == 3 || (state == 2 && i >= 4)) {
  ------------------
  |  Branch (601:11): [True: 4.00k, False: 461k]
  |  Branch (601:26): [True: 165k, False: 296k]
  |  Branch (601:40): [True: 160k, False: 5.37k]
  ------------------
  602|   164k|        auto word_iter = word.begin();
  603|   164k|        std::vector<w_char> candidate_utf(word_iter, word_iter + i - 1);
  604|   164k|        candidate_utf.insert(candidate_utf.end(), word_iter + i + 1, word.end());
  605|   164k|        std::string candidate;
  606|   164k|        u16_u8(candidate, candidate_utf);
  607|   164k|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  608|   164k|        state = 0;
  609|   164k|      }
  610|   998k|    } else {
  611|   998k|      state = 0;
  612|   998k|    }
  613|  1.46M|  }
  614|  92.6k|  return wlst.size();
  615|   144k|}
_ZN10SuggestMgr10badcharkeyERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  621|   244k|                           int cpdsuggest, int& info) {
  622|   244k|  std::string candidate(word);
  623|       |
  624|       |  // swap out each char one by one and try uppercase and neighbor
  625|       |  // keyboard chars in its place to see if that makes a good word
  626|  5.32M|  for (size_t i = 0, wl = candidate.size(); i < wl; ++i) {
  ------------------
  |  Branch (626:45): [True: 5.07M, False: 244k]
  ------------------
  627|  5.07M|    char tmpc = candidate[i];
  628|       |    // check with uppercase letters
  629|  5.07M|    candidate[i] = csconv[((unsigned char)tmpc)].cupper;
  630|  5.07M|    if (tmpc != candidate[i]) {
  ------------------
  |  Branch (630:9): [True: 1.18M, False: 3.89M]
  ------------------
  631|  1.18M|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  632|  1.18M|      candidate[i] = tmpc;
  633|  1.18M|    }
  634|       |    // check neighbor characters in keyboard string
  635|  5.07M|    if (ckey.empty())
  ------------------
  |  Branch (635:9): [True: 0, False: 5.07M]
  ------------------
  636|      0|      continue;
  637|  5.07M|    size_t loc = 0;
  638|   135M|    while ((loc < ckeyl) && ckey[loc] != tmpc)
  ------------------
  |  Branch (638:12): [True: 130M, False: 4.32M]
  |  Branch (638:29): [True: 129M, False: 751k]
  ------------------
  639|   129M|      ++loc;
  640|  5.84M|    while (loc < ckeyl) {
  ------------------
  |  Branch (640:12): [True: 767k, False: 5.07M]
  ------------------
  641|   767k|      if ((loc > 0) && ckey[loc - 1] != '|') {
  ------------------
  |  Branch (641:11): [True: 606k, False: 161k]
  |  Branch (641:24): [True: 576k, False: 29.6k]
  ------------------
  642|   576k|        candidate[i] = ckey[loc - 1];
  643|   576k|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  644|   576k|      }
  645|   767k|      if (((loc + 1) < ckeyl) && (ckey[loc + 1] != '|')) {
  ------------------
  |  Branch (645:11): [True: 699k, False: 67.7k]
  |  Branch (645:34): [True: 621k, False: 78.4k]
  ------------------
  646|   621k|        candidate[i] = ckey[loc + 1];
  647|   621k|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  648|   621k|      }
  649|  12.2M|      do {
  650|  12.2M|        loc++;
  651|  12.2M|      } while ((loc < ckeyl) && ckey[loc] != tmpc);
  ------------------
  |  Branch (651:16): [True: 11.4M, False: 751k]
  |  Branch (651:33): [True: 11.4M, False: 16.6k]
  ------------------
  652|   767k|    }
  653|  5.07M|    candidate[i] = tmpc;
  654|  5.07M|  }
  655|   244k|  return wlst.size();
  656|   244k|}
_ZN10SuggestMgr14badcharkey_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
  662|   144k|                               int cpdsuggest, int& info) {
  663|   144k|  std::string candidate;
  664|   144k|  std::vector<w_char> candidate_utf(word);
  665|       |  // swap out each char one by one and try all the tryme
  666|       |  // chars in its place to see if that makes a good word
  667|  1.92M|  for (size_t i = 0, wl = word.size(); i < wl; ++i) {
  ------------------
  |  Branch (667:40): [True: 1.78M, False: 144k]
  ------------------
  668|  1.78M|    w_char tmpc = candidate_utf[i];
  669|       |    // check with uppercase letters
  670|  1.78M|    candidate_utf[i] = upper_utf(candidate_utf[i], 1);
  671|  1.78M|    if (tmpc != candidate_utf[i]) {
  ------------------
  |  Branch (671:9): [True: 390k, False: 1.39M]
  ------------------
  672|   390k|      u16_u8(candidate, candidate_utf);
  673|   390k|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  674|   390k|      candidate_utf[i] = tmpc;
  675|   390k|    }
  676|       |    // check neighbor characters in keyboard string
  677|  1.78M|    if (ckey_utf.empty())
  ------------------
  |  Branch (677:9): [True: 0, False: 1.78M]
  ------------------
  678|      0|      continue;
  679|  1.78M|    size_t loc = 0;
  680|  45.1M|    while ((loc < ckeyl) && ckey_utf[loc] != tmpc)
  ------------------
  |  Branch (680:12): [True: 43.7M, False: 1.38M]
  |  Branch (680:29): [True: 43.3M, False: 396k]
  ------------------
  681|  43.3M|      ++loc;
  682|  2.18M|    while (loc < ckeyl) {
  ------------------
  |  Branch (682:12): [True: 405k, False: 1.78M]
  ------------------
  683|   405k|      if ((loc > 0) && ckey_utf[loc - 1] != W_VLINE) {
  ------------------
  |  Branch (683:11): [True: 302k, False: 102k]
  |  Branch (683:24): [True: 302k, False: 0]
  ------------------
  684|   302k|        candidate_utf[i] = ckey_utf[loc - 1];
  685|   302k|        u16_u8(candidate, candidate_utf);
  686|   302k|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  687|   302k|      }
  688|   405k|      if (((loc + 1) < ckeyl) && (ckey_utf[loc + 1] != W_VLINE)) {
  ------------------
  |  Branch (688:11): [True: 357k, False: 47.5k]
  |  Branch (688:34): [True: 357k, False: 0]
  ------------------
  689|   357k|        candidate_utf[i] = ckey_utf[loc + 1];
  690|   357k|        u16_u8(candidate, candidate_utf);
  691|   357k|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  692|   357k|      }
  693|  6.54M|      do {
  694|  6.54M|        loc++;
  695|  6.54M|      } while ((loc < ckeyl) && ckey_utf[loc] != tmpc);
  ------------------
  |  Branch (695:16): [True: 6.15M, False: 396k]
  |  Branch (695:33): [True: 6.14M, False: 8.90k]
  ------------------
  696|   405k|    }
  697|  1.78M|    candidate_utf[i] = tmpc;
  698|  1.78M|  }
  699|   144k|  return wlst.size();
  700|   144k|}
_ZN10SuggestMgr7badcharERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  705|   244k|                               int cpdsuggest, int& info) {
  706|   244k|  std::string candidate(word);
  707|   244k|  std::chrono::steady_clock::time_point timelimit = std::chrono::steady_clock::now();
  708|   244k|  int timer = MINTIMER;
  ------------------
  |  |  107|   244k|#define MINTIMER 100
  ------------------
  709|       |  // swap out each char one by one and try all the tryme
  710|       |  // chars in its place to see if that makes a good word
  711|   244k|  for (size_t j = 0; j < ctryl; ++j) {
  ------------------
  |  Branch (711:22): [True: 0, False: 244k]
  ------------------
  712|      0|    for (auto aI = candidate.rbegin(), aEnd = candidate.rend(); aI != aEnd; ++aI) {
  ------------------
  |  Branch (712:65): [True: 0, False: 0]
  ------------------
  713|      0|      char tmpc = *aI;
  714|      0|      if (ctry[j] == tmpc)
  ------------------
  |  Branch (714:11): [True: 0, False: 0]
  ------------------
  715|      0|        continue;
  716|      0|      *aI = ctry[j];
  717|      0|      testsug(wlst, candidate, cpdsuggest, &timer, &timelimit, info);
  718|      0|      if (!timer)
  ------------------
  |  Branch (718:11): [True: 0, False: 0]
  ------------------
  719|      0|        return wlst.size();
  720|      0|      *aI = tmpc;
  721|      0|    }
  722|      0|  }
  723|   244k|  return wlst.size();
  724|   244k|}
_ZN10SuggestMgr11badchar_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
  729|   144k|                            int cpdsuggest, int& info) {
  730|   144k|  std::vector<w_char> candidate_utf(word);
  731|   144k|  std::string candidate;
  732|   144k|  std::chrono::steady_clock::time_point timelimit = std::chrono::steady_clock::now();
  733|   144k|  int timer = MINTIMER;
  ------------------
  |  |  107|   144k|#define MINTIMER 100
  ------------------
  734|       |  // swap out each char one by one and try all the tryme
  735|       |  // chars in its place to see if that makes a good word
  736|   161k|  for (size_t j = 0; j < ctryl; ++j) {
  ------------------
  |  Branch (736:22): [True: 17.4k, False: 144k]
  ------------------
  737|   230k|    for (auto aI = candidate_utf.rbegin(), aEnd = candidate_utf.rend(); aI != aEnd; ++aI) {
  ------------------
  |  Branch (737:73): [True: 213k, False: 17.4k]
  ------------------
  738|   213k|      w_char tmpc = *aI;
  739|   213k|      if (tmpc == ctry_utf[j])
  ------------------
  |  Branch (739:11): [True: 0, False: 213k]
  ------------------
  740|      0|        continue;
  741|   213k|      *aI = ctry_utf[j];
  742|   213k|      u16_u8(candidate, candidate_utf);
  743|   213k|      testsug(wlst, candidate, cpdsuggest, &timer, &timelimit, info);
  744|   213k|      if (!timer)
  ------------------
  |  Branch (744:11): [True: 0, False: 213k]
  ------------------
  745|      0|        return wlst.size();
  746|   213k|      *aI = tmpc;
  747|   213k|    }
  748|  17.4k|  }
  749|   144k|  return wlst.size();
  750|   144k|}
_ZN10SuggestMgr13extrachar_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
  755|   144k|                              int cpdsuggest, int& info) {
  756|   144k|  std::vector<w_char> candidate_utf(word);
  757|   144k|  if (candidate_utf.size() < 2)
  ------------------
  |  Branch (757:7): [True: 13.8k, False: 130k]
  ------------------
  758|  13.8k|    return wlst.size();
  759|       |  // try omitting one char of word at a time
  760|  1.90M|  for (size_t i = 0; i < candidate_utf.size(); ++i) {
  ------------------
  |  Branch (760:22): [True: 1.76M, False: 130k]
  ------------------
  761|  1.76M|    size_t index = candidate_utf.size() - 1 - i;
  762|  1.76M|    w_char tmpc = candidate_utf[index];
  763|  1.76M|    candidate_utf.erase(candidate_utf.begin() + index);
  764|  1.76M|    std::string candidate;
  765|  1.76M|    u16_u8(candidate, candidate_utf);
  766|  1.76M|    testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  767|  1.76M|    candidate_utf.insert(candidate_utf.begin() + index, tmpc);
  768|  1.76M|  }
  769|   130k|  return wlst.size();
  770|   144k|}
_ZN10SuggestMgr9extracharERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  775|   244k|                          int cpdsuggest, int& info) {
  776|   244k|  std::string candidate(word);
  777|   244k|  if (candidate.size() < 2)
  ------------------
  |  Branch (777:7): [True: 16.3k, False: 228k]
  ------------------
  778|  16.3k|    return wlst.size();
  779|       |  // try omitting one char of word at a time
  780|  5.29M|  for (size_t i = 0; i < candidate.size(); ++i) {
  ------------------
  |  Branch (780:22): [True: 5.06M, False: 228k]
  ------------------
  781|  5.06M|    size_t index = candidate.size() - 1 - i;
  782|  5.06M|    char tmpc = candidate[index];
  783|  5.06M|    candidate.erase(candidate.begin() + index);
  784|  5.06M|    testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  785|  5.06M|    candidate.insert(candidate.begin() + index, tmpc);
  786|  5.06M|  }
  787|   228k|  return wlst.size();
  788|   244k|}
_ZN10SuggestMgr10forgotcharERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  793|   244k|                           int cpdsuggest, int& info) {
  794|   244k|  std::string candidate(word);
  795|   244k|  std::chrono::steady_clock::time_point timelimit = std::chrono::steady_clock::now();
  796|   244k|  int timer = MINTIMER;
  ------------------
  |  |  107|   244k|#define MINTIMER 100
  ------------------
  797|       |
  798|       |  // try inserting a tryme character before every letter (and the null
  799|       |  // terminator)
  800|   244k|  for (size_t k = 0; k < ctryl; ++k) {
  ------------------
  |  Branch (800:22): [True: 0, False: 244k]
  ------------------
  801|      0|    for (size_t i = 0; i <= candidate.size(); ++i) {
  ------------------
  |  Branch (801:24): [True: 0, False: 0]
  ------------------
  802|      0|      size_t index = candidate.size() - i;
  803|      0|      candidate.insert(candidate.begin() + index, ctry[k]);
  804|      0|      testsug(wlst, candidate, cpdsuggest, &timer, &timelimit, info);
  805|      0|      if (!timer)
  ------------------
  |  Branch (805:11): [True: 0, False: 0]
  ------------------
  806|      0|        return wlst.size();
  807|      0|      candidate.erase(candidate.begin() + index);
  808|      0|    }
  809|      0|  }
  810|   244k|  return wlst.size();
  811|   244k|}
_ZN10SuggestMgr14forgotchar_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
  816|   144k|                               int cpdsuggest, int& info) {
  817|   144k|  std::vector<w_char> candidate_utf(word);
  818|   144k|  std::chrono::steady_clock::time_point timelimit = std::chrono::steady_clock::now();
  819|   144k|  int timer = MINTIMER;
  ------------------
  |  |  107|   144k|#define MINTIMER 100
  ------------------
  820|       |
  821|       |  // try inserting a tryme character at the end of the word and before every
  822|       |  // letter
  823|   161k|  for (size_t k = 0; k < ctryl; ++k) {
  ------------------
  |  Branch (823:22): [True: 17.4k, False: 144k]
  ------------------
  824|   248k|    for (size_t i = 0; i <= candidate_utf.size(); ++i) {
  ------------------
  |  Branch (824:24): [True: 230k, False: 17.4k]
  ------------------
  825|   230k|      size_t index = candidate_utf.size() - i;
  826|   230k|      candidate_utf.insert(candidate_utf.begin() + index, ctry_utf[k]);
  827|   230k|      std::string candidate;
  828|   230k|      u16_u8(candidate, candidate_utf);
  829|   230k|      testsug(wlst, candidate, cpdsuggest, &timer, &timelimit, info);
  830|   230k|      if (!timer)
  ------------------
  |  Branch (830:11): [True: 0, False: 230k]
  ------------------
  831|      0|        return wlst.size();
  832|   230k|      candidate_utf.erase(candidate_utf.begin() + index);
  833|   230k|    }
  834|  17.4k|  }
  835|   144k|  return wlst.size();
  836|   144k|}
_ZN10SuggestMgr8twowordsERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_ibRi:
  846|   389k|                         bool good, int& info) {
  847|   389k|  int c2, forbidden = 0, cwrd, wl = word.size();
  848|   389k|  if (wl < 3)
  ------------------
  |  Branch (848:7): [True: 50.9k, False: 338k]
  ------------------
  849|  50.9k|    return false;
  850|       |
  851|   338k|  if (langnum == LANG_hu)
  ------------------
  |  Branch (851:7): [True: 13.5k, False: 324k]
  ------------------
  852|  13.5k|    forbidden = check_forbidden(word);
  853|       |
  854|   338k|  char* candidate = new char[wl + 2];
  855|   338k|  memcpy(candidate + 1, word.data(), wl);
  856|   338k|  candidate[wl + 1] = 0;
  857|       |
  858|       |  // split the string into two pieces after every char
  859|       |  // if both pieces are good words make them a suggestion
  860|  4.37M|  for (char* p = candidate + 1; p[1] != '\0'; p++) {
  ------------------
  |  Branch (860:33): [True: 4.07M, False: 303k]
  ------------------
  861|  4.07M|    p[-1] = *p;
  862|       |    // go to end of the UTF-8 character
  863|  4.33M|    while (utf8 && is_utf8_cont(p[1])) {
  ------------------
  |  Branch (863:12): [True: 1.42M, False: 2.90M]
  |  Branch (863:20): [True: 261k, False: 1.16M]
  ------------------
  864|   261k|      *p = p[1];
  865|   261k|      p++;
  866|   261k|    }
  867|  4.07M|    if (utf8 && p[1] == '\0')
  ------------------
  |  Branch (867:9): [True: 1.16M, False: 2.90M]
  |  Branch (867:17): [True: 34.4k, False: 1.12M]
  ------------------
  868|  34.4k|      break;  // last UTF-8 character
  869|       |
  870|       |    // Suggest only word pairs, if they are listed in the dictionary.
  871|       |    // For example, adding "a lot" to the English dic file will
  872|       |    // result only "alot" -> "a lot" suggestion instead of
  873|       |    // "alto, slot, alt, lot, allot, aloft, aloe, clot, plot, blot, a lot".
  874|       |    // Note: using "ph:alot" keeps the other suggestions:
  875|       |    // a lot ph:alot
  876|       |    // alot -> a lot, alto, slot...
  877|  4.03M|    *p = ' ';
  878|  4.03M|    if (!cpdsuggest && checkword(candidate, cpdsuggest, nullptr, nullptr)) {
  ------------------
  |  Branch (878:9): [True: 1.34M, False: 2.68M]
  |  Branch (878:9): [True: 1.44k, False: 4.03M]
  |  Branch (878:24): [True: 1.44k, False: 1.34M]
  ------------------
  879|       |      // best solution
  880|  1.44k|      info |= SPELL_BEST_SUG;
  ------------------
  |  |   86|  1.44k|#define SPELL_BEST_SUG (1 << 8)    // limit suggestions for the best ones, i.e. ph:
  ------------------
  881|       |
  882|       |      // remove not word pair suggestions
  883|  1.44k|      if (!good) {
  ------------------
  |  Branch (883:11): [True: 126, False: 1.32k]
  ------------------
  884|    126|        good = true;
  885|    126|        wlst.clear();
  886|    126|      }
  887|       |
  888|  1.44k|      wlst.insert(wlst.begin(), candidate);
  889|  1.44k|    }
  890|       |
  891|       |    // word pairs with dash?
  892|  4.03M|    if (lang_with_dash_usage) {
  ------------------
  |  Branch (892:9): [True: 0, False: 4.03M]
  ------------------
  893|      0|      *p = '-';
  894|       |
  895|      0|      if (!cpdsuggest && checkword(candidate, cpdsuggest, nullptr, nullptr)) {
  ------------------
  |  Branch (895:11): [True: 0, False: 0]
  |  Branch (895:11): [True: 0, False: 0]
  |  Branch (895:26): [True: 0, False: 0]
  ------------------
  896|       |        // best solution
  897|      0|        info |= SPELL_BEST_SUG;
  ------------------
  |  |   86|      0|#define SPELL_BEST_SUG (1 << 8)    // limit suggestions for the best ones, i.e. ph:
  ------------------
  898|       |
  899|       |        // remove not word pair suggestions
  900|      0|        if (!good) {
  ------------------
  |  Branch (900:13): [True: 0, False: 0]
  ------------------
  901|      0|          good = true;
  902|      0|          wlst.clear();
  903|      0|        }
  904|      0|        wlst.insert(wlst.begin(), candidate);
  905|      0|      }
  906|      0|    }
  907|       |
  908|  4.03M|    if (wlst.size() < maxSug && !nosplitsugs && !good) {
  ------------------
  |  Branch (908:9): [True: 4.03M, False: 640]
  |  Branch (908:33): [True: 4.03M, False: 0]
  |  Branch (908:49): [True: 4.03M, False: 808]
  ------------------
  909|  4.03M|      *p = '\0';
  910|  4.03M|      int c1 = checkword(candidate, cpdsuggest, nullptr, nullptr);
  911|  4.03M|      if (c1) {
  ------------------
  |  Branch (911:11): [True: 21.0k, False: 4.01M]
  ------------------
  912|  21.0k|        c2 = checkword((p + 1), cpdsuggest, nullptr, nullptr);
  913|  21.0k|        if (c2) {
  ------------------
  |  Branch (913:13): [True: 729, False: 20.3k]
  ------------------
  914|       |          // spec. Hungarian code (TODO need a better compound word support)
  915|    729|          if ((langnum == LANG_hu) && !forbidden &&
  ------------------
  |  Branch (915:15): [True: 17, False: 712]
  |  Branch (915:39): [True: 17, False: 0]
  ------------------
  916|       |              // if 3 repeating letter, use - instead of space
  917|     17|              (((p[-1] == p[1]) &&
  ------------------
  |  Branch (917:17): [True: 7, False: 10]
  ------------------
  918|      7|              (((p > candidate + 1) && (p[-1] == p[-2])) || (p[-1] == p[2]))) ||
  ------------------
  |  Branch (918:17): [True: 1, False: 6]
  |  Branch (918:40): [True: 0, False: 1]
  |  Branch (918:61): [True: 0, False: 7]
  ------------------
  919|       |              // or multiple compounding, with more, than 6 syllables
  920|     17|              ((c1 == 3) && (c2 >= 2))))
  ------------------
  |  Branch (920:16): [True: 0, False: 17]
  |  Branch (920:29): [True: 0, False: 0]
  ------------------
  921|      0|            *p = '-';
  922|    729|          else
  923|    729|            *p = ' ';
  924|       |
  925|    729|          cwrd = std::find(wlst.begin(), wlst.end(), candidate) != wlst.end() ? 0 : 1;
  ------------------
  |  Branch (925:18): [True: 17, False: 712]
  ------------------
  926|       |
  927|    729|          if (cwrd && (wlst.size() < maxSug))
  ------------------
  |  Branch (927:15): [True: 712, False: 17]
  |  Branch (927:23): [True: 712, False: 0]
  ------------------
  928|    712|              wlst.emplace_back(candidate);
  929|       |
  930|       |          // add two word suggestion with dash, depending on the language
  931|       |          // Note that cwrd doesn't modified for REP twoword sugg.
  932|    729|          if ( !nosplitsugs && lang_with_dash_usage &&
  ------------------
  |  Branch (932:16): [True: 729, False: 0]
  |  Branch (932:32): [True: 0, False: 729]
  ------------------
  933|      0|              mystrlen(p + 1) > 1 && mystrlen(candidate) - mystrlen(p) > 1) {
  ------------------
  |  Branch (933:15): [True: 0, False: 0]
  |  Branch (933:38): [True: 0, False: 0]
  ------------------
  934|      0|            *p = '-';
  935|      0|            for (auto& k : wlst) {
  ------------------
  |  Branch (935:26): [True: 0, False: 0]
  ------------------
  936|      0|              if (k == candidate) {
  ------------------
  |  Branch (936:19): [True: 0, False: 0]
  ------------------
  937|      0|                cwrd = 0;
  938|      0|                break;
  939|      0|              }
  940|      0|            }
  941|       |
  942|      0|            if ((wlst.size() < maxSug) && cwrd)
  ------------------
  |  Branch (942:17): [True: 0, False: 0]
  |  Branch (942:43): [True: 0, False: 0]
  ------------------
  943|      0|              wlst.emplace_back(candidate);
  944|      0|          }
  945|    729|        }
  946|  21.0k|      }
  947|  4.03M|    }
  948|  4.03M|  }
  949|   338k|  delete[] candidate;
  950|   338k|  return good;
  951|   389k|}
_ZN10SuggestMgr8swapcharERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
  956|   244k|                         int cpdsuggest, int& info) {
  957|   244k|  if (word.size() < 2)
  ------------------
  |  Branch (957:7): [True: 16.3k, False: 228k]
  ------------------
  958|  16.3k|    return wlst.size();
  959|       |
  960|   228k|  std::string candidate(word);
  961|       |
  962|       |  // try swapping adjacent chars one by one
  963|  5.06M|  for (size_t i = 0; i < candidate.size() - 1; ++i) {
  ------------------
  |  Branch (963:22): [True: 4.83M, False: 228k]
  ------------------
  964|  4.83M|    std::swap(candidate[i], candidate[i+1]);
  965|  4.83M|    testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  966|  4.83M|    std::swap(candidate[i], candidate[i+1]);
  967|  4.83M|  }
  968|       |
  969|       |  // try double swaps for short words
  970|       |  // ahev -> have, owudl -> would
  971|   228k|  if (candidate.size() == 4 || candidate.size() == 5) {
  ------------------
  |  Branch (971:7): [True: 15.8k, False: 212k]
  |  Branch (971:32): [True: 9.66k, False: 202k]
  ------------------
  972|  25.4k|    candidate[0] = word[1];
  973|  25.4k|    candidate[1] = word[0];
  974|  25.4k|    candidate[2] = word[2];
  975|  25.4k|    candidate[candidate.size() - 2] = word[candidate.size() - 1];
  976|  25.4k|    candidate[candidate.size() - 1] = word[candidate.size() - 2];
  977|  25.4k|    testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  978|  25.4k|    if (candidate.size() == 5) {
  ------------------
  |  Branch (978:9): [True: 9.66k, False: 15.8k]
  ------------------
  979|  9.66k|      candidate[0] = word[0];
  980|  9.66k|      candidate[1] = word[2];
  981|  9.66k|      candidate[2] = word[1];
  982|  9.66k|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
  983|  9.66k|    }
  984|  25.4k|  }
  985|       |
  986|   228k|  return wlst.size();
  987|   244k|}
_ZN10SuggestMgr12swapchar_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
  992|   144k|                             int cpdsuggest, int& info) {
  993|   144k|  if (word.size() < 2)
  ------------------
  |  Branch (993:7): [True: 13.8k, False: 130k]
  ------------------
  994|  13.8k|    return wlst.size();
  995|       |
  996|   130k|  std::vector<w_char> candidate_utf(word);
  997|       |
  998|   130k|  std::string candidate;
  999|       |  // try swapping adjacent chars one by one
 1000|  1.76M|  for (size_t i = 0; i < candidate_utf.size() - 1; ++i) {
  ------------------
  |  Branch (1000:22): [True: 1.63M, False: 130k]
  ------------------
 1001|  1.63M|    if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|  1.63M|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (1001:9): [True: 0, False: 1.63M]
  ------------------
 1002|      0|      return wlst.size();
 1003|  1.63M|    std::swap(candidate_utf[i], candidate_utf[i+1]);
 1004|  1.63M|    u16_u8(candidate, candidate_utf);
 1005|  1.63M|    testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1006|  1.63M|    std::swap(candidate_utf[i], candidate_utf[i+1]);
 1007|  1.63M|  }
 1008|       |
 1009|       |  // try double swaps for short words
 1010|       |  // ahev -> have, owudl -> would, suodn -> sound
 1011|   130k|  if (candidate_utf.size() == 4 || candidate_utf.size() == 5) {
  ------------------
  |  Branch (1011:7): [True: 17.6k, False: 113k]
  |  Branch (1011:36): [True: 8.12k, False: 104k]
  ------------------
 1012|  25.7k|    candidate_utf[0] = word[1];
 1013|  25.7k|    candidate_utf[1] = word[0];
 1014|  25.7k|    candidate_utf[2] = word[2];
 1015|  25.7k|    candidate_utf[candidate_utf.size() - 2] = word[candidate_utf.size() - 1];
 1016|  25.7k|    candidate_utf[candidate_utf.size() - 1] = word[candidate_utf.size() - 2];
 1017|  25.7k|    u16_u8(candidate, candidate_utf);
 1018|  25.7k|    testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1019|  25.7k|    if (candidate_utf.size() == 5) {
  ------------------
  |  Branch (1019:9): [True: 8.12k, False: 17.6k]
  ------------------
 1020|  8.12k|      candidate_utf[0] = word[0];
 1021|  8.12k|      candidate_utf[1] = word[2];
 1022|  8.12k|      candidate_utf[2] = word[1];
 1023|  8.12k|      u16_u8(candidate, candidate_utf);
 1024|  8.12k|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1025|  8.12k|    }
 1026|  25.7k|  }
 1027|   130k|  return wlst.size();
 1028|   130k|}
_ZN10SuggestMgr12longswapcharERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
 1033|   244k|                             int cpdsuggest, int& info) {
 1034|   244k|  std::string candidate(word);
 1035|       |  // try swapping not adjacent chars one by one
 1036|  5.32M|  for (auto p = candidate.begin(); p < candidate.end(); ++p) {
  ------------------
  |  Branch (1036:36): [True: 5.07M, False: 244k]
  ------------------
 1037|   188M|    for (auto q = candidate.begin(); q < candidate.end(); ++q) {
  ------------------
  |  Branch (1037:38): [True: 183M, False: 5.07M]
  ------------------
 1038|   183M|      const auto distance = std::abs(std::distance(q, p));
 1039|   183M|      if (distance > 1 && distance <= MAX_CHAR_DISTANCE && *p != *q) {
  ------------------
  |  |   84|   352M|#define MAX_CHAR_DISTANCE 4
  ------------------
  |  Branch (1039:11): [True: 168M, False: 14.7M]
  |  Branch (1039:27): [True: 26.3M, False: 142M]
  |  Branch (1039:60): [True: 19.9M, False: 6.37M]
  ------------------
 1040|  19.9M|        std::swap(*p, *q);
 1041|  19.9M|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1042|  19.9M|        std::swap(*p, *q);
 1043|  19.9M|      }
 1044|   183M|    }
 1045|  5.07M|  }
 1046|   244k|  return wlst.size();
 1047|   244k|}
_ZN10SuggestMgr16longswapchar_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
 1052|   144k|                                 int cpdsuggest, int& info) {
 1053|   144k|  std::vector<w_char> candidate_utf(word);
 1054|       |  // try swapping not adjacent chars
 1055|  1.92M|  for (auto p = candidate_utf.begin(); p < candidate_utf.end(); ++p) {
  ------------------
  |  Branch (1055:40): [True: 1.78M, False: 144k]
  ------------------
 1056|  51.1M|    for (auto q = candidate_utf.begin(); q < candidate_utf.end(); ++q) {
  ------------------
  |  Branch (1056:42): [True: 49.3M, False: 1.78M]
  ------------------
 1057|  49.3M|      const auto distance = std::abs(std::distance(q, p));
 1058|  49.3M|      if (distance > 1 && distance <= MAX_CHAR_DISTANCE && *p != *q) {
  ------------------
  |  |   84|  93.7M|#define MAX_CHAR_DISTANCE 4
  ------------------
  |  Branch (1058:11): [True: 44.3M, False: 5.06M]
  |  Branch (1058:27): [True: 8.35M, False: 35.9M]
  |  Branch (1058:60): [True: 5.78M, False: 2.56M]
  ------------------
 1059|  5.78M|        std::swap(*p, *q);
 1060|  5.78M|        std::string candidate;
 1061|  5.78M|        u16_u8(candidate, candidate_utf);
 1062|  5.78M|        testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1063|  5.78M|        std::swap(*p, *q);
 1064|  5.78M|      }
 1065|  49.3M|    }
 1066|  1.78M|  }
 1067|   144k|  return wlst.size();
 1068|   144k|}
_ZN10SuggestMgr8movecharERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_iRi:
 1073|   244k|                         int cpdsuggest, int& info) {
 1074|   244k|  if (word.size() < 2)
  ------------------
  |  Branch (1074:7): [True: 16.3k, False: 228k]
  ------------------
 1075|  16.3k|    return wlst.size();
 1076|       |
 1077|   228k|  std::string candidate(word);
 1078|       |
 1079|       |  // try moving a char
 1080|  5.29M|  for (auto p = candidate.begin(); p < candidate.end(); ++p) {
  ------------------
  |  Branch (1080:36): [True: 5.06M, False: 228k]
  ------------------
 1081|  23.0M|    for (auto q = p + 1; q < candidate.end() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
  ------------------
  |  |   84|  22.0M|#define MAX_CHAR_DISTANCE 4
  ------------------
  |  Branch (1081:26): [True: 22.0M, False: 1.06M]
  |  Branch (1081:26): [True: 18.0M, False: 5.06M]
  |  Branch (1081:49): [True: 18.0M, False: 3.99M]
  ------------------
 1082|  18.0M|      std::swap(*q, *(q - 1));
 1083|  18.0M|      if (std::distance(p, q) < 2)
  ------------------
  |  Branch (1083:11): [True: 4.83M, False: 13.1M]
  ------------------
 1084|  4.83M|        continue;  // omit swap char
 1085|  13.1M|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1086|  13.1M|    }
 1087|  5.06M|    const auto word_iter = word.begin();
 1088|  5.06M|    std::copy_n(word_iter, candidate.size(), candidate.begin());
 1089|  5.06M|  }
 1090|       |
 1091|  5.06M|  for (auto p = candidate.rbegin(), pEnd = candidate.rend() - 1; p != pEnd; ++p) {
  ------------------
  |  Branch (1091:66): [True: 4.83M, False: 228k]
  ------------------
 1092|  22.8M|    for (auto q = p + 1, qEnd = candidate.rend(); q != qEnd && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
  ------------------
  |  |   84|  22.0M|#define MAX_CHAR_DISTANCE 4
  ------------------
  |  Branch (1092:51): [True: 22.0M, False: 838k]
  |  Branch (1092:64): [True: 18.0M, False: 3.99M]
  ------------------
 1093|  18.0M|      std::swap(*q, *(q - 1));
 1094|  18.0M|      if (std::distance(p, q) < 2)
  ------------------
  |  Branch (1094:11): [True: 4.83M, False: 13.1M]
  ------------------
 1095|  4.83M|        continue;  // omit swap char
 1096|  13.1M|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1097|  13.1M|    }
 1098|  4.83M|    const auto word_iter = word.begin();
 1099|  4.83M|    std::copy_n(word_iter, candidate.size(), candidate.begin());
 1100|  4.83M|  }
 1101|       |
 1102|   228k|  return wlst.size();
 1103|   244k|}
_ZN10SuggestMgr12movechar_utfERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKNS1_I6w_charNS5_ISB_EEEEiRi:
 1108|   144k|                             int cpdsuggest, int& info) {
 1109|   144k|  if (word.size() < 2)
  ------------------
  |  Branch (1109:7): [True: 13.8k, False: 130k]
  ------------------
 1110|  13.8k|    return wlst.size();
 1111|       |
 1112|   130k|  std::vector<w_char> candidate_utf(word);
 1113|       |
 1114|       |  // try moving a char
 1115|  1.90M|  for (auto p = candidate_utf.begin(); p < candidate_utf.end(); ++p) {
  ------------------
  |  Branch (1115:40): [True: 1.76M, False: 130k]
  ------------------
 1116|  7.58M|    for (auto q = p + 1; q < candidate_utf.end() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
  ------------------
  |  |   84|  7.00M|#define MAX_CHAR_DISTANCE 4
  ------------------
  |  Branch (1116:26): [True: 7.00M, False: 583k]
  |  Branch (1116:26): [True: 5.81M, False: 1.76M]
  |  Branch (1116:53): [True: 5.81M, False: 1.18M]
  ------------------
 1117|  5.81M|      std::swap(*q, *(q - 1));
 1118|  5.81M|      if (std::distance(p, q) < 2)
  ------------------
  |  Branch (1118:11): [True: 1.63M, False: 4.17M]
  ------------------
 1119|  1.63M|        continue;  // omit swap char
 1120|  4.17M|      std::string candidate;
 1121|  4.17M|      u16_u8(candidate, candidate_utf);
 1122|  4.17M|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1123|  4.17M|    }
 1124|  1.76M|    const auto word_iter = word.begin();
 1125|  1.76M|    std::copy_n(word_iter, candidate_utf.size(), candidate_utf.begin());
 1126|  1.76M|  }
 1127|       |
 1128|  1.90M|  for (auto p = candidate_utf.rbegin(); p < candidate_utf.rend(); ++p) {
  ------------------
  |  Branch (1128:41): [True: 1.76M, False: 130k]
  ------------------
 1129|  7.58M|    for (auto q = p + 1; q < candidate_utf.rend() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
  ------------------
  |  |   84|  7.00M|#define MAX_CHAR_DISTANCE 4
  ------------------
  |  Branch (1129:26): [True: 7.00M, False: 583k]
  |  Branch (1129:26): [True: 5.81M, False: 1.76M]
  |  Branch (1129:54): [True: 5.81M, False: 1.18M]
  ------------------
 1130|  5.81M|      std::swap(*q, *(q - 1));
 1131|  5.81M|      if (std::distance(p, q) < 2)
  ------------------
  |  Branch (1131:11): [True: 1.63M, False: 4.17M]
  ------------------
 1132|  1.63M|        continue;  // omit swap char
 1133|  4.17M|      std::string candidate;
 1134|  4.17M|      u16_u8(candidate, candidate_utf);
 1135|  4.17M|      testsug(wlst, candidate, cpdsuggest, nullptr, nullptr, info);
 1136|  4.17M|    }
 1137|  1.76M|    const auto word_iter = word.begin();
 1138|  1.76M|    std::copy_n(word_iter, candidate_utf.size(), candidate_utf.begin());
 1139|  1.76M|  }
 1140|       |
 1141|   130k|  return wlst.size();
 1142|   144k|}
_ZN10SuggestMgr9ngsuggestERNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEEPKcRKNS1_INS0_10unique_ptrI7HashMgrNS0_14default_deleteISE_EEEENS5_ISH_EEEEi:
 1177|  59.6k|                          int captype) {
 1178|  59.6k|  int lval, sc, lp, lpphon, nonbmp = 0;
 1179|       |
 1180|       |  // exhaustively search through all root words
 1181|       |  // keeping track of the MAX_ROOTS most similar root words
 1182|  59.6k|  struct hentry* roots[MAX_ROOTS];
 1183|  59.6k|  char* rootsphon[MAX_ROOTS];
 1184|  59.6k|  int scores[MAX_ROOTS];
 1185|  59.6k|  int scoresphon[MAX_ROOTS];
 1186|  6.02M|  for (int i = 0; i < MAX_ROOTS; i++) {
  ------------------
  |  |   74|  6.02M|#define MAX_ROOTS 100
  ------------------
  |  Branch (1186:19): [True: 5.96M, False: 59.6k]
  ------------------
 1187|  5.96M|    roots[i] = nullptr;
 1188|  5.96M|    scores[i] = -100 * i;
 1189|  5.96M|    rootsphon[i] = nullptr;
 1190|  5.96M|    scoresphon[i] = -100 * i;
 1191|  5.96M|  }
 1192|  59.6k|  bool has_roots = false;
 1193|  59.6k|  bool has_rootsphon = false;
 1194|  59.6k|  lp = MAX_ROOTS - 1;
  ------------------
  |  |   74|  59.6k|#define MAX_ROOTS 100
  ------------------
 1195|  59.6k|  lpphon = MAX_ROOTS - 1;
  ------------------
  |  |   74|  59.6k|#define MAX_ROOTS 100
  ------------------
 1196|  59.6k|  int low = NGRAM_LOWERING;
  ------------------
  |  |   83|  59.6k|#define NGRAM_LOWERING (1 << 2)
  ------------------
 1197|       |
 1198|  59.6k|  std::string w2;
 1199|  59.6k|  const char* word = w;
 1200|       |
 1201|  59.6k|  int nc;
 1202|       |  // word reversing wrapper for complex prefixes
 1203|  59.6k|  if (complexprefixes) {
  ------------------
  |  Branch (1203:7): [True: 3.40k, False: 56.2k]
  ------------------
 1204|  3.40k|    w2.assign(w);
 1205|  3.40k|    if (utf8)
  ------------------
  |  Branch (1205:9): [True: 0, False: 3.40k]
  ------------------
 1206|      0|      reverseword_utf(w2);
 1207|  3.40k|    else
 1208|  3.40k|      reverseword(w2);
 1209|  3.40k|    word = w2.c_str();
 1210|  3.40k|    nc = (int)w2.size();
 1211|  56.2k|  } else {
 1212|  56.2k|    nc = (int)strlen(word);
 1213|  56.2k|  }
 1214|       |
 1215|  59.6k|  std::vector<w_char> u8;
 1216|  59.6k|  int n = (utf8) ? u8_u16(u8, word) : nc;
  ------------------
  |  Branch (1216:11): [True: 24.9k, False: 34.7k]
  ------------------
 1217|       |
 1218|       |  // set character based ngram suggestion for words with non-BMP Unicode
 1219|       |  // characters
 1220|  59.6k|  const struct cs_info* origconv = csconv;
 1221|  59.6k|  if (n == -1) {
  ------------------
  |  Branch (1221:7): [True: 1.96k, False: 57.7k]
  ------------------
 1222|  1.96k|    utf8 = 0;  // XXX not state-free
 1223|  1.96k|    if (!csconv)
  ------------------
  |  Branch (1223:9): [True: 1.96k, False: 0]
  ------------------
 1224|  1.96k|      csconv = get_current_cs("iso88591"); // XXX not state-free
 1225|  1.96k|    n = nc;
 1226|  1.96k|    nonbmp = 1;
 1227|  1.96k|    low = 0;
 1228|  1.96k|  }
 1229|  59.6k|  ngsuggest_guard restore_state(nonbmp, origconv, &utf8, &csconv);
 1230|  59.6k|  int max_word_len = (utf8) ? MAXWORDUTF8LEN : MAXWORDLEN;
  ------------------
  |  |   85|  22.9k|#define MAXWORDUTF8LEN (MAXWORDLEN * 3)
  |  |  ------------------
  |  |  |  |   89|  22.9k|#define MAXWORDLEN 100
  |  |  ------------------
  ------------------
                int max_word_len = (utf8) ? MAXWORDUTF8LEN : MAXWORDLEN;
  ------------------
  |  |   89|  36.7k|#define MAXWORDLEN 100
  ------------------
  |  Branch (1230:22): [True: 22.9k, False: 36.7k]
  ------------------
 1231|       |  // ofz#59067 a replist entry can generate a very long word, abandon
 1232|       |  // ngram if that odd-edge case arises
 1233|  59.6k|  if (n > max_word_len * 4)
  ------------------
  |  Branch (1233:7): [True: 0, False: 59.6k]
  ------------------
 1234|      0|      return;
 1235|       |
 1236|  59.6k|  struct hentry* hp = nullptr;
 1237|  59.6k|  int col = -1;
 1238|  59.6k|  phonetable* ph = (pAMgr) ? pAMgr->get_phonetable() : nullptr;
  ------------------
  |  Branch (1238:20): [True: 59.6k, False: 0]
  ------------------
 1239|  59.6k|  std::string target;
 1240|  59.6k|  std::string candidate;
 1241|  59.6k|  std::vector<w_char> w_candidate;
 1242|  59.6k|  if (ph) {
  ------------------
  |  Branch (1242:7): [True: 3.40k, False: 56.2k]
  ------------------
 1243|  3.40k|    if (utf8) {
  ------------------
  |  Branch (1243:9): [True: 0, False: 3.40k]
  ------------------
 1244|      0|      u8_u16(w_candidate, word);
 1245|      0|      mkallcap_utf(w_candidate, langnum);
 1246|      0|      u16_u8(candidate, w_candidate);
 1247|  3.40k|    } else {
 1248|  3.40k|      candidate.assign(word);
 1249|  3.40k|      if (!nonbmp)
  ------------------
  |  Branch (1249:11): [True: 3.40k, False: 0]
  ------------------
 1250|  3.40k|        mkallcap(candidate, csconv);
 1251|  3.40k|    }
 1252|  3.40k|    target = phonet(candidate, *ph);  // XXX phonet() is 8-bit (nc, not n)
 1253|  3.40k|  }
 1254|       |
 1255|  59.6k|  FLAG forbiddenword = pAMgr ? pAMgr->get_forbiddenword() : FLAG_NULL;
  ------------------
  |  |   95|  59.6k|#define FLAG unsigned short
  ------------------
                FLAG forbiddenword = pAMgr ? pAMgr->get_forbiddenword() : FLAG_NULL;
  ------------------
  |  |   96|  59.6k|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1255:24): [True: 59.6k, False: 0]
  ------------------
 1256|  59.6k|  FLAG nosuggest = pAMgr ? pAMgr->get_nosuggest() : FLAG_NULL;
  ------------------
  |  |   95|  59.6k|#define FLAG unsigned short
  ------------------
                FLAG nosuggest = pAMgr ? pAMgr->get_nosuggest() : FLAG_NULL;
  ------------------
  |  |   96|  59.6k|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1256:20): [True: 59.6k, False: 0]
  ------------------
 1257|  59.6k|  FLAG nongramsuggest = pAMgr ? pAMgr->get_nongramsuggest() : FLAG_NULL;
  ------------------
  |  |   95|  59.6k|#define FLAG unsigned short
  ------------------
                FLAG nongramsuggest = pAMgr ? pAMgr->get_nongramsuggest() : FLAG_NULL;
  ------------------
  |  |   96|  59.6k|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1257:25): [True: 59.6k, False: 0]
  ------------------
 1258|  59.6k|  FLAG onlyincompound = pAMgr ? pAMgr->get_onlyincompound() : FLAG_NULL;
  ------------------
  |  |   95|  59.6k|#define FLAG unsigned short
  ------------------
                FLAG onlyincompound = pAMgr ? pAMgr->get_onlyincompound() : FLAG_NULL;
  ------------------
  |  |   96|  59.6k|#define FLAG_NULL 0x00
  ------------------
  |  Branch (1258:25): [True: 59.6k, False: 0]
  ------------------
 1259|       |
 1260|  59.6k|  std::vector<w_char> w_word, w_target;
 1261|  59.6k|  if (utf8) {
  ------------------
  |  Branch (1261:7): [True: 22.9k, False: 36.7k]
  ------------------
 1262|  22.9k|    u8_u16(w_word, word);
 1263|  22.9k|    u8_u16(w_target, target);
 1264|  22.9k|  }
 1265|       |
 1266|  59.6k|  std::string f;
 1267|  59.6k|  std::vector<w_char> w_f;
 1268|       |
 1269|  59.6k|  for (const auto& i : rHMgr) {
  ------------------
  |  Branch (1269:22): [True: 59.6k, False: 59.6k]
  ------------------
 1270|  1.97M|    while (nullptr != (hp = i->walk_hashtable(col, hp))) {
  ------------------
  |  Branch (1270:12): [True: 1.91M, False: 59.6k]
  ------------------
 1271|       |      // skip exceptions
 1272|  1.91M|      if (
 1273|       |           // skip it, if the word length different by 5 or
 1274|       |           // more characters (to avoid strange suggestions)
 1275|       |           // (except Unicode characters over BMP)
 1276|  1.91M|           (((abs(n - hp->clen) > 4) && !nonbmp)) ||
  ------------------
  |  Branch (1276:12): [True: 1.32M, False: 584k]
  |  Branch (1276:14): [True: 1.20M, False: 709k]
  |  Branch (1276:41): [True: 1.14M, False: 59.0k]
  ------------------
 1277|       |           // don't suggest capitalized dictionary words for
 1278|       |           // lower case misspellings in ngram suggestions, except
 1279|       |           // - PHONE usage, or
 1280|       |           // - in the case of German, where not only proper
 1281|       |           //   nouns are capitalized, or
 1282|       |           // - the capitalized word has special pronunciation
 1283|   768k|           ((captype == NOCAP) && (hp->var & H_OPT_INITCAP) &&
  ------------------
  |  |   92|   768k|#define NOCAP 0
  ------------------
                         ((captype == NOCAP) && (hp->var & H_OPT_INITCAP) &&
  ------------------
  |  |   50|   192k|#define H_OPT_INITCAP (1 << 3)  // is dictionary word capitalized?
  ------------------
  |  Branch (1283:13): [True: 192k, False: 576k]
  |  Branch (1283:35): [True: 89.5k, False: 102k]
  ------------------
 1284|  89.5k|              !ph && (langnum != LANG_de) && !(hp->var & H_OPT_PHON)) ||
  ------------------
  |  |   49|  87.4k|#define H_OPT_PHON (1 << 2)     // is there ph: field in the morphological data?
  ------------------
  |  Branch (1284:15): [True: 87.4k, False: 2.15k]
  |  Branch (1284:22): [True: 87.4k, False: 0]
  |  Branch (1284:46): [True: 87.4k, False: 0]
  ------------------
 1285|       |           // or it has one of the following special flags
 1286|   681k|           ((hp->astr) && (pAMgr) &&
  ------------------
  |  Branch (1286:13): [True: 192k, False: 489k]
  |  Branch (1286:27): [True: 192k, False: 0]
  ------------------
 1287|   192k|             (TESTAFF(hp->astr, forbiddenword, hp->alen) ||
  ------------------
  |  |   99|   384k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 2.07k, False: 190k]
  |  |  ------------------
  ------------------
 1288|   190k|             TESTAFF(hp->astr, ONLYUPCASEFLAG, hp->alen) ||
  ------------------
  |  |   99|   382k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 95.3k, False: 94.8k]
  |  |  ------------------
  ------------------
 1289|  94.8k|             TESTAFF(hp->astr, nosuggest, hp->alen) ||
  ------------------
  |  |   99|   287k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 94.8k]
  |  |  ------------------
  ------------------
 1290|  94.8k|             TESTAFF(hp->astr, nongramsuggest, hp->alen) ||
  ------------------
  |  |   99|   287k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 94.8k]
  |  |  ------------------
  ------------------
 1291|  94.8k|             TESTAFF(hp->astr, onlyincompound, hp->alen)))
  ------------------
  |  |   99|  94.8k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 94.8k]
  |  |  ------------------
  ------------------
 1292|  1.91M|         )
 1293|  1.32M|        continue;
 1294|       |
 1295|   584k|      if (utf8) {
  ------------------
  |  Branch (1295:11): [True: 248k, False: 335k]
  ------------------
 1296|   248k|        u8_u16(w_f, HENTRY_WORD(hp));
  ------------------
  |  |   54|   248k|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1297|       |
 1298|   248k|        int leftcommon = leftcommonsubstring(w_word, w_f);
 1299|   248k|        if (low) {
  ------------------
  |  Branch (1299:13): [True: 248k, False: 0]
  ------------------
 1300|       |          // lowering dictionary word
 1301|   248k|          mkallsmall_utf(w_f, langnum);
 1302|   248k|        }
 1303|   248k|        sc = ngram(3, w_word, w_f, NGRAM_LONGER_WORSE) + leftcommon;
  ------------------
  |  |   81|   248k|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
 1304|   335k|      } else {
 1305|   335k|        f.assign(HENTRY_WORD(hp));
  ------------------
  |  |   54|   335k|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1306|       |
 1307|   335k|        int leftcommon = leftcommonsubstring(word, f.c_str());
 1308|   335k|        if (low) {
  ------------------
  |  Branch (1308:13): [True: 310k, False: 25.0k]
  ------------------
 1309|       |          // lowering dictionary word
 1310|   310k|          mkallsmall(f, csconv);
 1311|   310k|        }
 1312|   335k|        sc = ngram(3, word, f, NGRAM_LONGER_WORSE) + leftcommon;
  ------------------
  |  |   81|   335k|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
 1313|   335k|      }
 1314|       |
 1315|       |      // check special pronunciation
 1316|   584k|      f.clear();
 1317|   584k|      if ((hp->var & H_OPT_PHON) &&
  ------------------
  |  |   49|   584k|#define H_OPT_PHON (1 << 2)     // is there ph: field in the morphological data?
  ------------------
  |  Branch (1317:11): [True: 754, False: 583k]
  |  Branch (1317:11): [True: 754, False: 583k]
  ------------------
 1318|    754|          copy_field(f, HENTRY_DATA(hp), MORPH_PHON)) {
  ------------------
  |  |  114|    754|#define MORPH_PHON "ph:"
  ------------------
  |  Branch (1318:11): [True: 754, False: 0]
  ------------------
 1319|    754|        int sc2;
 1320|    754|        if (utf8) {
  ------------------
  |  Branch (1320:13): [True: 0, False: 754]
  ------------------
 1321|      0|          u8_u16(w_f, f);
 1322|       |
 1323|      0|          int leftcommon = leftcommonsubstring(w_word, w_f);
 1324|      0|          if (low) {
  ------------------
  |  Branch (1324:15): [True: 0, False: 0]
  ------------------
 1325|       |            // lowering dictionary word
 1326|      0|            mkallsmall_utf(w_f, langnum);
 1327|      0|          }
 1328|      0|          sc2 = ngram(3, w_word, w_f, NGRAM_LONGER_WORSE) + leftcommon;
  ------------------
  |  |   81|      0|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
 1329|    754|        } else {
 1330|    754|          int leftcommon = leftcommonsubstring(word, f.c_str());
 1331|    754|          if (low) {
  ------------------
  |  Branch (1331:15): [True: 754, False: 0]
  ------------------
 1332|       |            // lowering dictionary word
 1333|    754|            mkallsmall(f, csconv);
 1334|    754|          }
 1335|    754|          sc2 = ngram(3, word, f, NGRAM_LONGER_WORSE) + leftcommon;
  ------------------
  |  |   81|    754|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
 1336|    754|        }
 1337|    754|        if (sc2 > sc)
  ------------------
  |  Branch (1337:13): [True: 387, False: 367]
  ------------------
 1338|    387|          sc = sc2;
 1339|    754|      }
 1340|       |
 1341|   584k|      int scphon = -20000;
 1342|   584k|      if (ph && (sc > 2) && (abs(n - (int)hp->clen) <= 3)) {
  ------------------
  |  Branch (1342:11): [True: 35.0k, False: 548k]
  |  Branch (1342:17): [True: 8.31k, False: 26.7k]
  |  Branch (1342:29): [True: 7.09k, False: 1.22k]
  ------------------
 1343|  7.09k|        if (utf8) {
  ------------------
  |  Branch (1343:13): [True: 0, False: 7.09k]
  ------------------
 1344|      0|          u8_u16(w_candidate, HENTRY_WORD(hp));
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1345|      0|          mkallcap_utf(w_candidate, langnum);
 1346|      0|          u16_u8(candidate, w_candidate);
 1347|  7.09k|        } else {
 1348|  7.09k|          candidate = HENTRY_WORD(hp);
  ------------------
  |  |   54|  7.09k|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1349|  7.09k|          mkallcap(candidate, csconv);
 1350|  7.09k|        }
 1351|  7.09k|        f = phonet(candidate, *ph);
 1352|  7.09k|        if (utf8) {
  ------------------
  |  Branch (1352:13): [True: 0, False: 7.09k]
  ------------------
 1353|      0|          u8_u16(w_f, f);
 1354|      0|          scphon = 2 * ngram(3, w_target, w_f,
 1355|      0|                             NGRAM_LONGER_WORSE);
  ------------------
  |  |   81|      0|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
 1356|  7.09k|        } else {
 1357|  7.09k|          scphon = 2 * ngram(3, target, f,
 1358|  7.09k|                             NGRAM_LONGER_WORSE);
  ------------------
  |  |   81|  7.09k|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
 1359|  7.09k|        }
 1360|  7.09k|      }
 1361|       |
 1362|   584k|      if (sc > scores[lp]) {
  ------------------
  |  Branch (1362:11): [True: 584k, False: 0]
  ------------------
 1363|   584k|        scores[lp] = sc;
 1364|   584k|        roots[lp] = hp;
 1365|   584k|        has_roots = true;
 1366|   584k|        lval = sc;
 1367|  58.9M|        for (int j = 0; j < MAX_ROOTS; j++)
  ------------------
  |  |   74|  58.9M|#define MAX_ROOTS 100
  ------------------
  |  Branch (1367:25): [True: 58.4M, False: 584k]
  ------------------
 1368|  58.4M|          if (scores[j] < lval) {
  ------------------
  |  Branch (1368:15): [True: 48.5M, False: 9.82M]
  ------------------
 1369|  48.5M|            lp = j;
 1370|  48.5M|            lval = scores[j];
 1371|  48.5M|          }
 1372|   584k|      }
 1373|       |
 1374|   584k|      if (scphon > scoresphon[lpphon]) {
  ------------------
  |  Branch (1374:11): [True: 7.09k, False: 576k]
  ------------------
 1375|  7.09k|        scoresphon[lpphon] = scphon;
 1376|  7.09k|        rootsphon[lpphon] = HENTRY_WORD(hp);
  ------------------
  |  |   54|  7.09k|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1377|  7.09k|        has_rootsphon = true;
 1378|  7.09k|        lval = scphon;
 1379|   716k|        for (int j = 0; j < MAX_ROOTS; j++)
  ------------------
  |  |   74|   716k|#define MAX_ROOTS 100
  ------------------
  |  Branch (1379:25): [True: 709k, False: 7.09k]
  ------------------
 1380|   709k|          if (scoresphon[j] < lval) {
  ------------------
  |  Branch (1380:15): [True: 627k, False: 81.8k]
  ------------------
 1381|   627k|            lpphon = j;
 1382|   627k|            lval = scoresphon[j];
 1383|   627k|          }
 1384|  7.09k|      }
 1385|   584k|    }
 1386|  59.6k|  }
 1387|       |
 1388|  59.6k|  if (!has_roots && !has_rootsphon) {
  ------------------
  |  Branch (1388:7): [True: 13.4k, False: 46.1k]
  |  Branch (1388:21): [True: 13.4k, False: 0]
  ------------------
 1389|       |    // with no roots there will be no guesses and no point running
 1390|       |    // ngram
 1391|  13.4k|    return;
 1392|  13.4k|  }
 1393|       |
 1394|       |  // find minimum threshold for a passable suggestion
 1395|       |  // mangle original word three differnt ways
 1396|       |  // and score them to generate a minimum acceptable score
 1397|  46.1k|  std::vector<w_char> w_mw;
 1398|  46.1k|  int thresh = 0;
 1399|   184k|  for (int sp = 1; sp < 4; sp++) {
  ------------------
  |  Branch (1399:20): [True: 138k, False: 46.1k]
  ------------------
 1400|   138k|    if (utf8) {
  ------------------
  |  Branch (1400:9): [True: 55.8k, False: 82.7k]
  ------------------
 1401|  55.8k|      w_mw = w_word;
 1402|   102k|      for (int k = sp; k < n; k += 4) {
  ------------------
  |  Branch (1402:24): [True: 46.2k, False: 55.8k]
  ------------------
 1403|  46.2k|        w_mw[k].l = '*';
 1404|  46.2k|        w_mw[k].h = 0;
 1405|  46.2k|      }
 1406|       |
 1407|  55.8k|      if (low) {
  ------------------
  |  Branch (1407:11): [True: 55.8k, False: 0]
  ------------------
 1408|       |        // lowering dictionary word
 1409|  55.8k|        mkallsmall_utf(w_mw, langnum);
 1410|  55.8k|      }
 1411|       |
 1412|  55.8k|      thresh += ngram(n, w_word, w_mw, NGRAM_ANY_MISMATCH);
  ------------------
  |  |   82|  55.8k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
 1413|  82.7k|    } else {
 1414|  82.7k|      std::string mw = word;
 1415|   192k|      for (int k = sp; k < n; k += 4)
  ------------------
  |  Branch (1415:24): [True: 109k, False: 82.7k]
  ------------------
 1416|   109k|        mw[k] = '*';
 1417|       |
 1418|  82.7k|      if (low) {
  ------------------
  |  Branch (1418:11): [True: 76.8k, False: 5.88k]
  ------------------
 1419|       |        // lowering dictionary word
 1420|  76.8k|        mkallsmall(mw, csconv);
 1421|  76.8k|      }
 1422|       |
 1423|  82.7k|      thresh += ngram(n, word, mw, NGRAM_ANY_MISMATCH);
  ------------------
  |  |   82|  82.7k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
 1424|  82.7k|    }
 1425|   138k|  }
 1426|  46.1k|  thresh = thresh / 3;
 1427|  46.1k|  thresh--;
 1428|       |
 1429|       |  // now expand affixes on each of these root words and
 1430|       |  // and use length adjusted ngram scores to select
 1431|       |  // possible suggestions
 1432|  46.1k|  char* guess[MAX_GUESS];
 1433|  46.1k|  char* guessorig[MAX_GUESS];
 1434|  46.1k|  int gscore[MAX_GUESS];
 1435|  9.28M|  for (int i = 0; i < MAX_GUESS; i++) {
  ------------------
  |  |   76|  9.28M|#define MAX_GUESS 200
  ------------------
  |  Branch (1435:19): [True: 9.23M, False: 46.1k]
  ------------------
 1436|  9.23M|    guess[i] = nullptr;
 1437|  9.23M|    guessorig[i] = nullptr;
 1438|  9.23M|    gscore[i] = -100 * i;
 1439|  9.23M|  }
 1440|       |
 1441|  46.1k|  lp = MAX_GUESS - 1;
  ------------------
  |  |   76|  46.1k|#define MAX_GUESS 200
  ------------------
 1442|       |
 1443|  46.1k|  std::vector<guessword> glst(MAX_WORDS);
  ------------------
  |  |   75|  46.1k|#define MAX_WORDS 100
  ------------------
 1444|       |
 1445|  4.61M|  for (auto& root : roots) {
  ------------------
  |  Branch (1445:19): [True: 4.61M, False: 46.1k]
  ------------------
 1446|  4.61M|    if (root) {
  ------------------
  |  Branch (1446:9): [True: 584k, False: 4.03M]
  ------------------
 1447|   584k|      struct hentry* rp = root;
 1448|       |
 1449|   584k|      f.clear();
 1450|   584k|      const char* field = nullptr;
 1451|   584k|      if ((rp->var & H_OPT_PHON) && copy_field(f, HENTRY_DATA(rp), MORPH_PHON))
  ------------------
  |  |   49|   584k|#define H_OPT_PHON (1 << 2)     // is there ph: field in the morphological data?
  ------------------
                    if ((rp->var & H_OPT_PHON) && copy_field(f, HENTRY_DATA(rp), MORPH_PHON))
  ------------------
  |  |  114|    754|#define MORPH_PHON "ph:"
  ------------------
  |  Branch (1451:11): [True: 754, False: 583k]
  |  Branch (1451:11): [True: 754, False: 583k]
  |  Branch (1451:37): [True: 754, False: 0]
  ------------------
 1452|    754|          field = f.c_str();
 1453|   584k|      int nw = pAMgr->expand_rootword(
 1454|   584k|          glst.data(), MAX_WORDS, HENTRY_WORD(rp), rp->blen, rp->astr, rp->alen, word,
  ------------------
  |  |   75|   584k|#define MAX_WORDS 100
  ------------------
                        glst.data(), MAX_WORDS, HENTRY_WORD(rp), rp->blen, rp->astr, rp->alen, word,
  ------------------
  |  |   54|   584k|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1455|   584k|          nc, field);
 1456|       |
 1457|  1.16M|      for (int k = 0; k < nw; k++) {
  ------------------
  |  Branch (1457:23): [True: 582k, False: 584k]
  ------------------
 1458|   582k|        if (utf8) {
  ------------------
  |  Branch (1458:13): [True: 248k, False: 333k]
  ------------------
 1459|   248k|          u8_u16(w_f, glst[k].word);
 1460|       |
 1461|   248k|          int leftcommon = leftcommonsubstring(w_word, w_f);
 1462|   248k|          if (low) {
  ------------------
  |  Branch (1462:15): [True: 248k, False: 0]
  ------------------
 1463|       |            // lowering dictionary word
 1464|   248k|            mkallsmall_utf(w_f, langnum);
 1465|   248k|          }
 1466|       |
 1467|   248k|          sc = ngram(n, w_word, w_f, NGRAM_ANY_MISMATCH) + leftcommon;
  ------------------
  |  |   82|   248k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
 1468|   333k|        } else {
 1469|   333k|          f = glst[k].word;
 1470|       |
 1471|   333k|          int leftcommon = leftcommonsubstring(word, f.c_str());
 1472|   333k|          if (low) {
  ------------------
  |  Branch (1472:15): [True: 308k, False: 25.0k]
  ------------------
 1473|       |            // lowering dictionary word
 1474|   308k|            mkallsmall(f, csconv);
 1475|   308k|          }
 1476|       |
 1477|   333k|          sc = ngram(n, word, f, NGRAM_ANY_MISMATCH) + leftcommon;
  ------------------
  |  |   82|   333k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
 1478|   333k|        }
 1479|       |
 1480|   582k|        if (sc > thresh) {
  ------------------
  |  Branch (1480:13): [True: 101k, False: 480k]
  ------------------
 1481|   101k|          if (sc > gscore[lp]) {
  ------------------
  |  Branch (1481:15): [True: 101k, False: 0]
  ------------------
 1482|   101k|            if (guess[lp]) {
  ------------------
  |  Branch (1482:17): [True: 0, False: 101k]
  ------------------
 1483|      0|              delete[] guess[lp];
 1484|      0|              if (guessorig[lp]) {
  ------------------
  |  Branch (1484:19): [True: 0, False: 0]
  ------------------
 1485|      0|                delete[] guessorig[lp];
 1486|      0|                guessorig[lp] = nullptr;
 1487|      0|              }
 1488|      0|            }
 1489|   101k|            gscore[lp] = sc;
 1490|   101k|            guess[lp] = glst[k].word;
 1491|   101k|            guessorig[lp] = glst[k].orig;
 1492|   101k|            lval = sc;
 1493|  20.4M|            for (int j = 0; j < MAX_GUESS; j++)
  ------------------
  |  |   76|  20.4M|#define MAX_GUESS 200
  ------------------
  |  Branch (1493:29): [True: 20.3M, False: 101k]
  ------------------
 1494|  20.3M|              if (gscore[j] < lval) {
  ------------------
  |  Branch (1494:19): [True: 19.5M, False: 868k]
  ------------------
 1495|  19.5M|                lp = j;
 1496|  19.5M|                lval = gscore[j];
 1497|  19.5M|              }
 1498|   101k|          } else {
 1499|      0|            delete[] glst[k].word;
 1500|      0|            delete[] glst[k].orig;
 1501|      0|          }
 1502|   480k|        } else {
 1503|   480k|          delete[] glst[k].word;
 1504|   480k|          delete[] glst[k].orig;
 1505|   480k|        }
 1506|   582k|      }
 1507|   584k|    }
 1508|  4.61M|  }
 1509|  46.1k|  glst.clear();
 1510|       |
 1511|       |  // now we are done generating guesses
 1512|       |  // sort in order of decreasing score
 1513|       |
 1514|  46.1k|  bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS);
  ------------------
  |  |   76|  46.1k|#define MAX_GUESS 200
  ------------------
 1515|  46.1k|  if (ph)
  ------------------
  |  Branch (1515:7): [True: 2.70k, False: 43.4k]
  ------------------
 1516|  2.70k|    bubblesort(&rootsphon[0], nullptr, &scoresphon[0], MAX_ROOTS);
  ------------------
  |  |   74|  2.70k|#define MAX_ROOTS 100
  ------------------
 1517|       |
 1518|       |  // weight suggestions with a similarity index, based on
 1519|       |  // the longest common subsequent algorithm and resort
 1520|       |
 1521|  46.1k|  int is_swap = 0;
 1522|  46.1k|  int re = 0;
 1523|  46.1k|  double fact = 1.0;
 1524|  46.1k|  if (pAMgr) {
  ------------------
  |  Branch (1524:7): [True: 46.1k, False: 0]
  ------------------
 1525|  46.1k|    int maxd = pAMgr->get_maxdiff();
 1526|  46.1k|    if (maxd >= 0)
  ------------------
  |  Branch (1526:9): [True: 0, False: 46.1k]
  ------------------
 1527|      0|      fact = (10.0 - maxd) / 5.0;
 1528|  46.1k|  }
 1529|       |
 1530|  46.1k|  std::vector<w_char> w_gl;
 1531|  8.83M|  for (int i = 0; i < MAX_GUESS; i++) {
  ------------------
  |  |   76|  8.83M|#define MAX_GUESS 200
  ------------------
  |  Branch (1531:19): [True: 8.78M, False: 43.9k]
  ------------------
 1532|  8.78M|    if (guess[i]) {
  ------------------
  |  Branch (1532:9): [True: 79.5k, False: 8.70M]
  ------------------
 1533|       |      // lowering guess[i]
 1534|  79.5k|      std::string gl;
 1535|  79.5k|      int len;
 1536|  79.5k|      if (utf8) {
  ------------------
  |  Branch (1536:11): [True: 22.3k, False: 57.1k]
  ------------------
 1537|  22.3k|        len = u8_u16(w_gl, guess[i]);
 1538|  22.3k|        mkallsmall_utf(w_gl, langnum);
 1539|  22.3k|        u16_u8(gl, w_gl);
 1540|  57.1k|      } else {
 1541|  57.1k|        gl.assign(guess[i]);
 1542|  57.1k|        if (!nonbmp)
  ------------------
  |  Branch (1542:13): [True: 57.1k, False: 12]
  ------------------
 1543|  57.1k|          mkallsmall(gl, csconv);
 1544|  57.1k|        len = strlen(guess[i]);
 1545|  57.1k|      }
 1546|       |
 1547|  79.5k|      int _lcs = lcslen(word, gl.c_str());
 1548|       |
 1549|       |      // same characters with different casing
 1550|  79.5k|      if ((n == len) && (n == _lcs)) {
  ------------------
  |  Branch (1550:11): [True: 18.0k, False: 61.4k]
  |  Branch (1550:25): [True: 2.26k, False: 15.7k]
  ------------------
 1551|  2.26k|        gscore[i] += 2000;
 1552|  2.26k|        break;
 1553|  2.26k|      }
 1554|       |      // using 2-gram instead of 3, and other weightening
 1555|       |
 1556|  77.2k|      if (utf8) {
  ------------------
  |  Branch (1556:11): [True: 20.6k, False: 56.6k]
  ------------------
 1557|  20.6k|        u8_u16(w_gl, gl);
 1558|       |        //w_gl is lowercase already at this point
 1559|  20.6k|        re = ngram(2, w_word, w_gl, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   82|  20.6k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
                      re = ngram(2, w_word, w_gl, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   84|  20.6k|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
 1560|  20.6k|        if (low) {
  ------------------
  |  Branch (1560:13): [True: 20.6k, False: 0]
  ------------------
 1561|  20.6k|          w_f = w_word;
 1562|       |          // lowering dictionary word
 1563|  20.6k|          mkallsmall_utf(w_f, langnum);
 1564|  20.6k|          re += ngram(2, w_gl, w_f, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   82|  20.6k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
                        re += ngram(2, w_gl, w_f, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   84|  20.6k|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
 1565|  20.6k|        } else {
 1566|      0|          re += ngram(2, w_gl, w_word, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   82|      0|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
                        re += ngram(2, w_gl, w_word, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   84|      0|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
 1567|      0|        }
 1568|  56.6k|      } else {
 1569|       |        //gl is lowercase already at this point
 1570|  56.6k|        re = ngram(2, word, gl, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   82|  56.6k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
                      re = ngram(2, word, gl, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   84|  56.6k|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
 1571|  56.6k|        if (low) {
  ------------------
  |  Branch (1571:13): [True: 56.6k, False: 12]
  ------------------
 1572|  56.6k|          f = word;
 1573|       |          // lowering dictionary word
 1574|  56.6k|          mkallsmall(f, csconv);
 1575|  56.6k|          re += ngram(2, gl, f, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   82|  56.6k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
                        re += ngram(2, gl, f, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   84|  56.6k|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
 1576|  56.6k|        } else {
 1577|     12|          re += ngram(2, gl, word, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   82|     12|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
                        re += ngram(2, gl, word, NGRAM_ANY_MISMATCH | NGRAM_WEIGHTED);
  ------------------
  |  |   84|     12|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
 1578|     12|        }
 1579|  56.6k|      }
 1580|       |
 1581|  77.2k|      int ngram_score, leftcommon_score;
 1582|  77.2k|      if (utf8) {
  ------------------
  |  Branch (1582:11): [True: 20.6k, False: 56.6k]
  ------------------
 1583|       |        //w_gl is lowercase already at this point
 1584|  20.6k|        ngram_score = ngram(4, w_word, w_gl, NGRAM_ANY_MISMATCH);
  ------------------
  |  |   82|  20.6k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
 1585|  20.6k|        leftcommon_score = leftcommonsubstring(w_word, w_gl);
 1586|  56.6k|      } else {
 1587|       |        //gl is lowercase already at this point
 1588|  56.6k|        ngram_score = ngram(4, word, gl, NGRAM_ANY_MISMATCH);
  ------------------
  |  |   82|  56.6k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
 1589|  56.6k|        leftcommon_score = leftcommonsubstring(word, gl.c_str());
 1590|  56.6k|      }
 1591|  77.2k|      gscore[i] =
 1592|       |          // length of longest common subsequent minus length difference
 1593|  77.2k|          2 * _lcs - abs((int)(n - len)) +
 1594|       |          // weight length of the left common substring
 1595|  77.2k|          leftcommon_score +
 1596|       |          // weight equal character positions
 1597|  77.2k|          (!nonbmp && commoncharacterpositions(word, gl.c_str(), &is_swap)
  ------------------
  |  Branch (1597:12): [True: 77.2k, False: 12]
  |  Branch (1597:23): [True: 62.2k, False: 14.9k]
  ------------------
 1598|  77.2k|               ? 1
 1599|  77.2k|               : 0) +
 1600|       |          // swap character (not neighboring)
 1601|  77.2k|          ((is_swap) ? 10 : 0) +
  ------------------
  |  Branch (1601:12): [True: 170, False: 77.0k]
  ------------------
 1602|       |          // ngram
 1603|  77.2k|          ngram_score +
 1604|       |          // weighted ngrams
 1605|  77.2k|          re +
 1606|       |          // different limit for dictionaries with PHONE rules
 1607|  77.2k|          (ph ? (re < len * fact ? -1000 : 0)
  ------------------
  |  Branch (1607:12): [True: 5.26k, False: 71.9k]
  |  Branch (1607:18): [True: 4.02k, False: 1.23k]
  ------------------
 1608|  77.2k|              : (re < (n + len) * fact ? -1000 : 0));
  ------------------
  |  Branch (1608:18): [True: 65.8k, False: 6.13k]
  ------------------
 1609|  77.2k|    }
 1610|  8.78M|  }
 1611|       |
 1612|  46.1k|  bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS);
  ------------------
  |  |   76|  46.1k|#define MAX_GUESS 200
  ------------------
 1613|       |
 1614|       |  // phonetic version
 1615|  46.1k|  if (ph)
  ------------------
  |  Branch (1615:7): [True: 2.70k, False: 43.4k]
  ------------------
 1616|   273k|    for (int i = 0; i < MAX_ROOTS; i++) {
  ------------------
  |  |   74|   273k|#define MAX_ROOTS 100
  ------------------
  |  Branch (1616:21): [True: 270k, False: 2.70k]
  ------------------
 1617|   270k|      if (rootsphon[i]) {
  ------------------
  |  Branch (1617:11): [True: 7.09k, False: 263k]
  ------------------
 1618|       |        // lowering rootphon[i]
 1619|  7.09k|        std::string gl;
 1620|  7.09k|        int len;
 1621|  7.09k|        if (utf8) {
  ------------------
  |  Branch (1621:13): [True: 0, False: 7.09k]
  ------------------
 1622|      0|          len = u8_u16(w_gl, rootsphon[i]);
 1623|      0|          mkallsmall_utf(w_gl, langnum);
 1624|      0|          u16_u8(gl, w_gl);
 1625|  7.09k|        } else {
 1626|  7.09k|          gl.assign(rootsphon[i]);
 1627|  7.09k|          if (!nonbmp)
  ------------------
  |  Branch (1627:15): [True: 7.09k, False: 0]
  ------------------
 1628|  7.09k|            mkallsmall(gl, csconv);
 1629|  7.09k|          len = strlen(rootsphon[i]);
 1630|  7.09k|        }
 1631|       |
 1632|       |        // weight length of the left common substring
 1633|  7.09k|        int leftcommon_score;
 1634|  7.09k|        if (utf8)
  ------------------
  |  Branch (1634:13): [True: 0, False: 7.09k]
  ------------------
 1635|      0|          leftcommon_score = leftcommonsubstring(w_word, w_gl);
 1636|  7.09k|        else
 1637|  7.09k|          leftcommon_score = leftcommonsubstring(word, gl.c_str());
 1638|       |        // heuristic weigthing of ngram scores
 1639|  7.09k|        scoresphon[i] += 2 * lcslen(word, gl) - abs((int)(n - len)) +
 1640|  7.09k|                         leftcommon_score;
 1641|  7.09k|      }
 1642|   270k|    }
 1643|       |
 1644|  46.1k|  if (ph)
  ------------------
  |  Branch (1644:7): [True: 2.70k, False: 43.4k]
  ------------------
 1645|  2.70k|    bubblesort(&rootsphon[0], nullptr, &scoresphon[0], MAX_ROOTS);
  ------------------
  |  |   74|  2.70k|#define MAX_ROOTS 100
  ------------------
 1646|       |
 1647|       |  // copy over
 1648|  46.1k|  size_t oldns = wlst.size();
 1649|       |
 1650|  46.1k|  int same = 0;
 1651|  9.28M|  for (int i = 0; i < MAX_GUESS; i++) {
  ------------------
  |  |   76|  9.28M|#define MAX_GUESS 200
  ------------------
  |  Branch (1651:19): [True: 9.23M, False: 46.1k]
  ------------------
 1652|  9.23M|    if (guess[i]) {
  ------------------
  |  Branch (1652:9): [True: 101k, False: 9.13M]
  ------------------
 1653|   101k|      if ((wlst.size() < oldns + maxngramsugs) && (wlst.size() < maxSug) &&
  ------------------
  |  Branch (1653:11): [True: 92.0k, False: 9.79k]
  |  Branch (1653:51): [True: 92.0k, False: 0]
  ------------------
 1654|  92.0k|          (!same || (gscore[i] > 1000))) {
  ------------------
  |  Branch (1654:12): [True: 16.1k, False: 75.8k]
  |  Branch (1654:21): [True: 0, False: 75.8k]
  ------------------
 1655|  16.1k|        int unique = 1;
 1656|       |        // leave only excellent suggestions, if exists
 1657|  16.1k|        if (gscore[i] > 1000)
  ------------------
  |  Branch (1657:13): [True: 2.26k, False: 13.9k]
  ------------------
 1658|  2.26k|          same = 1;
 1659|  13.9k|        else if (gscore[i] < -100) {
  ------------------
  |  Branch (1659:18): [True: 8.39k, False: 5.53k]
  ------------------
 1660|  8.39k|          same = 1;
 1661|       |          // keep the best ngram suggestions, unless in ONLYMAXDIFF mode
 1662|  8.39k|          if (wlst.size() > oldns || (pAMgr && pAMgr->get_onlymaxdiff())) {
  ------------------
  |  Branch (1662:15): [True: 1.17k, False: 7.21k]
  |  Branch (1662:39): [True: 7.21k, False: 0]
  |  Branch (1662:48): [True: 0, False: 7.21k]
  ------------------
 1663|  1.17k|            delete[] guess[i];
 1664|  1.17k|            delete[] guessorig[i];
 1665|  1.17k|            continue;
 1666|  1.17k|          }
 1667|  8.39k|        }
 1668|  15.0k|        for (auto& j : wlst) {
  ------------------
  |  Branch (1668:22): [True: 8.01k, False: 14.1k]
  ------------------
 1669|       |          // don't suggest previous suggestions or a previous suggestion with
 1670|       |          // prefixes or affixes
 1671|  8.01k|          if ((!guessorig[i] && strstr(guess[i], j.c_str())) || (guessorig[i] && strstr(guessorig[i], j.c_str())) ||
  ------------------
  |  Branch (1671:15): [True: 830, False: 7.18k]
  |  Branch (1671:16): [True: 8.01k, False: 0]
  |  Branch (1671:33): [True: 830, False: 7.18k]
  |  Branch (1671:66): [True: 0, False: 7.18k]
  |  Branch (1671:82): [True: 0, False: 0]
  ------------------
 1672|       |              // check forbidden words
 1673|  7.18k|              !checkword(guess[i], 0, nullptr, nullptr)) {
  ------------------
  |  Branch (1673:15): [True: 0, False: 7.18k]
  ------------------
 1674|    830|            unique = 0;
 1675|    830|            break;
 1676|    830|          }
 1677|  8.01k|        }
 1678|  15.0k|        if (unique) {
  ------------------
  |  Branch (1678:13): [True: 14.1k, False: 830]
  ------------------
 1679|  14.1k|          if (guessorig[i]) {
  ------------------
  |  Branch (1679:15): [True: 0, False: 14.1k]
  ------------------
 1680|      0|            wlst.emplace_back(guessorig[i]);
 1681|  14.1k|          } else {
 1682|  14.1k|            wlst.emplace_back(guess[i]);
 1683|  14.1k|          }
 1684|  14.1k|        }
 1685|  15.0k|        delete[] guess[i];
 1686|  15.0k|        delete[] guessorig[i];
 1687|  85.6k|      } else {
 1688|  85.6k|        delete[] guess[i];
 1689|  85.6k|        delete[] guessorig[i];
 1690|  85.6k|      }
 1691|   101k|    }
 1692|  9.23M|  }
 1693|       |
 1694|  46.1k|  oldns = wlst.size();
 1695|  46.1k|  if (ph)
  ------------------
  |  Branch (1695:7): [True: 2.70k, False: 43.4k]
  ------------------
 1696|   270k|    for (auto& i : rootsphon) {
  ------------------
  |  Branch (1696:18): [True: 270k, False: 2.70k]
  ------------------
 1697|   270k|      if (i) {
  ------------------
  |  Branch (1697:11): [True: 7.09k, False: 263k]
  ------------------
 1698|  7.09k|        if ((wlst.size() < oldns + MAXPHONSUGS) && (wlst.size() < maxSug)) {
  ------------------
  |  |   78|  7.09k|#define MAXPHONSUGS 2
  ------------------
  |  Branch (1698:13): [True: 1.89k, False: 5.19k]
  |  Branch (1698:52): [True: 1.89k, False: 0]
  ------------------
 1699|  1.89k|          int unique = 1;
 1700|  3.58k|          for (auto& j : wlst) {
  ------------------
  |  Branch (1700:24): [True: 3.58k, False: 974]
  ------------------
 1701|       |            // don't suggest previous suggestions or a previous suggestion with
 1702|       |            // prefixes or affixes
 1703|  3.58k|            if (strstr(i, j.c_str()) ||
  ------------------
  |  Branch (1703:17): [True: 925, False: 2.66k]
  |  Branch (1703:17): [True: 925, False: 2.66k]
  ------------------
 1704|       |                // check forbidden words
 1705|  2.66k|                !checkword(i, 0, nullptr, nullptr)) {
  ------------------
  |  Branch (1705:17): [True: 0, False: 2.66k]
  ------------------
 1706|    925|              unique = 0;
 1707|    925|              break;
 1708|    925|            }
 1709|  3.58k|          }
 1710|  1.89k|          if (unique) {
  ------------------
  |  Branch (1710:15): [True: 974, False: 925]
  ------------------
 1711|    974|            wlst.emplace_back(i);
 1712|    974|          }
 1713|  1.89k|        }
 1714|  7.09k|      }
 1715|   270k|    }
 1716|  46.1k|}
_ZN10SuggestMgr9checkwordERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEiPiPNS0_6chrono10time_pointINSA_12steady_clockENSA_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEE:
 1727|  85.0M|                          std::chrono::steady_clock::time_point* timelimit) {
 1728|       |  // check overall suggestion time limit
 1729|  85.0M|  if (std::chrono::steady_clock::now() - suggest_start > TIMELIMIT_SUGGESTION_MS)
  ------------------
  |  |  105|  85.0M|#define TIMELIMIT_SUGGESTION_MS std::chrono::milliseconds(100)
  ------------------
  |  Branch (1729:7): [True: 8, False: 85.0M]
  ------------------
 1730|      8|    return 0;
 1731|       |
 1732|       |  // check time limit
 1733|  85.0M|  if (timer) {
  ------------------
  |  Branch (1733:7): [True: 1.37M, False: 83.6M]
  ------------------
 1734|  1.37M|    (*timer)--;
 1735|  1.37M|    if (!(*timer) && timelimit) {
  ------------------
  |  Branch (1735:9): [True: 9.30k, False: 1.36M]
  |  Branch (1735:22): [True: 9.30k, False: 0]
  ------------------
 1736|  9.30k|      if (std::chrono::steady_clock::now() - *timelimit > TIMELIMIT_MS)
  ------------------
  |  |  106|  9.30k|#define TIMELIMIT_MS std::chrono::milliseconds(50)
  ------------------
  |  Branch (1736:11): [True: 9, False: 9.29k]
  ------------------
 1737|      9|        return 0;
 1738|  9.29k|      *timer = MAXPLUSTIMER;
  ------------------
  |  |  108|  9.29k|#define MAXPLUSTIMER 100
  ------------------
 1739|  9.29k|    }
 1740|  1.37M|  }
 1741|       |
 1742|  85.0M|  if (pAMgr) {
  ------------------
  |  Branch (1742:7): [True: 85.0M, False: 0]
  ------------------
 1743|  85.0M|    struct hentry* rv = nullptr;
 1744|  85.0M|    int nosuffix = 0;
 1745|       |
 1746|  85.0M|    if (cpdsuggest >= 1) {
  ------------------
  |  Branch (1746:9): [True: 55.6M, False: 29.4M]
  ------------------
 1747|  55.6M|      if (pAMgr->get_compound()) {
  ------------------
  |  Branch (1747:11): [True: 14.0M, False: 41.5M]
  ------------------
 1748|  14.0M|        struct hentry* rv2 = nullptr;
 1749|  14.0M|        struct hentry* rwords[100] = {};  // buffer for COMPOUND pattern checking
 1750|  14.0M|        int info = (cpdsuggest == 1) ? SPELL_COMPOUND_2 : 0;
  ------------------
  |  |   85|  7.00M|#define SPELL_COMPOUND_2 (1 << 7)  // permit only 2 dictionary words in the compound
  ------------------
  |  Branch (1750:20): [True: 7.00M, False: 7.00M]
  ------------------
 1751|  14.0M|        AffixScratch scratch;
 1752|  14.0M|        rv = pAMgr->compound_check(word, 0, 0, 100, 0, nullptr, (hentry**)&rwords, 0, 1, &info, scratch);  // EXT
 1753|       |        // TODO filter 3-word or more compound words, as in spell()
 1754|       |        // (it's too slow to call suggest() here for all possible compound words)
 1755|  14.0M|        if (rv &&
  ------------------
  |  Branch (1755:13): [True: 0, False: 14.0M]
  |  Branch (1755:13): [True: 0, False: 14.0M]
  ------------------
 1756|      0|            (!(rv2 = pAMgr->lookup(word.c_str(), word.size())) || !rv2->astr ||
  ------------------
  |  Branch (1756:14): [True: 0, False: 0]
  |  Branch (1756:67): [True: 0, False: 0]
  ------------------
 1757|      0|             !(TESTAFF(rv2->astr, pAMgr->get_forbiddenword(), rv2->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1758|      0|               TESTAFF(rv2->astr, pAMgr->get_nosuggest(), rv2->alen))))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1759|      0|          return 3;  // XXX obsolote categorisation + only ICONV needs affix
 1760|       |                     // flag check?
 1761|  14.0M|      }
 1762|  55.6M|      return 0;
 1763|  55.6M|    }
 1764|       |
 1765|  29.4M|    rv = pAMgr->lookup(word.c_str(), word.size());
 1766|       |
 1767|  29.4M|    if (rv) {
  ------------------
  |  Branch (1767:9): [True: 34.3k, False: 29.3M]
  ------------------
 1768|  34.3k|      if ((rv->astr) &&
  ------------------
  |  Branch (1768:11): [True: 381, False: 33.9k]
  |  Branch (1768:11): [True: 0, False: 34.3k]
  ------------------
 1769|    381|          (TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) ||
  ------------------
  |  |   99|    762|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 381]
  |  |  ------------------
  ------------------
 1770|    381|           TESTAFF(rv->astr, pAMgr->get_nosuggest(), rv->alen) ||
  ------------------
  |  |   99|    762|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 381]
  |  |  ------------------
  ------------------
 1771|    381|           TESTAFF(rv->astr, pAMgr->get_substandard(), rv->alen)))
  ------------------
  |  |   99|    381|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 381]
  |  |  ------------------
  ------------------
 1772|      0|        return 0;
 1773|  34.7k|      while (rv) {
  ------------------
  |  Branch (1773:14): [True: 34.3k, False: 367]
  ------------------
 1774|  34.3k|        if (rv->astr &&
  ------------------
  |  Branch (1774:13): [True: 381, False: 33.9k]
  |  Branch (1774:13): [True: 367, False: 33.9k]
  ------------------
 1775|    381|            (TESTAFF(rv->astr, pAMgr->get_needaffix(), rv->alen) ||
  ------------------
  |  |   99|    762|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 381]
  |  |  ------------------
  ------------------
 1776|    381|             TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
  ------------------
  |  |   99|    762|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 367, False: 14]
  |  |  ------------------
  ------------------
 1777|    367|             TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen))) {
  ------------------
  |  |   99|     14|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 14]
  |  |  ------------------
  ------------------
 1778|    367|          rv = rv->next_homonym;
 1779|    367|        } else
 1780|  33.9k|          break;
 1781|  34.3k|      }
 1782|  29.3M|    } else {
 1783|  29.3M|      AffixScratch scratch;
 1784|  29.3M|      rv = pAMgr->prefix_check(word, 0, word.size(),
 1785|  29.3M|                               0, scratch);  // only prefix, and prefix + suffix XXX
 1786|  29.3M|    }
 1787|       |
 1788|  29.4M|    if (rv) {
  ------------------
  |  Branch (1788:9): [True: 33.9k, False: 29.3M]
  ------------------
 1789|  33.9k|      nosuffix = 1;
 1790|  29.3M|    } else {
 1791|  29.3M|      AffixScratch scratch;
 1792|  29.3M|      rv = pAMgr->suffix_check(word, 0, word.size(), 0, nullptr, scratch, FLAG_NULL, FLAG_NULL, IN_CPD_NOT);  // only suffix
  ------------------
  |  |   96|  29.3M|#define FLAG_NULL 0x00
  ------------------
                    rv = pAMgr->suffix_check(word, 0, word.size(), 0, nullptr, scratch, FLAG_NULL, FLAG_NULL, IN_CPD_NOT);  // only suffix
  ------------------
  |  |   96|  29.3M|#define FLAG_NULL 0x00
  ------------------
                    rv = pAMgr->suffix_check(word, 0, word.size(), 0, nullptr, scratch, FLAG_NULL, FLAG_NULL, IN_CPD_NOT);  // only suffix
  ------------------
  |  |   72|  29.3M|#define IN_CPD_NOT 0
  ------------------
 1793|  29.3M|    }
 1794|       |
 1795|  29.4M|    if (!rv && pAMgr->have_contclass()) {
  ------------------
  |  Branch (1795:9): [True: 29.3M, False: 33.9k]
  |  Branch (1795:16): [True: 10.5M, False: 18.8M]
  ------------------
 1796|  10.5M|      AffixScratch scratch;
 1797|  10.5M|      rv = pAMgr->suffix_check_twosfx(word, 0, word.size(), 0, nullptr, scratch, FLAG_NULL);
  ------------------
  |  |   96|  10.5M|#define FLAG_NULL 0x00
  ------------------
 1798|  10.5M|      if (!rv)
  ------------------
  |  Branch (1798:11): [True: 10.5M, False: 0]
  ------------------
 1799|  10.5M|        rv = pAMgr->prefix_check_twosfx(word, 0, word.size(), 0, scratch, FLAG_NULL);
  ------------------
  |  |   96|  10.5M|#define FLAG_NULL 0x00
  ------------------
 1800|  10.5M|    }
 1801|       |
 1802|       |    // check forbidden words
 1803|  29.4M|    if ((rv) && (rv->astr) &&
  ------------------
  |  Branch (1803:9): [True: 33.9k, False: 29.3M]
  |  Branch (1803:9): [True: 0, False: 29.4M]
  |  Branch (1803:17): [True: 16, False: 33.9k]
  ------------------
 1804|     16|        (TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) ||
  ------------------
  |  |   99|     32|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 16]
  |  |  ------------------
  ------------------
 1805|     16|         TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
  ------------------
  |  |   99|     32|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 16]
  |  |  ------------------
  ------------------
 1806|     16|         TESTAFF(rv->astr, pAMgr->get_nosuggest(), rv->alen) ||
  ------------------
  |  |   99|     32|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 16]
  |  |  ------------------
  ------------------
 1807|     16|         TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen)))
  ------------------
  |  |   99|     16|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 16]
  |  |  ------------------
  ------------------
 1808|      0|      return 0;
 1809|       |
 1810|  29.4M|    if (rv) {  // XXX obsolote
  ------------------
  |  Branch (1810:9): [True: 33.9k, False: 29.3M]
  ------------------
 1811|  33.9k|      if ((pAMgr->get_compoundflag()) &&
  ------------------
  |  Branch (1811:11): [True: 8.04k, False: 25.9k]
  |  Branch (1811:11): [True: 10, False: 33.9k]
  ------------------
 1812|  8.04k|          TESTAFF(rv->astr, pAMgr->get_compoundflag(), rv->alen))
  ------------------
  |  |   99|  8.04k|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 10, False: 8.03k]
  |  |  ------------------
  ------------------
 1813|     10|        return 2 + nosuffix;
 1814|  33.9k|      return 1;
 1815|  33.9k|    }
 1816|  29.4M|  }
 1817|  29.3M|  return 0;
 1818|  85.0M|}
_ZN10SuggestMgr15check_forbiddenERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1820|  13.5k|int SuggestMgr::check_forbidden(const std::string& word) {
 1821|  13.5k|  if (pAMgr) {
  ------------------
  |  Branch (1821:7): [True: 13.5k, False: 0]
  ------------------
 1822|  13.5k|    struct hentry* rv = pAMgr->lookup(word.c_str(), word.size());
 1823|  13.5k|    if (rv && rv->astr &&
  ------------------
  |  Branch (1823:9): [True: 0, False: 13.5k]
  |  Branch (1823:9): [True: 0, False: 13.5k]
  |  Branch (1823:15): [True: 0, False: 0]
  ------------------
 1824|      0|        (TESTAFF(rv->astr, pAMgr->get_needaffix(), rv->alen) ||
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1825|      0|         TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen)))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1826|      0|      rv = nullptr;
 1827|  13.5k|    size_t len = word.size();
 1828|  13.5k|    AffixScratch scratch;
 1829|  13.5k|    if (!(pAMgr->prefix_check(word, 0, len, 1, scratch)))
  ------------------
  |  Branch (1829:9): [True: 13.5k, False: 0]
  ------------------
 1830|  13.5k|      rv = pAMgr->suffix_check(word, 0, len, 0, nullptr, scratch, FLAG_NULL, FLAG_NULL, IN_CPD_NOT);  // prefix+suffix, suffix
  ------------------
  |  |   96|  13.5k|#define FLAG_NULL 0x00
  ------------------
                    rv = pAMgr->suffix_check(word, 0, len, 0, nullptr, scratch, FLAG_NULL, FLAG_NULL, IN_CPD_NOT);  // prefix+suffix, suffix
  ------------------
  |  |   96|  13.5k|#define FLAG_NULL 0x00
  ------------------
                    rv = pAMgr->suffix_check(word, 0, len, 0, nullptr, scratch, FLAG_NULL, FLAG_NULL, IN_CPD_NOT);  // prefix+suffix, suffix
  ------------------
  |  |   72|  13.5k|#define IN_CPD_NOT 0
  ------------------
 1831|       |    // check forbidden words
 1832|  13.5k|    if ((rv) && (rv->astr) &&
  ------------------
  |  Branch (1832:9): [True: 0, False: 13.5k]
  |  Branch (1832:9): [True: 0, False: 13.5k]
  |  Branch (1832:17): [True: 0, False: 0]
  ------------------
 1833|      0|        TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen))
  ------------------
  |  |   99|      0|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1834|      0|      return 1;
 1835|  13.5k|  }
 1836|  13.5k|  return 0;
 1837|  13.5k|}
_ZN10SuggestMgr13suggest_morphERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
 1839|  10.6k|std::string SuggestMgr::suggest_morph(const std::string& in_w) {
 1840|  10.6k|  std::string result;
 1841|       |
 1842|  10.6k|  struct hentry* rv = nullptr;
 1843|       |
 1844|  10.6k|  if (!pAMgr)
  ------------------
  |  Branch (1844:7): [True: 0, False: 10.6k]
  ------------------
 1845|      0|    return {};
 1846|       |
 1847|  10.6k|  std::string w(in_w);
 1848|       |
 1849|       |  // word reversing wrapper for complex prefixes
 1850|  10.6k|  if (complexprefixes) {
  ------------------
  |  Branch (1850:7): [True: 543, False: 10.1k]
  ------------------
 1851|    543|    if (utf8)
  ------------------
  |  Branch (1851:9): [True: 0, False: 543]
  ------------------
 1852|      0|      reverseword_utf(w);
 1853|    543|    else
 1854|    543|      reverseword(w);
 1855|    543|  }
 1856|       |
 1857|  10.6k|  rv = pAMgr->lookup(w.c_str(), w.size());
 1858|       |
 1859|  12.5k|  while (rv) {
  ------------------
  |  Branch (1859:10): [True: 1.88k, False: 10.6k]
  ------------------
 1860|  1.88k|    if ((!rv->astr) ||
  ------------------
  |  Branch (1860:9): [True: 1.48k, False: 400]
  |  Branch (1860:9): [True: 1.88k, False: 0]
  ------------------
 1861|    400|        !(TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) ||
  ------------------
  |  |   99|    800|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 400]
  |  |  ------------------
  ------------------
 1862|    400|          TESTAFF(rv->astr, pAMgr->get_needaffix(), rv->alen) ||
  ------------------
  |  |   99|    800|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 400]
  |  |  ------------------
  ------------------
 1863|  1.88k|          TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen))) {
  ------------------
  |  |   99|    400|#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
  |  |  ------------------
  |  |  |  Branch (99:26): [True: 0, False: 400]
  |  |  ------------------
  ------------------
 1864|  1.88k|      if (!HENTRY_FIND(rv, MORPH_STEM)) {
  ------------------
  |  |  103|  1.88k|#define MORPH_STEM "st:"
  ------------------
  |  Branch (1864:11): [True: 1.88k, False: 0]
  ------------------
 1865|  1.88k|        result.push_back(MSEP_FLD);
  ------------------
  |  |  121|  1.88k|#define MSEP_FLD ' '
  ------------------
 1866|  1.88k|        result.append(MORPH_STEM);
  ------------------
  |  |  103|  1.88k|#define MORPH_STEM "st:"
  ------------------
 1867|  1.88k|        result.append(w);
 1868|  1.88k|      }
 1869|  1.88k|      if (HENTRY_DATA(rv)) {
  ------------------
  |  Branch (1869:11): [True: 0, False: 1.88k]
  ------------------
 1870|      0|        result.push_back(MSEP_FLD);
  ------------------
  |  |  121|      0|#define MSEP_FLD ' '
  ------------------
 1871|      0|        result.append(HENTRY_DATA2(rv));
 1872|      0|      }
 1873|  1.88k|      result.push_back(MSEP_REC);
  ------------------
  |  |  122|  1.88k|#define MSEP_REC '\n'
  ------------------
 1874|  1.88k|    }
 1875|  1.88k|    rv = rv->next_homonym;
 1876|  1.88k|  }
 1877|       |
 1878|  10.6k|  AffixScratch scratch;
 1879|  10.6k|  std::string st = pAMgr->affix_check_morph(w, 0, w.size(), scratch);
 1880|  10.6k|  if (!st.empty()) {
  ------------------
  |  Branch (1880:7): [True: 0, False: 10.6k]
  ------------------
 1881|      0|    result.append(st);
 1882|      0|  }
 1883|       |
 1884|  10.6k|  if (pAMgr->get_compound() && result.empty()) {
  ------------------
  |  Branch (1884:7): [True: 2.22k, False: 8.47k]
  |  Branch (1884:32): [True: 1.75k, False: 472]
  ------------------
 1885|  1.75k|    struct hentry* rwords[100] = {};  // buffer for COMPOUND pattern checking
 1886|  1.75k|    pAMgr->compound_check_morph(w, 0, 0, 100, 0, nullptr, (hentry**)&rwords, 0, result, nullptr, scratch);
 1887|  1.75k|  }
 1888|       |
 1889|  10.6k|  line_uniq(result, MSEP_REC);
  ------------------
  |  |  122|  10.6k|#define MSEP_REC '\n'
  ------------------
 1890|       |
 1891|  10.6k|  return result;
 1892|  10.6k|}
_ZN10SuggestMgr18suggest_hentry_genEP6hentryPKc:
 1917|   339k|std::string SuggestMgr::suggest_hentry_gen(hentry* rv, const char* pattern) {
 1918|   339k|  std::string result;
 1919|   339k|  int sfxcount = get_sfxcount(pattern);
 1920|       |
 1921|   339k|  if (get_sfxcount(HENTRY_DATA(rv)) > sfxcount)
  ------------------
  |  Branch (1921:7): [True: 0, False: 339k]
  ------------------
 1922|      0|    return result;
 1923|       |
 1924|   339k|  if (HENTRY_DATA(rv)) {
  ------------------
  |  Branch (1924:7): [True: 0, False: 339k]
  ------------------
 1925|      0|    std::string aff = pAMgr->morphgen(HENTRY_WORD(rv), rv->blen, rv->astr, rv->alen,
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1926|      0|                                      HENTRY_DATA(rv), pattern, 0);
 1927|      0|    if (!aff.empty()) {
  ------------------
  |  Branch (1927:9): [True: 0, False: 0]
  ------------------
 1928|      0|      result.append(aff);
 1929|      0|      result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1930|      0|    }
 1931|      0|  }
 1932|       |
 1933|       |  // check all allomorphs
 1934|   339k|  char* p = nullptr;
 1935|   339k|  if (HENTRY_DATA(rv))
  ------------------
  |  Branch (1935:7): [True: 0, False: 339k]
  ------------------
 1936|      0|    p = (char*)strstr(HENTRY_DATA2(rv), MORPH_ALLOMORPH);
  ------------------
  |  |  104|      0|#define MORPH_ALLOMORPH "al:"
  ------------------
 1937|   339k|  while (p) {
  ------------------
  |  Branch (1937:10): [True: 0, False: 339k]
  ------------------
 1938|      0|    p += MORPH_TAG_LEN;
  ------------------
  |  |  119|      0|#define MORPH_TAG_LEN strlen(MORPH_STEM)
  |  |  ------------------
  |  |  |  |  103|      0|#define MORPH_STEM "st:"
  |  |  ------------------
  ------------------
 1939|      0|    int plen = fieldlen(p);
 1940|      0|    std::string allomorph(p, plen);
 1941|      0|    struct hentry* rv2 = pAMgr->lookup(allomorph.c_str(), allomorph.size());
 1942|      0|    while (rv2) {
  ------------------
  |  Branch (1942:12): [True: 0, False: 0]
  ------------------
 1943|       |      //            if (HENTRY_DATA(rv2) && get_sfxcount(HENTRY_DATA(rv2)) <=
 1944|       |      //            sfxcount) {
 1945|      0|      if (HENTRY_DATA(rv2)) {
  ------------------
  |  Branch (1945:11): [True: 0, False: 0]
  ------------------
 1946|      0|        char* st = (char*)strstr(HENTRY_DATA2(rv2), MORPH_STEM);
  ------------------
  |  |  103|      0|#define MORPH_STEM "st:"
  ------------------
 1947|      0|        if (st && (strncmp(st + MORPH_TAG_LEN, HENTRY_WORD(rv),
  ------------------
  |  |  119|      0|#define MORPH_TAG_LEN strlen(MORPH_STEM)
  |  |  ------------------
  |  |  |  |  103|      0|#define MORPH_STEM "st:"
  |  |  ------------------
  ------------------
                      if (st && (strncmp(st + MORPH_TAG_LEN, HENTRY_WORD(rv),
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
  |  Branch (1947:13): [True: 0, False: 0]
  |  Branch (1947:19): [True: 0, False: 0]
  ------------------
 1948|      0|                           fieldlen(st + MORPH_TAG_LEN)) == 0)) {
  ------------------
  |  |  119|      0|#define MORPH_TAG_LEN strlen(MORPH_STEM)
  |  |  ------------------
  |  |  |  |  103|      0|#define MORPH_STEM "st:"
  |  |  ------------------
  ------------------
 1949|      0|          std::string aff = pAMgr->morphgen(HENTRY_WORD(rv2), rv2->blen, rv2->astr,
  ------------------
  |  |   54|      0|#define HENTRY_WORD(h) &(h->word[0])
  ------------------
 1950|      0|                                            rv2->alen, HENTRY_DATA(rv2), pattern, 0);
 1951|      0|          if (!aff.empty()) {
  ------------------
  |  Branch (1951:15): [True: 0, False: 0]
  ------------------
 1952|      0|            result.append(aff);
 1953|      0|            result.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 1954|      0|          }
 1955|      0|        }
 1956|      0|      }
 1957|      0|      rv2 = rv2->next_homonym;
 1958|      0|    }
 1959|      0|    p = strstr(p + plen, MORPH_ALLOMORPH);
  ------------------
  |  |  104|      0|#define MORPH_ALLOMORPH "al:"
  ------------------
 1960|      0|  }
 1961|       |
 1962|   339k|  return result;
 1963|   339k|}
_ZN10SuggestMgr11suggest_genERKNSt3__16vectorINS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS5_IS7_EEEERKS7_NS0_6chrono10time_pointINSE_12steady_clockENSE_8durationIxNS0_5ratioILl1ELl1000000000EEEEEEE:
 1966|  7.75M|                                    std::chrono::steady_clock::time_point start_time) {
 1967|  7.75M|  if (desc.empty() || !pAMgr)
  ------------------
  |  Branch (1967:7): [True: 7.64M, False: 112k]
  |  Branch (1967:23): [True: 0, False: 112k]
  ------------------
 1968|  7.64M|    return {};
 1969|       |
 1970|   112k|  const char* pattern = in_pattern.c_str();
 1971|   112k|  std::string result2;
 1972|   112k|  std::string newpattern;
 1973|   112k|  struct hentry* rv = nullptr;
 1974|       |
 1975|       |  // search affixed forms with and without derivational suffixes
 1976|   155k|  while (true) {
  ------------------
  |  Branch (1976:10): [True: 155k, Folded]
  ------------------
 1977|   178k|    for (const auto& k : desc) {
  ------------------
  |  Branch (1977:24): [True: 178k, False: 155k]
  ------------------
 1978|   178k|      if (std::chrono::steady_clock::now() - start_time > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|   178k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (1978:11): [True: 0, False: 178k]
  ------------------
 1979|      0|        return result2;
 1980|   178k|      std::string result;
 1981|       |
 1982|       |      // add compound word parts (except the last one)
 1983|   178k|      const char* s = k.c_str();
 1984|   178k|      const char* part = strstr(s, MORPH_PART);
  ------------------
  |  |  116|   178k|#define MORPH_PART "pa:"
  ------------------
 1985|   178k|      if (part) {
  ------------------
  |  Branch (1985:11): [True: 0, False: 178k]
  ------------------
 1986|      0|        const char* nextpart = strstr(part + 1, MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 1987|      0|        while (nextpart) {
  ------------------
  |  Branch (1987:16): [True: 0, False: 0]
  ------------------
 1988|      0|          std::string field;
 1989|      0|          copy_field(field, part, MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 1990|      0|          result.append(field);
 1991|      0|          part = nextpart;
 1992|      0|          nextpart = strstr(part + 1, MORPH_PART);
  ------------------
  |  |  116|      0|#define MORPH_PART "pa:"
  ------------------
 1993|      0|        }
 1994|      0|        s = part;
 1995|      0|      }
 1996|       |
 1997|   178k|      std::string tok(s);
 1998|   178k|      size_t pos = tok.find(" | ");
 1999|   178k|      while (pos != std::string::npos) {
  ------------------
  |  Branch (1999:14): [True: 0, False: 178k]
  ------------------
 2000|      0|        tok[pos + 1] = MSEP_ALT;
  ------------------
  |  |  123|      0|#define MSEP_ALT '\v'
  ------------------
 2001|      0|        pos = tok.find(" | ", pos);
 2002|      0|      }
 2003|   178k|      std::vector<std::string> pl = line_tok(tok, MSEP_ALT);
  ------------------
  |  |  123|   178k|#define MSEP_ALT '\v'
  ------------------
 2004|   178k|      for (auto& i : pl) {
  ------------------
  |  Branch (2004:20): [True: 178k, False: 178k]
  ------------------
 2005|       |        // remove inflectional and terminal suffixes
 2006|   178k|        size_t is = i.find(MORPH_INFL_SFX);
  ------------------
  |  |  110|   178k|#define MORPH_INFL_SFX "is:"
  ------------------
 2007|   178k|        if (is != std::string::npos)
  ------------------
  |  Branch (2007:13): [True: 0, False: 178k]
  ------------------
 2008|      0|          i.resize(is);
 2009|   178k|        size_t ts = i.find(MORPH_TERM_SFX);
  ------------------
  |  |  111|   178k|#define MORPH_TERM_SFX "ts:"
  ------------------
 2010|   178k|        while (ts != std::string::npos) {
  ------------------
  |  Branch (2010:16): [True: 0, False: 178k]
  ------------------
 2011|      0|          i[ts] = '_';
 2012|      0|          ts = i.find(MORPH_TERM_SFX);
  ------------------
  |  |  111|      0|#define MORPH_TERM_SFX "ts:"
  ------------------
 2013|      0|        }
 2014|   178k|        const char* st = strstr(s, MORPH_STEM);
  ------------------
  |  |  103|   178k|#define MORPH_STEM "st:"
  ------------------
 2015|   178k|        if (st) {
  ------------------
  |  Branch (2015:13): [True: 169k, False: 8.69k]
  ------------------
 2016|   169k|          copy_field(tok, st, MORPH_STEM);
  ------------------
  |  |  103|   169k|#define MORPH_STEM "st:"
  ------------------
 2017|   169k|          rv = pAMgr->lookup(tok.c_str(), tok.size());
 2018|   339k|          while (rv) {
  ------------------
  |  Branch (2018:18): [True: 169k, False: 169k]
  ------------------
 2019|   169k|            if (std::chrono::steady_clock::now() - start_time > TIMELIMIT_GLOBAL_MS)
  ------------------
  |  |  104|   169k|#define TIMELIMIT_GLOBAL_MS std::chrono::milliseconds(250)
  ------------------
  |  Branch (2019:17): [True: 0, False: 169k]
  ------------------
 2020|      0|              return result2;
 2021|   169k|            std::string newpat(i);
 2022|   169k|            newpat.append(pattern);
 2023|   169k|            std::string sg = suggest_hentry_gen(rv, newpat.c_str());
 2024|   169k|            if (sg.empty())
  ------------------
  |  Branch (2024:17): [True: 169k, False: 0]
  ------------------
 2025|   169k|              sg = suggest_hentry_gen(rv, pattern);
 2026|   169k|            if (!sg.empty()) {
  ------------------
  |  Branch (2026:17): [True: 0, False: 169k]
  ------------------
 2027|      0|              std::vector<std::string> gen = line_tok(sg, MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2028|      0|              for (auto& j : gen) {
  ------------------
  |  Branch (2028:28): [True: 0, False: 0]
  ------------------
 2029|      0|                result2.push_back(MSEP_REC);
  ------------------
  |  |  122|      0|#define MSEP_REC '\n'
  ------------------
 2030|      0|                result2.append(result);
 2031|      0|                if (i.find(MORPH_SURF_PFX) != std::string::npos) {
  ------------------
  |  |  112|      0|#define MORPH_SURF_PFX "sp:"
  ------------------
  |  Branch (2031:21): [True: 0, False: 0]
  ------------------
 2032|      0|                  std::string field;
 2033|      0|                  copy_field(field, i, MORPH_SURF_PFX);
  ------------------
  |  |  112|      0|#define MORPH_SURF_PFX "sp:"
  ------------------
 2034|      0|                  result2.append(field);
 2035|      0|                }
 2036|      0|                result2.append(j);
 2037|      0|              }
 2038|      0|            }
 2039|   169k|            rv = rv->next_homonym;
 2040|   169k|          }
 2041|   169k|        }
 2042|   178k|      }
 2043|   178k|    }
 2044|       |
 2045|   155k|    if (!result2.empty() || !strstr(pattern, MORPH_DERI_SFX))
  ------------------
  |  |  109|   155k|#define MORPH_DERI_SFX "ds:"
  ------------------
  |  Branch (2045:9): [True: 0, False: 155k]
  |  Branch (2045:29): [True: 112k, False: 43.0k]
  ------------------
 2046|   112k|      break;
 2047|       |
 2048|  43.0k|    newpattern.assign(pattern);
 2049|  43.0k|    mystrrep(newpattern, MORPH_DERI_SFX, MORPH_TERM_SFX);
  ------------------
  |  |  109|  43.0k|#define MORPH_DERI_SFX "ds:"
  ------------------
                  mystrrep(newpattern, MORPH_DERI_SFX, MORPH_TERM_SFX);
  ------------------
  |  |  111|  43.0k|#define MORPH_TERM_SFX "ts:"
  ------------------
 2050|  43.0k|    pattern = newpattern.c_str();
 2051|  43.0k|  }
 2052|   112k|  return result2;
 2053|   112k|}
_ZN10SuggestMgr5ngramEiRKNSt3__16vectorI6w_charNS0_9allocatorIS2_EEEES7_i:
 2059|   614k|                      int opt) {
 2060|   614k|  int nscore = 0, ns, l1 = su1.size(), l2 = su2.size();
 2061|       |
 2062|   614k|  if (l2 == 0)
  ------------------
  |  Branch (2062:7): [True: 6.12k, False: 608k]
  ------------------
 2063|  6.12k|    return 0;
 2064|   935k|  for (int j = 1; j <= n; j++) {
  ------------------
  |  Branch (2064:19): [True: 886k, False: 48.6k]
  ------------------
 2065|   886k|    ns = 0;
 2066|  4.09M|    for (int i = 0; i <= (l1 - j); i++) {
  ------------------
  |  Branch (2066:21): [True: 3.20M, False: 886k]
  ------------------
 2067|  3.20M|      int k = 0;
 2068|  13.0M|      for (int l = 0; l <= (l2 - j); l++) {
  ------------------
  |  Branch (2068:23): [True: 10.8M, False: 2.14M]
  ------------------
 2069|  13.9M|        for (k = 0; k < j; k++) {
  ------------------
  |  Branch (2069:21): [True: 12.8M, False: 1.06M]
  ------------------
 2070|  12.8M|          if (su1[i + k] != su2[l + k])
  ------------------
  |  Branch (2070:15): [True: 9.83M, False: 3.06M]
  ------------------
 2071|  9.83M|            break;
 2072|  12.8M|        }
 2073|  10.8M|        if (k == j) {
  ------------------
  |  Branch (2073:13): [True: 1.06M, False: 9.83M]
  ------------------
 2074|  1.06M|          ns++;
 2075|  1.06M|          break;
 2076|  1.06M|        }
 2077|  10.8M|      }
 2078|  3.20M|      if (k != j && opt & NGRAM_WEIGHTED) {
  ------------------
  |  |   84|  2.14M|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
  |  Branch (2078:11): [True: 2.14M, False: 1.06M]
  |  Branch (2078:21): [True: 83.4k, False: 2.06M]
  ------------------
 2079|  83.4k|        ns--;
 2080|  83.4k|        if (i == 0 || i == l1 - j)
  ------------------
  |  Branch (2080:13): [True: 21.7k, False: 61.7k]
  |  Branch (2080:23): [True: 34.2k, False: 27.5k]
  ------------------
 2081|  55.9k|          ns--;  // side weight
 2082|  83.4k|      }
 2083|  3.20M|    }
 2084|   886k|    nscore = nscore + ns;
 2085|   886k|    if (ns < 2 && !(opt & NGRAM_WEIGHTED))
  ------------------
  |  |   84|   619k|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
  |  Branch (2085:9): [True: 619k, False: 266k]
  |  Branch (2085:19): [True: 560k, False: 59.7k]
  ------------------
 2086|   560k|      break;
 2087|   886k|  }
 2088|       |
 2089|   608k|  ns = 0;
 2090|   608k|  if (opt & NGRAM_LONGER_WORSE)
  ------------------
  |  |   81|   608k|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
  |  Branch (2090:7): [True: 248k, False: 360k]
  ------------------
 2091|   248k|    ns = (l2 - l1) - 2;
 2092|   608k|  if (opt & NGRAM_ANY_MISMATCH)
  ------------------
  |  |   82|   608k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
  |  Branch (2092:7): [True: 360k, False: 248k]
  ------------------
 2093|   360k|    ns = abs(l2 - l1) - 2;
 2094|   608k|  ns = (nscore - ((ns > 0) ? ns : 0));
  ------------------
  |  Branch (2094:19): [True: 101k, False: 507k]
  ------------------
 2095|   608k|  return ns;
 2096|   614k|}
_ZN10SuggestMgr5ngramEiRKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_i:
 2102|   929k|                      int opt) {
 2103|   929k|  int nscore = 0, ns, l1, l2 = s2.size();
 2104|       |
 2105|   929k|  if (l2 == 0)
  ------------------
  |  Branch (2105:7): [True: 12.4k, False: 917k]
  ------------------
 2106|  12.4k|    return 0;
 2107|   917k|  l1 = s1.size();
 2108|  1.70M|  for (int j = 1; j <= n; j++) {
  ------------------
  |  Branch (2108:19): [True: 1.56M, False: 146k]
  ------------------
 2109|  1.56M|    ns = 0;
 2110|  11.0M|    for (int i = 0; i <= (l1 - j); i++) {
  ------------------
  |  Branch (2110:21): [True: 9.53M, False: 1.56M]
  ------------------
 2111|       |      //s2 is haystack, s1[i..i+j) is needle
 2112|  9.53M|      if (s2.find(s1.c_str()+i, 0, j) != std::string::npos) {
  ------------------
  |  Branch (2112:11): [True: 3.54M, False: 5.98M]
  ------------------
 2113|  3.54M|        ns++;
 2114|  5.98M|      } else if (opt & NGRAM_WEIGHTED) {
  ------------------
  |  |   84|  5.98M|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
  |  Branch (2114:18): [True: 383k, False: 5.60M]
  ------------------
 2115|   383k|        ns--;
 2116|   383k|        if (i == 0 || i == l1 - j)
  ------------------
  |  Branch (2116:13): [True: 46.4k, False: 337k]
  |  Branch (2116:23): [True: 122k, False: 214k]
  ------------------
 2117|   169k|          ns--;  // side weight
 2118|   383k|      }
 2119|  9.53M|    }
 2120|  1.56M|    nscore = nscore + ns;
 2121|  1.56M|    if (ns < 2 && !(opt & NGRAM_WEIGHTED))
  ------------------
  |  |   84|   920k|#define NGRAM_WEIGHTED (1 << 3)
  ------------------
  |  Branch (2121:9): [True: 920k, False: 641k]
  |  Branch (2121:19): [True: 770k, False: 149k]
  ------------------
 2122|   770k|      break;
 2123|  1.56M|  }
 2124|       |
 2125|   917k|  ns = 0;
 2126|   917k|  if (opt & NGRAM_LONGER_WORSE)
  ------------------
  |  |   81|   917k|#define NGRAM_LONGER_WORSE (1 << 0)
  ------------------
  |  Branch (2126:7): [True: 341k, False: 575k]
  ------------------
 2127|   341k|    ns = (l2 - l1) - 2;
 2128|   917k|  if (opt & NGRAM_ANY_MISMATCH)
  ------------------
  |  |   82|   917k|#define NGRAM_ANY_MISMATCH (1 << 1)
  ------------------
  |  Branch (2128:7): [True: 575k, False: 341k]
  ------------------
 2129|   575k|    ns = abs(l2 - l1) - 2;
 2130|   917k|  ns = (nscore - ((ns > 0) ? ns : 0));
  ------------------
  |  Branch (2130:19): [True: 195k, False: 721k]
  ------------------
 2131|   917k|  return ns;
 2132|   929k|}
_ZN10SuggestMgr19leftcommonsubstringERKNSt3__16vectorI6w_charNS0_9allocatorIS2_EEEES7_:
 2137|   517k|    const std::vector<w_char>& su2) {
 2138|   517k|  int l1 = su1.size(), l2 = su2.size();
 2139|       |  // decapitalize dictionary word
 2140|   517k|  if (complexprefixes) {
  ------------------
  |  Branch (2140:7): [True: 0, False: 517k]
  ------------------
 2141|      0|    if (l1 && l2 && su1[l1 - 1] == su2[l2 - 1])
  ------------------
  |  Branch (2141:9): [True: 0, False: 0]
  |  Branch (2141:15): [True: 0, False: 0]
  |  Branch (2141:21): [True: 0, False: 0]
  ------------------
 2142|      0|      return 1;
 2143|   517k|  } else {
 2144|   517k|    unsigned short idx = su2.empty() ? 0 : (unsigned short)(su2[0]),
  ------------------
  |  Branch (2144:26): [True: 0, False: 517k]
  ------------------
 2145|   517k|                   otheridx = su1.empty() ? 0 : (unsigned short)(su1[0]);
  ------------------
  |  Branch (2145:31): [True: 18.1k, False: 499k]
  ------------------
 2146|   517k|    if (otheridx != idx && (otheridx != unicodetolower(idx, langnum)))
  ------------------
  |  Branch (2146:9): [True: 485k, False: 32.6k]
  |  Branch (2146:28): [True: 357k, False: 127k]
  ------------------
 2147|   357k|      return 0;
 2148|   160k|    int i;
 2149|   238k|    for (i = 1; (i < l1) && (i < l2) && (su1[i] == su2[i]);
  ------------------
  |  Branch (2149:17): [True: 227k, False: 10.5k]
  |  Branch (2149:29): [True: 216k, False: 11.5k]
  |  Branch (2149:41): [True: 77.8k, False: 138k]
  ------------------
 2150|   160k|         i++)
 2151|  77.8k|      ;
 2152|   160k|    return i;
 2153|   517k|  }
 2154|      0|  return 0;
 2155|   517k|}
_ZN10SuggestMgr19leftcommonsubstringEPKcS1_:
 2160|   733k|    const char* s2) {
 2161|   733k|  if (complexprefixes) {
  ------------------
  |  Branch (2161:7): [True: 60.0k, False: 673k]
  ------------------
 2162|  60.0k|    int l1 = strlen(s1), l2 = strlen(s2);
 2163|  60.0k|    if (l1 && l1 <= l2 && s1[l1 - 1] == s2[l2 - 1])
  ------------------
  |  Branch (2163:9): [True: 58.1k, False: 1.90k]
  |  Branch (2163:15): [True: 28.2k, False: 29.9k]
  |  Branch (2163:27): [True: 2.53k, False: 25.6k]
  ------------------
 2164|  2.53k|      return 1;
 2165|   673k|  } else if (csconv) {
  ------------------
  |  Branch (2165:14): [True: 673k, False: 0]
  ------------------
 2166|   673k|    const char* olds = s1;
 2167|       |    // decapitalise dictionary word
 2168|   673k|    if ((*s1 != *s2) && (((unsigned char)*s1) != csconv[((unsigned char)*s2)].clower))
  ------------------
  |  Branch (2168:9): [True: 609k, False: 64.2k]
  |  Branch (2168:25): [True: 430k, False: 178k]
  ------------------
 2169|   430k|      return 0;
 2170|   488k|    do {
 2171|   488k|      s1++;
 2172|   488k|      s2++;
 2173|   488k|    } while ((*s1 == *s2) && (*s1 != '\0'));
  ------------------
  |  Branch (2173:14): [True: 246k, False: 242k]
  |  Branch (2173:30): [True: 245k, False: 555]
  ------------------
 2174|   243k|    return (int)(s1 - olds);
 2175|   673k|  }
 2176|  57.4k|  return 0;
 2177|   733k|}
_ZN10SuggestMgr24commoncharacterpositionsEPKcS1_Pi:
 2181|  77.2k|                                         int* is_swap) {
 2182|  77.2k|  int num = 0, diff = 0, diffpos[2];
 2183|  77.2k|  *is_swap = 0;
 2184|  77.2k|  if (utf8) {
  ------------------
  |  Branch (2184:7): [True: 20.6k, False: 56.6k]
  ------------------
 2185|  20.6k|    std::vector<w_char> su1;
 2186|  20.6k|    std::vector<w_char> su2;
 2187|  20.6k|    int l1 = u8_u16(su1, s1), l2 = u8_u16(su2, s2);
 2188|       |
 2189|  20.6k|    if (l1 <= 0 || l2 <= 0)
  ------------------
  |  Branch (2189:9): [True: 3.78k, False: 16.8k]
  |  Branch (2189:20): [True: 0, False: 16.8k]
  ------------------
 2190|  3.78k|      return 0;
 2191|       |
 2192|       |    // decapitalize dictionary word
 2193|  16.8k|    if (complexprefixes) {
  ------------------
  |  Branch (2193:9): [True: 0, False: 16.8k]
  ------------------
 2194|      0|      su2[l2 - 1] = lower_utf(su2[l2 - 1], langnum);
 2195|  16.8k|    } else {
 2196|  16.8k|      su2[0] = lower_utf(su2[0], langnum);
 2197|  16.8k|    }
 2198|  60.9k|    for (int i = 0; (i < l1) && (i < l2); i++) {
  ------------------
  |  Branch (2198:21): [True: 48.6k, False: 12.3k]
  |  Branch (2198:33): [True: 44.1k, False: 4.46k]
  ------------------
 2199|  44.1k|      if (su1[i] == su2[i]) {
  ------------------
  |  Branch (2199:11): [True: 24.2k, False: 19.9k]
  ------------------
 2200|  24.2k|        num++;
 2201|  24.2k|      } else {
 2202|  19.9k|        if (diff < 2)
  ------------------
  |  Branch (2202:13): [True: 18.2k, False: 1.66k]
  ------------------
 2203|  18.2k|          diffpos[diff] = i;
 2204|  19.9k|        diff++;
 2205|  19.9k|      }
 2206|  44.1k|    }
 2207|  16.8k|    if ((diff == 2) && (l1 == l2) &&
  ------------------
  |  Branch (2207:9): [True: 3.43k, False: 13.3k]
  |  Branch (2207:24): [True: 1.00k, False: 2.43k]
  ------------------
 2208|  1.00k|        (su1[diffpos[0]] == su2[diffpos[1]]) &&
  ------------------
  |  Branch (2208:9): [True: 249, False: 756]
  ------------------
 2209|    249|        (su1[diffpos[1]] == su2[diffpos[0]]))
  ------------------
  |  Branch (2209:9): [True: 70, False: 179]
  ------------------
 2210|     70|      *is_swap = 1;
 2211|  56.6k|  } else {
 2212|  56.6k|    size_t i;
 2213|  56.6k|    std::string t(s2);
 2214|       |    // decapitalize dictionary word
 2215|  56.6k|    if (complexprefixes) {
  ------------------
  |  Branch (2215:9): [True: 3.26k, False: 53.3k]
  ------------------
 2216|  3.26k|      size_t l2 = t.size();
 2217|  3.26k|      t[l2 - 1] = csconv[(unsigned char)t[l2 - 1]].clower;
 2218|  53.3k|    } else {
 2219|  53.3k|      mkallsmall(t, csconv);
 2220|  53.3k|    }
 2221|   288k|    for (i = 0; i < t.size() && (*(s1 + i) != 0); ++i) {
  ------------------
  |  Branch (2221:17): [True: 263k, False: 25.6k]
  |  Branch (2221:33): [True: 232k, False: 30.9k]
  ------------------
 2222|   232k|      if (*(s1 + i) == t[i]) {
  ------------------
  |  Branch (2222:11): [True: 124k, False: 108k]
  ------------------
 2223|   124k|        num++;
 2224|   124k|      } else {
 2225|   108k|        if (diff < 2)
  ------------------
  |  Branch (2225:13): [True: 66.0k, False: 42.0k]
  ------------------
 2226|  66.0k|          diffpos[diff] = i;
 2227|   108k|        diff++;
 2228|   108k|      }
 2229|   232k|    }
 2230|  56.6k|    if ((diff == 2) && (*(s1 + i) == 0) && i == t.size() &&
  ------------------
  |  Branch (2230:9): [True: 12.6k, False: 43.9k]
  |  Branch (2230:24): [True: 10.3k, False: 2.34k]
  |  Branch (2230:44): [True: 3.52k, False: 6.80k]
  ------------------
 2231|  3.52k|        (*(s1 + diffpos[0]) == t[diffpos[1]]) &&
  ------------------
  |  Branch (2231:9): [True: 643, False: 2.88k]
  ------------------
 2232|    643|        (*(s1 + diffpos[1]) == t[diffpos[0]]))
  ------------------
  |  Branch (2232:9): [True: 100, False: 543]
  ------------------
 2233|    100|      *is_swap = 1;
 2234|  56.6k|  }
 2235|  73.4k|  return num;
 2236|  77.2k|}
_ZN10SuggestMgr10bubblesortEPPcS1_Pii:
 2247|  97.8k|void SuggestMgr::bubblesort(char** rword, char** rword2, int* rsc, int n) {
 2248|  97.8k|  int m = 1;
 2249|  19.0M|  while (m < n) {
  ------------------
  |  Branch (2249:10): [True: 18.9M, False: 97.8k]
  ------------------
 2250|  18.9M|    int j = m;
 2251|  39.2M|    while (j > 0) {
  ------------------
  |  Branch (2251:12): [True: 39.2M, False: 27.6k]
  ------------------
 2252|  39.2M|      if (rsc[j - 1] < rsc[j]) {
  ------------------
  |  Branch (2252:11): [True: 20.3M, False: 18.8M]
  ------------------
 2253|  20.3M|        int sctmp = rsc[j - 1];
 2254|  20.3M|        char* wdtmp = rword[j - 1];
 2255|  20.3M|        rsc[j - 1] = rsc[j];
 2256|  20.3M|        rword[j - 1] = rword[j];
 2257|  20.3M|        rsc[j] = sctmp;
 2258|  20.3M|        rword[j] = wdtmp;
 2259|  20.3M|        if (rword2) {
  ------------------
  |  Branch (2259:13): [True: 19.7M, False: 587k]
  ------------------
 2260|  19.7M|          wdtmp = rword2[j - 1];
 2261|  19.7M|          rword2[j - 1] = rword2[j];
 2262|  19.7M|          rword2[j] = wdtmp;
 2263|  19.7M|        }
 2264|  20.3M|        j--;
 2265|  20.3M|      } else
 2266|  18.8M|        break;
 2267|  39.2M|    }
 2268|  18.9M|    m++;
 2269|  18.9M|  }
 2270|  97.8k|}
_ZN10SuggestMgr3lcsEPKcS1_PiS2_:
 2276|  86.6k|                      int* l2) {
 2277|  86.6k|  int n, m, i, j;
 2278|  86.6k|  std::vector<w_char> su;
 2279|  86.6k|  std::vector<w_char> su2;
 2280|  86.6k|  if (utf8) {
  ------------------
  |  Branch (2280:7): [True: 22.3k, False: 64.2k]
  ------------------
 2281|  22.3k|    m = u8_u16(su, s);
 2282|  22.3k|    n = u8_u16(su2, s2);
 2283|  64.2k|  } else {
 2284|  64.2k|    m = strlen(s);
 2285|  64.2k|    n = strlen(s2);
 2286|  64.2k|  }
 2287|  86.6k|  if (m <= 0 || n <= 0) {
  ------------------
  |  Branch (2287:7): [True: 9.60k, False: 76.9k]
  |  Branch (2287:17): [True: 0, False: 76.9k]
  ------------------
 2288|  9.60k|    *l1 = 0;
 2289|  9.60k|    *l2 = 0;
 2290|  9.60k|    return nullptr;
 2291|  9.60k|  }
 2292|  76.9k|  char* c = new char[(m + 1) * (n + 1)]();
 2293|  76.9k|  char* b = new char[(m + 1) * (n + 1)]();
 2294|   441k|  for (i = 1; i <= m; i++) {
  ------------------
  |  Branch (2294:15): [True: 364k, False: 76.9k]
  ------------------
 2295|  3.47M|    for (j = 1; j <= n; j++) {
  ------------------
  |  Branch (2295:17): [True: 3.10M, False: 364k]
  ------------------
 2296|  3.10M|      if (((utf8) && (su[i - 1] == su2[j - 1])) ||
  ------------------
  |  Branch (2296:12): [True: 209k, False: 2.89M]
  |  Branch (2296:22): [True: 51.7k, False: 157k]
  ------------------
 2297|  3.05M|          ((!utf8) && (s[i - 1] == s2[j - 1]))) {
  ------------------
  |  Branch (2297:12): [True: 2.89M, False: 157k]
  |  Branch (2297:23): [True: 349k, False: 2.54M]
  ------------------
 2298|   401k|        c[i * (n + 1) + j] = c[(i - 1) * (n + 1) + j - 1] + 1;
 2299|   401k|        b[i * (n + 1) + j] = LCS_UPLEFT;
 2300|  2.70M|      } else if (c[(i - 1) * (n + 1) + j] >= c[i * (n + 1) + j - 1]) {
  ------------------
  |  Branch (2300:18): [True: 1.88M, False: 819k]
  ------------------
 2301|  1.88M|        c[i * (n + 1) + j] = c[(i - 1) * (n + 1) + j];
 2302|  1.88M|        b[i * (n + 1) + j] = LCS_UP;
 2303|  1.88M|      } else {
 2304|   819k|        c[i * (n + 1) + j] = c[i * (n + 1) + j - 1];
 2305|   819k|        b[i * (n + 1) + j] = LCS_LEFT;
 2306|   819k|      }
 2307|  3.10M|    }
 2308|   364k|  }
 2309|  76.9k|  delete[] c;
 2310|  76.9k|  *l1 = m;
 2311|  76.9k|  *l2 = n;
 2312|  76.9k|  return b;
 2313|  86.6k|}
_ZN10SuggestMgr6lcslenEPKcS1_:
 2315|  86.6k|int SuggestMgr::lcslen(const char* s, const char* s2) {
 2316|  86.6k|  int m, n, len = 0;
 2317|  86.6k|  char* result = lcs(s, s2, &m, &n);
 2318|  86.6k|  if (!result)
  ------------------
  |  Branch (2318:7): [True: 9.60k, False: 76.9k]
  ------------------
 2319|  9.60k|    return 0;
 2320|  76.9k|  int i = m, j = n;
 2321|   589k|  while ((i != 0) && (j != 0)) {
  ------------------
  |  Branch (2321:10): [True: 518k, False: 71.1k]
  |  Branch (2321:22): [True: 512k, False: 5.85k]
  ------------------
 2322|   512k|    if (result[i * (n + 1) + j] == LCS_UPLEFT) {
  ------------------
  |  Branch (2322:9): [True: 212k, False: 299k]
  ------------------
 2323|   212k|      len++;
 2324|   212k|      i--;
 2325|   212k|      j--;
 2326|   299k|    } else if (result[i * (n + 1) + j] == LCS_UP) {
  ------------------
  |  Branch (2326:16): [True: 140k, False: 159k]
  ------------------
 2327|   140k|      i--;
 2328|   140k|    } else
 2329|   159k|      j--;
 2330|   512k|  }
 2331|  76.9k|  delete[] result;
 2332|  76.9k|  return len;
 2333|  86.6k|}
_ZN10SuggestMgr6lcslenERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_:
 2335|  7.09k|int SuggestMgr::lcslen(const std::string& s, const std::string& s2) {
 2336|  7.09k|  return lcslen(s.c_str(), s2.c_str());
 2337|  7.09k|}
suggestmgr.cxx:_ZN12_GLOBAL__N_115ngsuggest_guardC2EbPK7cs_infoPiPS3_:
 1156|  59.6k|      : m_nonbmp(nonbmp)
 1157|  59.6k|      , m_origconv(origconv)
 1158|  59.6k|      , m_utf8(utf8)
 1159|  59.6k|      , m_csconv(csconv)
 1160|  59.6k|    {
 1161|  59.6k|    }
suggestmgr.cxx:_ZN12_GLOBAL__N_115ngsuggest_guardD2Ev:
 1164|  59.6k|    {
 1165|  59.6k|      if (m_nonbmp) {
  ------------------
  |  Branch (1165:11): [True: 1.96k, False: 57.7k]
  ------------------
 1166|  1.96k|        *m_csconv = m_origconv;
 1167|  1.96k|        *m_utf8 = 1;
 1168|  1.96k|      }
 1169|  59.6k|    }
suggestmgr.cxx:_ZL12get_sfxcountPKc:
 1894|   678k|static int get_sfxcount(const char* morph) {
 1895|   678k|  if (!morph || !*morph)
  ------------------
  |  Branch (1895:7): [True: 339k, False: 339k]
  |  Branch (1895:17): [True: 0, False: 339k]
  ------------------
 1896|   339k|    return 0;
 1897|   339k|  int n = 0;
 1898|   339k|  const char* old = morph;
 1899|   339k|  morph = strstr(morph, MORPH_DERI_SFX);
  ------------------
  |  |  109|   339k|#define MORPH_DERI_SFX "ds:"
  ------------------
 1900|   339k|  if (!morph)
  ------------------
  |  Branch (1900:7): [True: 243k, False: 95.5k]
  ------------------
 1901|   243k|    morph = strstr(old, MORPH_INFL_SFX);
  ------------------
  |  |  110|   243k|#define MORPH_INFL_SFX "is:"
  ------------------
 1902|   339k|  if (!morph)
  ------------------
  |  Branch (1902:7): [True: 243k, False: 95.7k]
  ------------------
 1903|   243k|    morph = strstr(old, MORPH_TERM_SFX);
  ------------------
  |  |  111|   243k|#define MORPH_TERM_SFX "ts:"
  ------------------
 1904|   612k|  while (morph) {
  ------------------
  |  Branch (1904:10): [True: 272k, False: 339k]
  ------------------
 1905|   272k|    n++;
 1906|   272k|    old = morph;
 1907|   272k|    morph = strstr(morph + 1, MORPH_DERI_SFX);
  ------------------
  |  |  109|   272k|#define MORPH_DERI_SFX "ds:"
  ------------------
 1908|   272k|    if (!morph)
  ------------------
  |  Branch (1908:9): [True: 236k, False: 36.2k]
  ------------------
 1909|   236k|      morph = strstr(old + 1, MORPH_INFL_SFX);
  ------------------
  |  |  110|   236k|#define MORPH_INFL_SFX "is:"
  ------------------
 1910|   272k|    if (!morph)
  ------------------
  |  Branch (1910:9): [True: 227k, False: 45.3k]
  ------------------
 1911|   227k|      morph = strstr(old + 1, MORPH_TERM_SFX);
  ------------------
  |  |  111|   227k|#define MORPH_TERM_SFX "ts:"
  ------------------
 1912|   272k|  }
 1913|   339k|  return n;
 1914|   678k|}

_ZNK6w_charcvtEv:
   57|   194M|  {
   58|   194M|#if defined(_WIN32) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__))  || defined(__LITTLE_ENDIAN__)
   59|       |    //use little-endian optimized version
   60|       |#if (__cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) && defined __cpp_lib_bit_cast && __cpp_lib_bit_cast >= 201806L
   61|       |    return std::bit_cast<unsigned short>(*this);
   62|       |#else
   63|   194M|    unsigned short u;
   64|   194M|    memcpy(&u, this, sizeof(unsigned short));
   65|   194M|    return u;
   66|   194M|#endif
   67|       |
   68|       |#else
   69|       |    return ((unsigned short)h << 8) | (unsigned short)l;
   70|       |#endif
   71|   194M|  }
_Zlt6w_charS_:
   73|  9.69M|  friend bool operator<(const w_char a, const w_char b) {
   74|  9.69M|    return (unsigned short)a < (unsigned short)b;
   75|  9.69M|  }
_Zeq6w_charS_:
   77|  75.7M|  friend bool operator==(const w_char a, const w_char b) {
   78|  75.7M|    return (unsigned short)a == (unsigned short)b;
   79|  75.7M|  }
_Zne6w_charS_:
   81|  73.6M|  friend bool operator!=(const w_char a, const w_char b) {
   82|  73.6M|    return !(a == b);
   83|  73.6M|  }

_Z8endswithRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES7_:
   40|    198|{
   41|    198|    return str.size() >= suffix.size() &&
  ------------------
  |  Branch (41:12): [True: 190, False: 8]
  ------------------
   42|    190|           str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
  ------------------
  |  Branch (42:12): [True: 38, False: 152]
  ------------------
   43|    198|}
LLVMFuzzerInitialize:
   46|      2|{
   47|      2|    char* exe_path = (*argv)[0];
   48|       |    // dirname() can modify its argument.
   49|      2|    char* exe_path_copy = strdup(exe_path);
   50|      2|    char* dir = dirname(exe_path_copy);
   51|      2|    DIR* d = opendir(dir);
   52|      2|    struct dirent *direntry;
   53|      2|    std::vector<std::string> affs;
   54|    200|    while ((direntry = readdir(d)) != NULL)
  ------------------
  |  Branch (54:12): [True: 198, False: 2]
  ------------------
   55|    198|    {
   56|    198|        std::string entry(direntry->d_name);
   57|    198|        if (endswith(entry, ".aff"))
  ------------------
  |  Branch (57:13): [True: 38, False: 160]
  ------------------
   58|     38|            affs.push_back(std::move(entry));
   59|    198|    }
   60|      2|    closedir(d);
   61|      2|    free(exe_path_copy);
   62|       |
   63|       |    // sort so dict iteration order is reproducible across runs regardless of
   64|       |    // readdir ordering; a failing input then reproduces against the same dict
   65|      2|    std::sort(affs.begin(), affs.end());
   66|      2|    for (const auto& entry : affs)
  ------------------
  |  Branch (66:28): [True: 38, False: 2]
  ------------------
   67|     38|    {
   68|     38|        std::string dic = entry.substr(0, entry.size() - 4) + ".dic";
   69|     38|        dictionaries.emplace_back(new Hunspell(entry.c_str(), dic.c_str()));
   70|     38|    }
   71|       |
   72|      2|    return 0;
   73|      2|}
LLVMFuzzerTestOneInput:
   76|  3.08k|{
   77|  3.08k|    std::string word(data, size);
   78|  3.08k|    for (auto& dict : dictionaries)
  ------------------
  |  Branch (78:21): [True: 58.5k, False: 3.08k]
  ------------------
   79|  58.5k|    {
   80|  58.5k|        if (!dict->spell(word))
  ------------------
  |  Branch (80:13): [True: 58.1k, False: 381]
  ------------------
   81|  58.1k|            dict->suggest(word);
   82|  58.5k|    }
   83|  3.08k|    return 0;
   84|  3.08k|}

