slang_clear(slang_T *lp)
{
    garray_T	*gap;
    fromto_T	*ftp;
    salitem_T	*smp;
    int		i;
    int		round;

    VIM_CLEAR(lp->sl_fbyts);
    VIM_CLEAR(lp->sl_kbyts);
    VIM_CLEAR(lp->sl_pbyts);

    VIM_CLEAR(lp->sl_fidxs);
    VIM_CLEAR(lp->sl_kidxs);
    VIM_CLEAR(lp->sl_pidxs);

    for (round = 1; round <= 2; ++round)
    {
	gap = round == 1 ? &lp->sl_rep : &lp->sl_repsal;
	while (gap->ga_len > 0)
	{
	    ftp = &((fromto_T *)gap->ga_data)[--gap->ga_len];
	    vim_free(ftp->ft_from);
	    vim_free(ftp->ft_to);
	}
	ga_clear(gap);
    }

    gap = &lp->sl_sal;
    if (lp->sl_sofo)
    {
	// "ga_len" is set to 1 without adding an item for latin1
	if (gap->ga_data != NULL)
	    // SOFOFROM and SOFOTO items: free lists of wide characters.
	    for (i = 0; i < gap->ga_len; ++i)
		vim_free(((int **)gap->ga_data)[i]);
    }
    else
	// SAL items: free salitem_T items
	while (gap->ga_len > 0)
	{
	    smp = &((salitem_T *)gap->ga_data)[--gap->ga_len];
	    vim_free(smp->sm_lead);
	    // Don't free sm_oneof and sm_rules, they point into sm_lead.
	    vim_free(smp->sm_to);
	    vim_free(smp->sm_lead_w);
	    vim_free(smp->sm_oneof_w);
	    vim_free(smp->sm_to_w);
	}
    ga_clear(gap);

    for (i = 0; i < lp->sl_prefixcnt; ++i)
	vim_regfree(lp->sl_prefprog[i]);
    lp->sl_prefixcnt = 0;
    VIM_CLEAR(lp->sl_prefprog);

    VIM_CLEAR(lp->sl_info);

    VIM_CLEAR(lp->sl_midword);

    vim_regfree(lp->sl_compprog);
    lp->sl_compprog = NULL;
    VIM_CLEAR(lp->sl_comprules);
    VIM_CLEAR(lp->sl_compstartflags);
    VIM_CLEAR(lp->sl_compallflags);

    VIM_CLEAR(lp->sl_syllable);
    ga_clear(&lp->sl_syl_items);

    ga_clear_strings(&lp->sl_comppat);

    hash_clear_all(&lp->sl_wordcount, WC_KEY_OFF);
    hash_init(&lp->sl_wordcount);

    hash_clear_all(&lp->sl_map_hash, 0);

    // Clear info from .sug file.
    slang_clear_sug(lp);

    lp->sl_compmax = MAXWLEN;
    lp->sl_compminlen = 0;
    lp->sl_compsylmax = MAXWLEN;
    lp->sl_regions[0] = NUL;
}
Unknown