Exemple #1
0
FCITX_EXPORT_API
void FcitxInstanceCommitString(FcitxInstance* instance, FcitxInputContext* ic, const char* str)
{
    if (str == NULL)
        return ;

    if (ic == NULL)
        return;

    char *pstr = FcitxInstanceProcessCommitFilter(instance, str);
    if (pstr != NULL)
        str = pstr;

    FcitxAddon **pfrontend = FcitxInstanceGetPFrontend(instance, ic->frontendid);
    if (pfrontend == NULL)
        return;
    FcitxFrontend* frontend = (*pfrontend)->frontend;
    frontend->CommitString((*pfrontend)->addonInstance, ic, str);

    FcitxInputState* input = instance->input;
    fcitx_utf8_strncpy(input->strLastCommit, str, MAX_USER_INPUT);
    input->strLastCommit[MAX_USER_INPUT] = '\0';
    instance->iHZInputed += (int)(fcitx_utf8_strlen(str));

    if (pstr)
        free(pstr);
}
Exemple #2
0
char* ProcessFullWidthChar(void* arg, const char* str)
{
    FcitxFullWidthChar* fwchar = (FcitxFullWidthChar*)arg;
    FcitxProfile* profile = FcitxInstanceGetProfile(fwchar->owner);
    if (profile->bUseFullWidthChar) {
        size_t i = 0, ret_len = 0, len = fcitx_utf8_strlen(str);
        char* ret = (char *) fcitx_utils_malloc0(sizeof(char) * (UTF8_MAX_LENGTH * len + 1));
        const char* ps = str;
        ret[0] = '\0';
        for (; i < len; ++i) {
            int wc;
            int chr_len = fcitx_utf8_char_len(ps);
            char *nps;
            nps = fcitx_utf8_get_char(ps , &wc);

            if (chr_len == 1 && ps[0] >= '\x20' && ps[0] <= '\x7e') {
                strcat(ret, sCornerTrans[ps[0] - 32]);
                ret_len += strlen(sCornerTrans[ps[0] - 32]);
            } else {
                strncat(ret, ps, chr_len);
                ret_len += chr_len;
            }

            ps = nps;

        }
        ret[ret_len] = '\0';
        return ret;
    }
    else
        return NULL;
}
Exemple #3
0
static void
_fcitx_im_context_update_preedit_cb(DBusGProxy* proxy, char* str, int cursor_pos, void* user_data)
{
    FcitxLog(LOG_LEVEL, "_fcitx_im_context_commit_string_cb");
    FcitxIMContext* context =  FCITX_IM_CONTEXT(user_data);

    gboolean visible = false;

    if (context->preedit_string != NULL) {
        if (strlen(context->preedit_string) != 0)
            visible = true;
        g_free(context->preedit_string);
        context->preedit_string = NULL;
    }
    context->preedit_string = g_strdup(str);
    char* tempstr = g_strndup(str, cursor_pos);
    context->cursor_pos =  fcitx_utf8_strlen(tempstr);
    g_free(tempstr);

    gboolean new_visible = false;

    if (context->preedit_string != NULL) {
        if (strlen(context->preedit_string) != 0)
            new_visible = true;
    }
    gboolean flag = new_visible != visible;

    if (new_visible) {
        if (flag) {
            /* invisible => visible */
            g_signal_emit(context, _signal_preedit_start_id, 0);
        }
        g_signal_emit(context, _signal_preedit_changed_id, 0);
    } else {
        if (flag) {
            /* visible => invisible */
            g_signal_emit(context, _signal_preedit_changed_id, 0);
            g_signal_emit(context, _signal_preedit_end_id, 0);
        } else {
            /* still invisible */
            /* do nothing */
        }
    }

    g_signal_emit(context, _signal_preedit_changed_id, 0);
}
Exemple #4
0
/**
 * @brief get the candidate word by index
 *
 * @param iIndex index of candidate word
 * @return the string of canidate word
 **/
__EXPORT_API
INPUT_RETURN_VALUE FcitxLibpinyinGetCandWord (void* arg, FcitxCandidateWord* candWord)
{
    FcitxLibpinyin* libpinyin = (FcitxLibpinyin* )arg;
    FcitxLibpinyinCandWord* pyCand = (FcitxLibpinyinCandWord*) candWord->priv;
    FcitxInstance* instance = libpinyin->owner->owner;
    FcitxInputState* input = FcitxInstanceGetInputState(instance);

    if (pyCand->ispunc) {
        strcpy(FcitxInputStateGetOutputString(input), candWord->strWord);
        return IRV_COMMIT_STRING;
    } else {
        if (!libpinyin->candidate || libpinyin->candidate->len <= pyCand->idx)
            return IRV_TO_PROCESS;
        lookup_candidate_t* cand = &g_array_index(libpinyin->candidate, lookup_candidate_t, pyCand->idx);
        pinyin_choose_candidate(libpinyin->inst, LibpinyinGetOffset(libpinyin), cand);

        FcitxLibpinyinFixed f;
        f.len = fcitx_utf8_strlen(cand->m_phrase_string);
        g_array_append_val(libpinyin->fixed_string, f);

        int offset = LibpinyinGetOffset(libpinyin);
        if (offset >= libpinyin->inst->m_pinyin_keys->len)
        {
            char* sentence = NULL;
            pinyin_guess_sentence(libpinyin->inst);
            sentence = LibpinyinGetSentence(libpinyin);
            if (sentence) {
                strcpy(FcitxInputStateGetOutputString(input), sentence);
                g_free(sentence);
                pinyin_train(libpinyin->inst);
            }
            else
                strcpy(FcitxInputStateGetOutputString(input), "");

            return IRV_COMMIT_STRING;
        }

        int pyoffset = LibpinyinGetPinyinOffset(libpinyin);
        if (pyoffset > libpinyin->cursor_pos)
            libpinyin->cursor_pos = pyoffset;

        return IRV_DISPLAY_CANDWORDS;
    }
    return IRV_TO_PROCESS;
}
Exemple #5
0
static int
SpellCustomGetDistance(SpellCustomDict *custom_dict, const char *word,
                       const char *dict, int word_len)
{
#define REPLACE_WEIGHT 3
#define INSERT_WEIGHT 3
#define REMOVE_WEIGHT 3
#define END_WEIGHT 1
    /*
     * three kinds of error, replace, insert and remove
     * replace means apple vs aplle
     * insert means apple vs applee
     * remove means apple vs aple
     *
     * each error need to follow a correct match.
     *
     * number of "remove error" shoud be no more than "maxremove"
     * while maxremove equals to (length - 2) / 3
     *
     * and the total error number should be no more than "maxdiff"
     * while maxdiff equales to length / 3.
     */
    int replace = 0;
    int insert = 0;
    int remove = 0;
    int diff = 0;
    int maxdiff;
    int maxremove;
    unsigned int cur_word_c;
    unsigned int cur_dict_c;
    unsigned int next_word_c;
    unsigned int next_dict_c;
    maxdiff = word_len / 3;
    maxremove = (word_len - 2) / 3;
    word = fcitx_utf8_get_char(word, &cur_word_c);
    dict = fcitx_utf8_get_char(dict, &cur_dict_c);
    while ((diff = replace + insert + remove) <= maxdiff &&
           remove <= maxremove) {
        /*
         * cur_word_c and cur_dict_c are the current characters
         * and dict and word are pointing to the next one.
         */
        if (!cur_word_c) {
            return ((replace * REPLACE_WEIGHT + insert * INSERT_WEIGHT
                     + remove * REMOVE_WEIGHT) +
                    (cur_dict_c ?
                     (fcitx_utf8_strlen(dict) + 1) * END_WEIGHT : 0));
        }
        word = fcitx_utf8_get_char(word, &next_word_c);

        /* check remove error */
        if (!cur_dict_c) {
            if (next_word_c)
                return -1;
            remove++;
            if (diff <= maxdiff && remove <= maxremove) {
                return (replace * REPLACE_WEIGHT + insert * INSERT_WEIGHT
                        + remove * REMOVE_WEIGHT);
            }
            return -1;
        }
        dict = fcitx_utf8_get_char(dict, &next_dict_c);
        if (cur_word_c == cur_dict_c ||
            (custom_dict->word_comp_func &&
             custom_dict->word_comp_func(cur_word_c, cur_dict_c))) {
            cur_word_c = next_word_c;
            cur_dict_c = next_dict_c;
            continue;
        }
        if (next_word_c == cur_dict_c ||
            (custom_dict->word_comp_func && next_word_c &&
             custom_dict->word_comp_func(next_word_c, cur_dict_c))) {
            word = fcitx_utf8_get_char(word, &cur_word_c);
            cur_dict_c = next_dict_c;
            remove++;
            continue;
        }

        /* check insert error */
        if (cur_word_c == next_dict_c ||
            (custom_dict->word_comp_func && next_dict_c &&
             custom_dict->word_comp_func(cur_word_c, next_dict_c))) {
            cur_word_c = next_word_c;
            dict = fcitx_utf8_get_char(dict, &cur_dict_c);
            insert++;
            continue;
        }

        /* check replace error */
        if (next_word_c == next_dict_c ||
            (custom_dict->word_comp_func && next_word_c && next_dict_c &&
             custom_dict->word_comp_func(next_word_c, next_dict_c))) {
            if (next_word_c) {
                dict = fcitx_utf8_get_char(dict, &cur_dict_c);
                word = fcitx_utf8_get_char(word, &cur_word_c);
            } else {
                cur_word_c = 0;
                cur_dict_c = 0;
            }
            replace++;
            continue;
        }
        break;
    }
    return -1;
}
Exemple #6
0
SpellHint*
SpellCustomHintWords(FcitxSpell *spell, unsigned int len_limit)
{
    SpellCustomCWord clist[len_limit + 1];
    int i;
    unsigned int num = 0;
    int word_type = 0;
    SpellCustomDict *dict = spell->custom_dict;
    const char *word;
    const char *prefix = NULL;
    int prefix_len = 0;
    const char *real_word;
    SpellHint *res;
    int word_len;
    if (!SpellCustomCheck(spell))
        return NULL;
    if (!*spell->current_str)
        return NULL;
    word = spell->current_str;
    real_word = word;
    if (dict->delim && *dict->delim) {
        size_t delta;
        while (real_word[delta = strcspn(real_word, dict->delim)]) {
            prefix = word;
            real_word += delta + 1;
        }
        prefix_len = prefix ? real_word - prefix : 0;
    }
    if (!*real_word)
        return NULL;
    if (dict->word_check_func)
        word_type = dict->word_check_func(real_word);
    word_len = fcitx_utf8_strlen(real_word);
    for (i = 0;i < dict->words_count;i++) {
        int dist;
        if ((dist = SpellCustomGetDistance(
                 dict, real_word, dict->map + dict->words[i], word_len)) >= 0) {
            int j = num;
            clist[j].word = dict->map + dict->words[i];
            clist[j].dist = dist;
            if (num < len_limit)
                num++;
            for (;j > 0;j--) {
                if (SpellCustomCWordCompare(clist + j - 1, clist + j) > 0) {
                    SpellCustomCWord tmp = clist[j];
                    clist[j] = clist[j - 1];
                    clist[j - 1] = tmp;
                    continue;
                }
                break;
            }
        }
    }
    res = SpellHintListWithPrefix(num, prefix, prefix_len,
                                  &clist->word, sizeof(SpellCustomCWord));
    if (!res)
        return NULL;
    if (dict->hint_cmplt_func)
        dict->hint_cmplt_func(res, word_type);
    return res;
}
Exemple #7
0
/**
 * 该函数装载data/gbks2t.tab的简体转繁体的码表,
 * 然后按码表将GBK字符转换成GBK繁体字符。
 *
 * WARNING: 该函数返回新分配内存字符串,请调用者
 * 注意释放。
 */
char *ConvertGBKTradition2Simple(FcitxChttrans* transState, const char *strHZ)
{
    if (strHZ == NULL)
        return NULL;

    switch (transState->engine) {
    case ENGINE_OPENCC:
#ifdef ENABLE_OPENCC
        do {
            if (transState->odt2s == NULL) {
                OpenCCInit(transState);
                if (transState->odt2s == NULL) {
                    break;
                }
            }

            char * res = OpenCCConvert(transState->odt2s, strHZ, (size_t) - 1);

            if (!res || res == (char *) - 1) {
                return NULL;
            }

            return res;
        } while(0);
#endif
    case ENGINE_NATIVE: {
        FILE           *fp;
        char           *ret;
        int             i, len, ret_len;
        const char     *ps;

        if (!transState->t2s_table) {
            char *strBuf = NULL;
            size_t bufLen = 0;
            fp = FcitxXDGGetFileWithPrefix("data", TABLE_GBKS2T, "r", NULL);
            if (!fp) {
                ret = (char *) malloc(sizeof(char) * (strlen(strHZ) + 1));
                strcpy(ret, strHZ);
                return ret;
            }
            while (getline(&strBuf, &bufLen, fp) != -1) {
                simple2trad_t *t2s = NULL;
                char *ps;
                uint32_t wc;

                ps = fcitx_utf8_get_char(strBuf, &wc);
                HASH_FIND_INT(transState->s2t_table, &wc, t2s);
                if (t2s) {
                    continue;
                }
                t2s = (simple2trad_t*) malloc(sizeof(simple2trad_t));

                fcitx_utf8_get_char(ps, &wc);
                t2s->wc = wc;
                t2s->len = fcitx_utf8_char_len(strBuf);
                strncpy(t2s->str, strBuf, t2s->len);
                t2s->str[t2s->len] = '\0';

                HASH_ADD_INT(transState->t2s_table, wc, t2s);
            }
            fcitx_utils_free(strBuf);
        }

        i = 0;
        len = fcitx_utf8_strlen(strHZ);
        ret_len = 0;
        ret = fcitx_utils_malloc0(UTF8_MAX_LENGTH * len + 1);
        ps = strHZ;
        ret[0] = '\0';
        for (; i < len; ++i) {
            uint32_t wc;
            simple2trad_t *t2s = NULL;
            int chr_len = fcitx_utf8_char_len(ps);
            char *nps;
            nps = fcitx_utf8_get_char(ps , &wc);
            HASH_FIND_INT(transState->t2s_table, &wc, t2s);

            if (t2s) {
                strcat(ret, t2s->str);
                ret_len += t2s->len;
            } else {
                strncat(ret, ps, chr_len);
                ret_len += chr_len;
            }

            ps = nps;

        }
        ret[ret_len] = '\0';

        return ret;
    }
    }
    return NULL;
}
Exemple #8
0
/**
 * 该函数装载data/gbks2t.tab的简体转繁体的码表,
 * 然后按码表将GBK字符转换成GBK繁体字符。
 *
 * WARNING: 该函数返回新分配内存字符串,请调用者
 * 注意释放。
 */
char *ConvertGBKTradition2Simple(FcitxChttrans* transState, const char *strHZ)
{
    if (strHZ == NULL)
        return NULL;

    switch (transState->engine) {
    case ENGINE_OPENCC:
#ifdef _ENABLE_OPENCC
        {
            if (transState->odt2s == NULL) {
                transState->odt2s = opencc_open(OPENCC_DEFAULT_CONFIG_TRAD_TO_SIMP);
                if (transState->odt2s == NULL) {
                    opencc_perror(_("OpenCC initialization error"));
                    return NULL;
                }
            }

            char * res = opencc_convert_utf8(transState->odt2s, strHZ, (size_t) - 1);

            if (res == (char *) - 1) {
                opencc_perror(_("OpenCC error"));
                return NULL;
            }

            return res;
        }
#endif
    case ENGINE_NATIVE: {
        FILE           *fp;
        char           *ret;
        int             i, len, ret_len;
        char           *strBuf = NULL;
        size_t          bufLen = 0;
        const char     *ps;

        if (!transState->t2s_table) {
            len = 0;

            fp = FcitxXDGGetFileWithPrefix("data", TABLE_GBKS2T, "r", NULL);
            if (!fp) {
                ret = (char *) malloc(sizeof(char) * (strlen(strHZ) + 1));
                strcpy(ret, strHZ);
                return ret;
            }
            while (getline(&strBuf, &bufLen, fp) != -1) {
                simple2trad_t *t2s;
                char *ps;
                unsigned int wc;

                ps = fcitx_utf8_get_char(strBuf, &wc);
                t2s = (simple2trad_t*) malloc(sizeof(simple2trad_t));

                fcitx_utf8_get_char(ps, &wc);
                t2s->wc = wc;
                t2s->len = fcitx_utf8_char_len(strBuf);
                strncpy(t2s->str, strBuf, t2s->len);
                t2s->str[t2s->len] = '\0';

                HASH_ADD_INT(transState->t2s_table, wc, t2s);
            }
            if (strBuf)
                free(strBuf);
        }

        i = 0;
        len = fcitx_utf8_strlen(strHZ);
        ret_len = 0;
        ret = (char *) fcitx_utils_malloc0(sizeof(char) * (UTF8_MAX_LENGTH * len + 1));
        ps = strHZ;
        ret[0] = '\0';
        for (; i < len; ++i) {
            unsigned int wc;
            simple2trad_t *t2s = NULL;
            int chr_len = fcitx_utf8_char_len(ps);
            char *nps;
            nps = fcitx_utf8_get_char(ps , &wc);
            HASH_FIND_INT(transState->t2s_table, &wc, t2s);

            if (t2s) {
                strcat(ret, t2s->str);
                ret_len += t2s->len;
            } else {
                strncat(ret, ps, chr_len);
                ret_len += chr_len;
            }

            ps = nps;

        }
        ret[ret_len] = '\0';

        return ret;
    }
    }
    return NULL;
}
Exemple #9
0
boolean TableCreatePhraseCode(TableDict* tableDict, char *strHZ)
{
    unsigned char   i;
    unsigned char   i1, i2;
    size_t          iLen;
    char            strTemp[UTF8_MAX_LENGTH + 1] = {'\0', };
    RECORD         *recTemp;
    boolean bCanntFindCode = false;

    iLen = fcitx_utf8_strlen(strHZ);
    if (iLen >= tableDict->iCodeLength) {
        i2 = tableDict->iCodeLength;
        i1 = 1;
    } else {
        i2 = iLen;
        i1 = 0;
    }

    for (i = 0; i < tableDict->iCodeLength - 1; i++) {
        if (tableDict->rule[i].iWords == i2 && tableDict->rule[i].iFlag == i1)
            break;
    }

    if (i == tableDict->iCodeLength - 1)
        return true;

    int codeIdx = 0;
    for (i1 = 0; i1 < tableDict->iCodeLength; i1++) {
        int clen;
        char* ps;
        if (tableDict->rule[i].rule[i1].iFlag) {
            ps = fcitx_utf8_get_nth_char(strHZ, tableDict->rule[i].rule[i1].iWhich - 1);
            clen = fcitx_utf8_char_len(ps);
            strncpy(strTemp, ps, clen);
        } else {
            ps = fcitx_utf8_get_nth_char(strHZ, iLen - tableDict->rule[i].rule[i1].iWhich);
            clen = fcitx_utf8_char_len(ps);
            strncpy(strTemp, ps, clen);
        }

        int hzIndex = CalHZIndex(strTemp);

        if (tableDict->tableSingleHZ[hzIndex]) {
            if (tableDict->tableSingleHZCons[hzIndex])
                recTemp = tableDict->tableSingleHZCons[hzIndex];
            else
                recTemp = tableDict->tableSingleHZ[hzIndex];
        }
        else {
            bCanntFindCode = true;
            break;
        }

        if (strlen(recTemp->strCode) >= tableDict->rule[i].rule[i1].iIndex) {
            tableDict->strNewPhraseCode[codeIdx] = recTemp->strCode[tableDict->rule[i].rule[i1].iIndex - 1];
            codeIdx++;
        }

    }

    return bCanntFindCode;
}
Exemple #10
0
boolean LoadTableDict(TableMetaData* tableMetaData)
{
    char            strCode[MAX_CODE_LENGTH + 1];
    char           *strHZ = 0;
    FILE           *fpDict;
    RECORD         *recTemp;
    unsigned int    i = 0;
    uint32_t        iTemp, iTempCount;
    char            cChar = 0, cTemp;
    int8_t          iVersion = 1;
    int             iRecordIndex;
    TableDict      *tableDict;

    //读入码表
    FcitxLog(DEBUG, _("Loading Table Dict"));

    int reload = 0;
    do {
        boolean error = false;
        if (!reload) {
            /**
             * kcm saves a absolute path here but it is then interpreted as
             * a relative path?
             **/
            fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strPath,
                                               "r", NULL);
        } else {
            char *tablepath;
            char *path = fcitx_utils_get_fcitx_path("pkgdatadir");
            fcitx_utils_alloc_cat_str(tablepath, path, "/table/",
                                      tableMetaData->strPath);
            fpDict = fopen(tablepath, "r");
            free(tablepath);
        }
        if (!fpDict)
            return false;

        tableMetaData->tableDict = fcitx_utils_new(TableDict);

        tableDict = tableMetaData->tableDict;
        tableDict->pool = fcitx_memory_pool_create();
#define CHECK_LOAD_TABLE_ERROR(SIZE) if (size < (SIZE)) { error = true; goto table_load_error; }

        //先读取码表的信息
        //判断版本信息
        size_t size;
        size = fcitx_utils_read_uint32(fpDict, &iTemp);
        CHECK_LOAD_TABLE_ERROR(1);

        if (!iTemp) {
            size = fread(&iVersion, sizeof(int8_t), 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(1);
            iVersion = (iVersion < INTERNAL_VERSION);
            size = fcitx_utils_read_uint32(fpDict, &iTemp);
            CHECK_LOAD_TABLE_ERROR(1);
        }

        tableDict->strInputCode = (char*)realloc(tableDict->strInputCode, sizeof(char) * (iTemp + 1));
        size = fread(tableDict->strInputCode, sizeof(char), iTemp + 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(iTemp + 1);
        /*
         * 建立索引,加26是为了为拼音编码预留空间
         */
        size_t tmp_len = strlen(tableDict->strInputCode) + 26;
        tableDict->recordIndex = (RECORD_INDEX*)fcitx_memory_pool_alloc(tableDict->pool, tmp_len * sizeof(RECORD_INDEX));
        for (iTemp = 0; iTemp < tmp_len; iTemp++) {
            tableDict->recordIndex[iTemp].cCode = 0;
            tableDict->recordIndex[iTemp].record = NULL;
        }
        /********************************************************************/

        size = fread(&(tableDict->iCodeLength), sizeof(uint8_t), 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(1);
        UpdateTableMetaData(tableMetaData);

        if (!iVersion) {
            size = fread(&(tableDict->iPYCodeLength), sizeof(uint8_t), 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(1);
        }
        else
            tableDict->iPYCodeLength = tableDict->iCodeLength;

        size = fcitx_utils_read_uint32(fpDict, &iTemp);
        CHECK_LOAD_TABLE_ERROR(1);
        tableDict->strIgnoreChars = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (iTemp + 1));
        size = fread(tableDict->strIgnoreChars, sizeof(char), iTemp + 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(iTemp + 1);

        size = fread(&(tableDict->bRule), sizeof(unsigned char), 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(1);

        if (tableDict->bRule) { //表示有组词规则
            tableDict->rule = (RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE) * (tableDict->iCodeLength - 1));
            for (i = 0; i < tableDict->iCodeLength - 1; i++) {
                size = fread(&(tableDict->rule[i].iFlag), sizeof(unsigned char), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                size = fread(&(tableDict->rule[i].iWords), sizeof(unsigned char), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                tableDict->rule[i].rule = (RULE_RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE_RULE) * tableDict->iCodeLength);
                for (iTemp = 0; iTemp < tableDict->iCodeLength; iTemp++) {
                    size = fread(&(tableDict->rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                    size = fread(&(tableDict->rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                    size = fread(&(tableDict->rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                }
            }
        }

        tableDict->recordHead = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD));
        tableDict->currentRecord = tableDict->recordHead;

        size = fcitx_utils_read_uint32(fpDict, &tableDict->iRecordCount);
        CHECK_LOAD_TABLE_ERROR(1);

        for (i = 0; i < SINGLE_HZ_COUNT; i++) {
            tableDict->tableSingleHZ[i] = (RECORD*)NULL;
            tableDict->tableSingleHZCons[i] = (RECORD*)NULL;
        }

        iRecordIndex = 0;
        size_t bufSize = 0;
        for (i = 0; i < tableDict->iRecordCount; i++) {
            size = fread(strCode, sizeof(int8_t), tableDict->iPYCodeLength + 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(tableDict->iPYCodeLength + 1);
            size = fcitx_utils_read_uint32(fpDict, &iTemp);
            CHECK_LOAD_TABLE_ERROR(1);
            /* we don't actually have such limit, but sometimes, broken table
             * may break this, so we need to give a limitation.
             */
            if (iTemp > UTF8_MAX_LENGTH * 30) {
                error = true;
                goto table_load_error;
            }
            if (iTemp > bufSize) {
                bufSize = iTemp;
                strHZ = realloc(strHZ, bufSize);
            }
            size = fread(strHZ, sizeof(int8_t), iTemp, fpDict);
            CHECK_LOAD_TABLE_ERROR(iTemp);
            recTemp = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD));
            recTemp->strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iPYCodeLength + 1));
            memset(recTemp->strCode, 0, sizeof(char) * (tableDict->iPYCodeLength + 1));
            strcpy(recTemp->strCode, strCode);
            recTemp->strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * iTemp);
            strcpy(recTemp->strHZ, strHZ);

            if (!iVersion) {
                size = fread(&cTemp, sizeof(int8_t), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                recTemp->type = cTemp;
            }

            size = fcitx_utils_read_uint32(fpDict, &recTemp->iHit);
            CHECK_LOAD_TABLE_ERROR(1);
            size = fcitx_utils_read_uint32(fpDict, &recTemp->iIndex);
            CHECK_LOAD_TABLE_ERROR(1);
            if (recTemp->iIndex > tableDict->iTableIndex)
                tableDict->iTableIndex = recTemp->iIndex;

            /* 建立索引 */
            if (cChar != recTemp->strCode[0]) {
                cChar = recTemp->strCode[0];
                tableDict->recordIndex[iRecordIndex].cCode = cChar;
                tableDict->recordIndex[iRecordIndex].record = recTemp;
                iRecordIndex++;
            }
            /******************************************************************/
            /** 为单字生成一个表   */
            if (fcitx_utf8_strlen(recTemp->strHZ) == 1 && !IsIgnoreChar(tableDict, strCode[0]))
            {
                RECORD** tableSingleHZ = NULL;
                if (recTemp->type == RECORDTYPE_NORMAL)
                    tableSingleHZ = tableDict->tableSingleHZ;
                else if (recTemp->type == RECORDTYPE_CONSTRUCT)
                    tableSingleHZ = tableDict->tableSingleHZCons;

                if (tableSingleHZ) {
                    iTemp = CalHZIndex(recTemp->strHZ);
                    if (iTemp < SINGLE_HZ_COUNT) {
                        if (tableSingleHZ[iTemp]) {
                            if (strlen(strCode) > strlen(tableDict->tableSingleHZ[iTemp]->strCode))
                                tableSingleHZ[iTemp] = recTemp;
                        } else
                            tableSingleHZ[iTemp] = recTemp;
                    }
                }
            }

            if (recTemp->type == RECORDTYPE_PINYIN)
                tableDict->bHasPinyin = true;

            if (recTemp->type == RECORDTYPE_PROMPT && strlen(recTemp->strCode) == 1)
                tableDict->promptCode[(uint8_t) recTemp->strCode[0]] = recTemp;

            tableDict->currentRecord->next = recTemp;
            recTemp->prev = tableDict->currentRecord;
            tableDict->currentRecord = recTemp;
        }
        if (strHZ) {
            free(strHZ);
            strHZ = NULL;
        }

        tableDict->currentRecord->next = tableDict->recordHead;
        tableDict->recordHead->prev = tableDict->currentRecord;

table_load_error:
        fclose(fpDict);
        if (error) {
            fcitx_memory_pool_destroy(tableDict->pool);
            tableDict->pool = NULL;
            reload++;
        } else {
            break;
        }
    } while(reload < 2);

    if (!tableDict->pool)
        return false;

    FcitxLog(DEBUG, _("Load Table Dict OK"));

    //读取相应的特殊符号表
    fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strSymbolFile, "r", NULL);

    if (fpDict) {
        tableDict->iFH = fcitx_utils_calculate_record_number(fpDict);
        tableDict->fh = (FH*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(FH) * tableDict->iFH);

        char* strBuf = NULL;
        size_t bufLen = 0;
        for (i = 0; i < tableDict->iFH; i++) {
            if (getline(&strBuf, &bufLen, fpDict) == -1)
                break;

            if (!fcitx_utf8_check_string(strBuf))
                break;

            if (fcitx_utf8_strlen(strBuf) > FH_MAX_LENGTH)
                break;

            strcpy(tableDict->fh[i].strFH, strBuf);
        }
        fcitx_utils_free(strBuf);
        tableDict->iFH = i;

        fclose(fpDict);
    }

    tableDict->strNewPhraseCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
    tableDict->strNewPhraseCode[tableDict->iCodeLength] = '\0';

    tableDict->iAutoPhrase = 0;
    if (tableMetaData->bAutoPhrase) {
        tableDict->autoPhrase = (AUTOPHRASE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(AUTOPHRASE) * AUTO_PHRASE_COUNT);

        //读取上次保存的自动词组信息
        FcitxLog(DEBUG, _("Loading Autophrase."));

        char *temppath;
        fcitx_utils_alloc_cat_str(temppath, tableMetaData->uniqueName,
                                  "_LastAutoPhrase.tmp");
        fpDict = FcitxXDGGetFileWithPrefix("table", temppath, "r", NULL);
        free(temppath);
        i = 0;
        if (fpDict) {
            size_t size = fcitx_utils_read_int32(fpDict, &tableDict->iAutoPhrase);
            if (size == 1) {
                for (; i < tableDict->iAutoPhrase; i++) {
                    tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
                    tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1));
                    size = fread(tableDict->autoPhrase[i].strCode, tableDict->iCodeLength + 1, 1, fpDict);
                    if (size != 1) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }
                    size = fread(tableDict->autoPhrase[i].strHZ, PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1, 1, fpDict);
                    tableDict->autoPhrase[i].strHZ[PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH] = 0;
                    if (size != 1 || !fcitx_utf8_check_string(tableDict->autoPhrase[i].strHZ)) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }
                    size = fcitx_utils_read_uint32(fpDict, &iTempCount);
                    if (size != 1) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }

                    tableDict->autoPhrase[i].iSelected = iTempCount;
                    if (i == AUTO_PHRASE_COUNT - 1)
                        tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0];
                    else
                        tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1];
                }
            }
            fclose(fpDict);
        }

        for (; i < AUTO_PHRASE_COUNT; i++) {
            tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
            tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1));
            tableDict->autoPhrase[i].iSelected = 0;
            if (i == AUTO_PHRASE_COUNT - 1)
                tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0];
            else
                tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1];
        }

        if (i == AUTO_PHRASE_COUNT)
            tableDict->insertPoint = &tableDict->autoPhrase[0];
        else
            tableDict->insertPoint = &tableDict->autoPhrase[i - 1];

        FcitxLog(DEBUG, _("Load Autophrase OK"));
    } else
        tableDict->autoPhrase = (AUTOPHRASE *) NULL;

    return true;
}
Exemple #11
0
void FcitxLibpinyinUpdatePreedit(FcitxLibpinyin* libpinyin, char* sentence)
{
    FcitxInstance* instance = libpinyin->owner->owner;
    FcitxInputState* input = FcitxInstanceGetInputState(instance);
    int offset = LibpinyinGetOffset(libpinyin);

    if (libpinyin->type == LPT_Pinyin) {
        int libpinyinLen = strlen(libpinyin->inst->m_raw_full_pinyin);
        int fcitxLen = strlen(libpinyin->buf);
        if (fcitxLen != libpinyinLen) {
            strcpy(libpinyin->buf, libpinyin->inst->m_raw_full_pinyin);
            libpinyin->cursor_pos += libpinyinLen - fcitxLen;
        }
    }

    int pyoffset = LibpinyinGetPinyinOffset(libpinyin);
    if (pyoffset > libpinyin->cursor_pos)
        libpinyin->cursor_pos = pyoffset;

    int hzlen = 0;
    if (fcitx_utf8_strlen(sentence) > offset)
        hzlen = fcitx_utf8_get_nth_char(sentence, offset) - sentence;
    else
        hzlen = strlen(sentence);

    if (hzlen > 0) {
        char* buf = (char*) fcitx_utils_malloc0((hzlen + 1) * sizeof(char));
        strncpy(buf, sentence, hzlen);
        buf[hzlen] = 0;
        FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, "%s", buf);
        free(buf);
    }

    int charcurpos = hzlen;

    int lastpos = pyoffset;
    int curoffset = pyoffset;
    for (int i = offset; i < libpinyin->inst->m_pinyin_keys->len; i ++)
    {
        PinyinKey* pykey = &g_array_index(libpinyin->inst->m_pinyin_keys, PinyinKey, i);
        PinyinKeyPos* pykeypos = &g_array_index(libpinyin->inst->m_pinyin_key_rests, PinyinKeyPos, i);

        if (lastpos > 0) {
            FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), " ");
            if (curoffset < libpinyin->cursor_pos)
                charcurpos ++;
            for (int j = lastpos; j < pykeypos->m_raw_begin; j ++) {
                char temp[2] = {'\0', '\0'};
                temp[0] = libpinyin->buf[j];
                FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), temp);
                if (curoffset < libpinyin->cursor_pos)
                {
                    curoffset ++;
                    charcurpos ++;
                }
            }
        }
        lastpos = pykeypos->m_raw_end;

        switch (libpinyin->type) {
            case LPT_Pinyin: {
                gchar* pystring = pykey->get_pinyin_string();
                FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring);
                size_t pylen = strlen(pystring);
                if (curoffset + pylen < libpinyin->cursor_pos) {
                    curoffset += pylen;
                    charcurpos += pylen;
                }
                else {
                    charcurpos += libpinyin->cursor_pos - curoffset;
                    curoffset = libpinyin->cursor_pos;
                }
                g_free(pystring);
                break;
            }
            case LPT_Shuangpin: {
                if (pykeypos->length() == 2) {
                    const char* initial = 0;
                    if (pykey->m_initial == CHEWING_ZERO_INITIAL)
                        initial = "'";
                    else
                        initial = get_initial_string(pykey);
                    if (curoffset + 1 <= libpinyin->cursor_pos) {
                        curoffset += 1;
                        charcurpos += strlen(initial);
                    }
                    FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", initial);

                    if (curoffset + 1 <= libpinyin->cursor_pos) {
                        curoffset += 1;
                        charcurpos += strlen(get_middle_string(pykey)) + strlen(get_final_string(pykey));
                    }
                    FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s%s", get_middle_string(pykey), get_final_string(pykey));
                }
                else if (pykeypos->length() == 1) {
                    gchar* pystring = pykey->get_pinyin_string();
                    if (curoffset + 1 <= libpinyin->cursor_pos) {
                        curoffset += 1;
                        charcurpos += strlen(pystring);
                    }
                    FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring);
                    g_free(pystring);
                }
                break;
            }
            case LPT_Zhuyin: {
                gchar* pystring = pykey->get_chewing_string();
                FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring);

                if (curoffset + pykeypos->length() <= libpinyin->cursor_pos) {
                    curoffset += pykeypos->length();
                    charcurpos += strlen(pystring);
                }
                else {
                    int diff = libpinyin->cursor_pos - curoffset;
                    curoffset = libpinyin->cursor_pos;
                    size_t len = fcitx_utf8_strlen(pystring);
                    if (pykey->m_tone != CHEWING_ZERO_TONE)
                        len --;

                    if (diff > len)
                        charcurpos += strlen(pystring);
                    else {
                        charcurpos += fcitx_utf8_get_nth_char(pystring, diff) - pystring;
                    }
                }
                g_free(pystring);
                break;
            }
        }
    }

    int buflen = strlen(libpinyin->buf);

    if (lastpos < buflen) {
        FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), " ");
        if (lastpos < libpinyin->cursor_pos)
            charcurpos ++;

        for (int i = lastpos; i < buflen; i ++)
        {
            char temp[2] = {'\0', '\0'};
            temp[0] = libpinyin->buf[i];
            FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), temp);
            if (lastpos < libpinyin->cursor_pos) {
                charcurpos ++;
                lastpos++;
            }
        }
    }
    FcitxInputStateSetCursorPos(input, charcurpos);
}
Exemple #12
0
void CreatePYBase(void)
{
    _PyStruct      *head, *pyList, *temp, *t;
    char            strPY[7], strHZ[UTF8_MAX_LENGTH * 80 + 1], strMap[3];
    int             iIndex, iCount, i;
    int             iBaseCount;
    int             s = 0;
    int             tt = 0;

    head = (_PyStruct *) malloc(sizeof(_PyStruct));
    head->prev = head;
    head->next = head;

    iBaseCount = 0;

    while (PYTable_template[iBaseCount].strPY[0] != '\0')
        iBaseCount++;

    for (iIndex = 0; iIndex < iBaseCount; iIndex++)
        YY[iIndex] = 0;

    iIndex = 0;

    while (!feof(fps)) {
        fscanf(fps, "%s", strPY);
        fscanf(fps, "%s\n", strHZ);

        if (MapPY(&pyconfig, strPY, strMap, PY_PARSE_INPUT_SYSTEM)) {
            for (i = 0; i < iBaseCount; i++)
                if ((!strcmp(PYTable_template[i].strPY, strPY)) && PYTable_template[i].control == PYTABLE_NONE)
                    YY[i] += 1;

            iIndex++;

            if (fcitx_utf8_strlen(strHZ) > 1) {
                int8_t charLen = fcitx_utf8_char_len(strHZ);
                fprintf(stderr, "%s length is larger that 1, truncated to ", strHZ);
                strHZ[charLen] = '\0';
                fprintf(stderr, "%s.\n", strHZ);
            }

            temp = (_PyStruct *) malloc(sizeof(_PyStruct));

            strcpy(temp->strHZ, strHZ);
            strcpy(temp->strPY, strMap);
            pyList = head->prev;

            while (pyList != head) {
                if (strcmp(pyList->strPY, strMap) <= 0)
                    break;

                pyList = pyList->prev;
            }

            temp->next = pyList->next;

            temp->prev = pyList;
            pyList->next->prev = temp;
            pyList->next = temp;
        } else
            fprintf(stderr, "%s Error!!!!\n", strPY);
    }

    iCount = 0;

    for (i = 0; i < iBaseCount; i++) {
        if (YY[i])
            iCount++;
    }

    fwrite(&iCount, sizeof(int), 1, fp1);

    printf("Groups: %d\n", iCount);
    iAllCount = iIndex;

    pyList = head->next;

    strcpy(strPY, pyList->strPY);
    iCount = 0;
    t = pyList;

    while (pyList != head) {
        if (!strcmp(strPY, pyList->strPY)) {
            iCount++;
        } else {
            tt++;
            fwrite(strPY, sizeof(char) * 2, 1, fp1);
            fwrite(&iCount, sizeof(int), 1, fp1);

            for (i = 0; i < iCount; i++) {
                int8_t len = strlen(t->strHZ);
                fwrite(&len, sizeof(int8_t), 1, fp1);
                fwrite(t->strHZ, sizeof(char) * len , 1, fp1);

                t = t->next;
            }

            s += iCount;

            t = pyList;
            iCount = 1;
            strcpy(strPY, pyList->strPY);
        }

        pyList = pyList->next;
    }

    fwrite(strPY, sizeof(char) * 2, 1, fp1);

    fwrite(&iCount, sizeof(int), 1, fp1);

    for (i = 0; i < iCount; i++) {
        int8_t len = strlen(t->strHZ);
        fwrite(&len, sizeof(int8_t), 1, fp1);
        fwrite(t->strHZ, sizeof(char) * len , 1, fp1);
        t = t->next;
    }

    s += iCount;

    fclose(fp1);
    fclose(fps);
}
Exemple #13
0
void CreatePYPhrase(void)
{
    char            strPY[256];
    char            strPhrase[256];
    char            strMap[256];
    ParsePYStruct   strTemp;
    int             iIndex, i, s1, s2, j, k;
    _PyPhrase      *phrase, *t, *tt;
    FILE           *f = fopen("pyERROR", "w");
    FILE           *fg = fopen("pyPhrase.ok", "w");
    int             kkk;
    unsigned int    uIndex, uTemp;
    FcitxPinyinConfig pyconfig;

    memset(&pyconfig, 0 , sizeof(pyconfig));
    InitMHPY(&pyconfig.MHPY_C, MHPY_C_TEMPLATE);
    InitMHPY(&pyconfig.MHPY_S, MHPY_S_TEMPLATE);
    InitPYTable(&pyconfig);

    s1 = 0;
    s2 = 0;
    uIndex = 0;
    printf("Start Loading Phrase...\n");

    while (!feof(fpt)) {
        fscanf(fpt, "%s", strPY);
        fscanf(fpt, "%s\n", strPhrase);

        if (strlen(strPhrase) < 3)
            continue;

        ParsePY(&pyconfig, strPY, &strTemp, PY_PARSE_INPUT_SYSTEM, false);

        s2++;

        kkk = 0;

        if (strTemp.iHZCount != fcitx_utf8_strlen(strPhrase) || (strTemp.iMode & PARSE_ABBR)) {
            fprintf(f, "%s %s\n", strPY, strPhrase);
            continue;
        }

        strMap[0] = '\0';

        for (iIndex = 0; iIndex < strTemp.iHZCount; iIndex++)
            strcat(strMap, strTemp.strMap[iIndex]);

        for (iIndex = 0; iIndex < iPYFACount; iIndex++) {
            if (!strncmp(PYFAList[iIndex].strMap, strMap, 2)) {
                for (i = 0; i < PYFAList[iIndex].iHZCount; i++) {
                    if (!fcitx_utf8_strncmp(PYFAList[iIndex].pyBase[i].strHZ, strPhrase, 1)) {
                        t = PYFAList[iIndex].pyBase[i].phrase;

                        for (j = 0; j < PYFAList[iIndex].pyBase[i].iPhraseCount; j++) {
                            tt = t;
                            t = t->next;

                            if (!strcmp(t->strMap, strMap + 2) && !strcmp(t->strPhrase, strPhrase + fcitx_utf8_char_len(strPhrase))) {
                                printf("\n\t%d: %s %s ----->deleted.\n", s2, strPY, strPhrase);
                                goto _next;
                            }

                            if (strcmp(t->strMap, strMap + 2) > 0) {
                                t = tt;
                                break;
                            }
                        }

                        phrase = (_PyPhrase *) malloc(sizeof(_PyPhrase));

                        phrase->strPhrase = (char *) malloc(sizeof(char) * (strlen(strPhrase) - fcitx_utf8_char_len(strPhrase) + 1));
                        phrase->strMap = (char *) malloc(sizeof(char) * ((strTemp.iHZCount - 1) * 2 + 1));
                        phrase->uIndex = uIndex++;
                        strcpy(phrase->strPhrase, strPhrase + fcitx_utf8_char_len(strPhrase));
                        strcpy(phrase->strMap, strMap + 2);

                        tt = t->next;
                        t->next = phrase;
                        phrase->next = tt;
                        PYFAList[iIndex].pyBase[i].iPhraseCount++;
                        s1++;
                        kkk = 1;

                    _next:
                        ;
                    }
                }
            }
        }

        if (!kkk)
            fprintf(f, "%s %s %s\n", strPY, strPhrase, (char *)(strTemp.strPYParsed));
        else
            fprintf(fg, "%s %s\n", strPY, strPhrase);
    }

    printf("%d Phrases, %d Converted!\nWriting Phrase file ...", s2, s1);

    for (i = 0; i < iPYFACount; i++) {
        for (j = 0; j < PYFAList[i].iHZCount; j++) {
            iIndex = PYFAList[i].pyBase[j].iPhraseCount;

            if (iIndex) {
                int8_t clen = strlen(PYFAList[i].pyBase[j].strHZ);
                fwrite(&i, sizeof(int), 1, fp2);
                fwrite(&clen, sizeof(int8_t), 1, fp2);
                fwrite(PYFAList[i].pyBase[j].strHZ, sizeof(char) * clen, 1, fp2);

                fwrite(&iIndex, sizeof(int), 1, fp2);
                t = PYFAList[i].pyBase[j].phrase->next;

                for (k = 0; k < PYFAList[i].pyBase[j].iPhraseCount; k++) {
                    int slen = strlen(t->strPhrase);
                    iIndex = strlen(t->strMap);
                    fwrite(&iIndex, sizeof(int), 1, fp2);
                    fwrite(t->strMap, sizeof(char), iIndex, fp2);
                    fwrite(&slen, sizeof(int), 1, fp2);
                    fwrite(t->strPhrase, sizeof(char), strlen(t->strPhrase), fp2);
                    uTemp = uIndex - 1 - t->uIndex;
                    fwrite(&uTemp, sizeof(unsigned int), 1, fp2);
                    t = t->next;
                }
            }
        }
    }

    printf("\nOK!\n");

    fclose(fp2);
    fclose(fpt);
}
Exemple #14
0
int main(int argc, char *argv[])
{
    FILE           *fpDict, *fpNew;
    RECORD         *temp, *head, *newRec, *current;
    uint32_t        s = 0;
    int             i;
    uint32_t        iTemp;
    char           *pstr = 0;
    char            strTemp[10];
    unsigned char   bRule;
    RULE           *rule = NULL;
    unsigned int    l;

    unsigned char   iCodeLength = 0;
    unsigned char   iPYCodeLength = 0;

    int8_t          type;

    if (argc != 3) {
        printf("\nUsage: txt2mb <Source File> <IM File>\n\n");
        exit(1);
    }

    fpDict = fopen(argv[1], "r");

    if (!fpDict) {
        printf("\nCannot read source file!\n\n");
        exit(2);
    }

    head = (RECORD *) malloc(sizeof(RECORD));
    head->next = head;
    head->prev = head;
    current = head;

    bRule = 0;
    l = 0;

    char* buf = NULL, *buf1 = NULL;
    size_t len;
    for (;;) {
        l++;

        if (getline(&buf, &len, fpDict) == -1)
            break;

        i = strlen(buf) - 1;

        while ((i >= 0) && (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r'))
            buf[i--] = '\0';

        pstr = buf;

        if (*pstr == ' ')
            pstr++;

        if (pstr[0] == '#')
            continue;

        if (CHECK_OPTION(pstr, STR_KEYCODE)) {
            pstr += ADD_LENGTH(pstr, STR_KEYCODE);
            strcpy(strInputCode, pstr);
        } else if (CHECK_OPTION(pstr, STR_CODELEN)) {
            pstr += ADD_LENGTH(pstr, STR_CODELEN);
            iCodeLength = atoi(pstr);

            if (iCodeLength > MAX_CODE_LENGTH) {
                iCodeLength = MAX_CODE_LENGTH;
                printf("Max Code Length is %d\n", MAX_CODE_LENGTH);
            }
        } else if (CHECK_OPTION(pstr, STR_IGNORECHAR)) {
            pstr += ADD_LENGTH(pstr, STR_IGNORECHAR);
            strcpy(strIgnoreChars, pstr);
        } else if (CHECK_OPTION(pstr, STR_PINYIN)) {
            pstr += ADD_LENGTH(pstr, STR_PINYIN);

            while (*pstr == ' ' && *pstr != '\0')
                pstr++;

            cPinyinKey = *pstr;
        } else if (CHECK_OPTION(pstr, STR_PROMPT)) {
            pstr += ADD_LENGTH(pstr, STR_PROMPT);

            while (*pstr == ' ' && *pstr != '\0')
                pstr++;

            cPromptKey = *pstr;
        } else if (CHECK_OPTION(pstr, STR_CONSTRUCTPHRASE)) {
            pstr += ADD_LENGTH(pstr, STR_CONSTRUCTPHRASE);

            while (*pstr == ' ' && *pstr != '\0')
                pstr++;

            cPhraseKey = *pstr;
        } else if (CHECK_OPTION(pstr, STR_PINYINLEN)) {
            pstr += ADD_LENGTH(pstr, STR_PINYINLEN);
            iPYCodeLength = atoi(pstr);
        }

        else if (CHECK_OPTION(pstr, STR_DATA))
            break;
        else if (CHECK_OPTION(pstr, STR_RULE)) {
            bRule = 1;
            break;
        }
    }

    if (iCodeLength <= 0 || !strInputCode[0]) {
        printf("Source File Format Error!\n");
        exit(1);
    }

    if (bRule) {
        /*
         * 组词规则数应该比键码长度小1
         */
        rule = (RULE *) malloc(sizeof(RULE) * (iCodeLength - 1));

        for (iTemp = 0; iTemp < (iCodeLength - 1); iTemp++) {
            l++;

            if (getline(&buf, &len, fpDict) == -1)
                break;

            rule[iTemp].rule = (RULE_RULE *) malloc(sizeof(RULE_RULE) * iCodeLength);

            i = strlen(buf) - 1;

            while ((i >= 0) && (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r'))
                buf[i--] = '\0';

            pstr = buf;

            if (*pstr == ' ')
                pstr++;

            if (pstr[0] == '#')
                continue;

            if (CHECK_OPTION(pstr, STR_DATA))
                break;

            switch (*pstr) {

            case 'e':

            case 'E':
                rule[iTemp].iFlag = 0;
                break;

            case 'a':

            case 'A':
                rule[iTemp].iFlag = 1;
                break;

            default:
                printf("2   Phrase rules are not suitable!\n");
                printf("\t\t%s\n", buf);
                exit(1);
            }

            pstr++;

            char* p = pstr;

            while (*p && *p != '=')
                p++;

            if (!(*p)) {
                printf("3   Phrase rules are not suitable!\n");
                printf("\t\t%s\n", buf);
                exit(1);
            }

            strncpy(strTemp, pstr, p - pstr);

            strTemp[p - pstr] = '\0';
            rule[iTemp].iWords = atoi(strTemp);

            p++;

            for (i = 0; i < iCodeLength; i++) {
                while (*p == ' ')
                    p++;

                switch (*p) {

                case 'p':

                case 'P':
                    rule[iTemp].rule[i].iFlag = 1;
                    break;

                case 'n':

                case 'N':
                    rule[iTemp].rule[i].iFlag = 0;
                    break;

                default:
                    printf("4   Phrase rules are not suitable!\n");
                    printf("\t\t%s\n", buf);
                    exit(1);
                }

                p++;

                rule[iTemp].rule[i].iWhich = *p++ - '0';
                rule[iTemp].rule[i].iIndex = *p++ - '0';

                while (*p == ' ')
                    p++;

                if (i != (iCodeLength - 1)) {
                    if (*p != '+') {
                        printf("5   Phrase rules are not suitable!\n");
                        printf("\t\t%s  %d\n", buf, iCodeLength);
                        exit(1);
                    }

                    p++;
                }
            }
        }

        if (iTemp != iCodeLength - 1) {
            printf("6  Phrase rules are not suitable!\n");
            exit(1);
        }

        for (iTemp = 0; iTemp < (iCodeLength - 1); iTemp++) {
            l++;

            if (getline(&buf, &len, fpDict) == -1)
                break;

            i = strlen(buf) - 1;

            while ((i >= 0) && (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r'))
                buf[i--] = '\0';

            pstr = buf;

            if (*pstr == ' ')
                pstr++;

            if (pstr[0] == '#')
                continue;

            if (CHECK_OPTION(pstr, STR_DATA))
                break;
        }
    }

    if (iPYCodeLength < iCodeLength)
        iPYCodeLength = iCodeLength;

    if (!CHECK_OPTION(pstr, STR_DATA)) {
        printf("Source File Format Error!\n");
        exit(1);
    }

    while (getline(&buf, &len, fpDict) != -1) {
        l++;
        if (buf1)
            free(buf1);
        buf1 = fcitx_utils_trim(buf);
        char *p = buf1;

        while (*p && !isspace(*p))
            p ++;

        if (*p == '\0')
            continue;

        while (isspace(*p)) {
            *p = '\0';
            p ++;
        }

        char* strHZ = p;

        if (!IsValidCode(buf1[0])) {
            printf("Invalid Format: Line-%d  %s %s\n", l, buf1, strHZ);

            exit(1);
        }

        if (((buf1[0] != cPinyinKey) && (strlen(buf1) > iCodeLength))
                || ((buf1[0] == cPinyinKey) && (strlen(buf1) > (iPYCodeLength + 1)))
                || ((buf1[0] == cPhraseKey) && (strlen(buf1) > (iCodeLength + 1)))
                || ((buf1[0] == cPromptKey) && (strlen(buf1) > (iPYCodeLength + 1)))
           ) {
            printf("Delete:  %s %s, Too long\n", buf1, strHZ);
            continue;
        }

        size_t hzLen = fcitx_utf8_strlen(strHZ);
        if (buf1[0] == cPhraseKey && hzLen != 1) {
            printf("Delete:  %s %s, Too long\n", buf1, strHZ);
            continue;
        }

        type = RECORDTYPE_NORMAL;

        pstr = buf1;

        if (buf1[0] == cPinyinKey) {
            pstr ++;
            type = RECORDTYPE_PINYIN;
        } else if (buf1[0] == cPhraseKey) {
            pstr ++;
            type = RECORDTYPE_CONSTRUCT;
        } else if (buf1[0] == cPromptKey) {
            pstr ++;
            type = RECORDTYPE_PROMPT;
        }

        //查找是否重复
        temp = current;

        if (temp != head) {
            if (strcmp(temp->strCode, pstr) >= 0) {
                while (temp != head && strcmp(temp->strCode, pstr) >= 0) {
                    if (!strcmp(temp->strHZ, strHZ) && !strcmp(temp->strCode, pstr) && temp->type == type) {
                        printf("Delete:  %s %s\n", pstr, strHZ);
                        goto _next;
                    }

                    temp = temp->prev;
                }

                if (temp == head)
                    temp = temp->next;

                while (temp != head && strcmp(temp->strCode, pstr) <= 0)
                    temp = temp->next;
            } else {
                while (temp != head && strcmp(temp->strCode, pstr) <= 0) {
                    if (!strcmp(temp->strHZ, strHZ) && !strcmp(temp->strCode, pstr) && temp->type == type) {
                        printf("Delete:  %s %s\n", pstr, strHZ);
                        goto _next;
                    }

                    temp = temp->next;
                }
            }
        }

        //插在temp的前面
        newRec = (RECORD *) fcitx_utils_malloc0(sizeof(RECORD));

        newRec->strCode = (char *) fcitx_utils_malloc0(sizeof(char) * (iPYCodeLength + 1));

        newRec->strHZ = (char *) fcitx_utils_malloc0(sizeof(char) * strlen(strHZ) + 1);

        strcpy(newRec->strCode, pstr);

        strcpy(newRec->strHZ, strHZ);

        newRec->type = type;

        newRec->iHit = 0;

        newRec->iIndex = 0;

        temp->prev->next = newRec;

        newRec->next = temp;

        newRec->prev = temp->prev;

        temp->prev = newRec;

        current = newRec;

        s++;

_next:
        continue;

    }


    if (buf)
        free(buf);
    if (buf1)
        free(buf1);

    fclose(fpDict);

    printf("\nReading %d records.\n\n", s);

    fpNew = fopen(argv[2], "w");

    if (!fpNew) {
        printf("\nCannot create target file!\n\n");
        exit(3);
    }

    int8_t iInternalVersion = INTERNAL_VERSION;

    //写入版本号--如果第一个字为0,表示后面那个字节为版本号
    fcitx_utils_write_uint32(fpNew, 0);
    fwrite(&iInternalVersion, sizeof(int8_t), 1, fpNew);

    iTemp = (uint32_t)strlen(strInputCode);
    fcitx_utils_write_uint32(fpNew, iTemp);
    fwrite(strInputCode, sizeof(char), iTemp + 1, fpNew);
    fwrite(&iCodeLength, sizeof(unsigned char), 1, fpNew);
    fwrite(&iPYCodeLength, sizeof(unsigned char), 1, fpNew);
    iTemp = (uint32_t)strlen(strIgnoreChars);
    fcitx_utils_write_uint32(fpNew, iTemp);
    fwrite(strIgnoreChars, sizeof(char), iTemp + 1, fpNew);

    fwrite(&bRule, sizeof(unsigned char), 1, fpNew);

    if (bRule) {
        for (i = 0; i < iCodeLength - 1; i++) {
            fwrite(&(rule[i].iFlag), sizeof(unsigned char), 1, fpNew);
            fwrite(&(rule[i].iWords), sizeof(unsigned char), 1, fpNew);

            for (iTemp = 0; iTemp < iCodeLength; iTemp++) {
                fwrite(&(rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpNew);
                fwrite(&(rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpNew);
                fwrite(&(rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpNew);
            }
        }
    }

    fcitx_utils_write_uint32(fpNew, s);

    current = head->next;

    while (current != head) {
        fwrite(current->strCode, sizeof(char), iPYCodeLength + 1, fpNew);
        s = strlen(current->strHZ) + 1;
        fcitx_utils_write_uint32(fpNew, s);
        fwrite(current->strHZ, sizeof(char), s, fpNew);
        fwrite(&(current->type), sizeof(int8_t), 1, fpNew);
        fcitx_utils_write_uint32(fpNew, current->iHit);
        fcitx_utils_write_uint32(fpNew, current->iIndex);
        current = current->next;
    }

    fclose(fpNew);

    return 0;
}
Exemple #15
0
void
XimPreeditCallbackDraw(FcitxXimFrontend* xim, FcitxXimIC* ic, const char* preedit_string, int cursorPos)
{
    XTextProperty tp;

    uint i, len;

    if (preedit_string == NULL)
        return;

    len = fcitx_utf8_strlen(preedit_string);

    if (len + 1 > xim->feedback_len) {
        xim->feedback_len = len + 1;
        if (xim->feedback) {
            xim->feedback = realloc(xim->feedback, sizeof(XIMFeedback) * xim->feedback_len);
        } else {
            xim->feedback = fcitx_utils_malloc0(sizeof(XIMFeedback) * xim->feedback_len);
        }
    }

    FcitxInputState* input = FcitxInstanceGetInputState(xim->owner);
    FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input);
    int offset = 0;
    for (i = 0; i < FcitxMessagesGetMessageCount(clientPreedit) ; i ++) {
        int type = FcitxMessagesGetClientMessageType(clientPreedit, i);
        char* str = FcitxMessagesGetMessageString(clientPreedit, i);
        int j = 0;
        XIMFeedback fb = 0;
        if ((type & MSG_NOUNDERLINE) == 0)
            fb |= XIMUnderline;
        if (type & MSG_HIGHLIGHT)
            fb |= XIMReverse;
        for (; j < fcitx_utf8_strlen(str); j++) {
            xim->feedback[offset] = fb;
            offset ++;
        }
    }
    xim->feedback[len] = 0;

    IMPreeditCBStruct* pcb = fcitx_utils_new(IMPreeditCBStruct);
    XIMText* text = fcitx_utils_new(XIMText);
    pcb->major_code = XIM_PREEDIT_DRAW;
    pcb->connect_id = ic->connect_id;
    pcb->icid = ic->id;

    pcb->todo.draw.caret = fcitx_utf8_strnlen(preedit_string, cursorPos);
    pcb->todo.draw.chg_first = 0;
    pcb->todo.draw.chg_length = ic->onspot_preedit_length;
    pcb->todo.draw.text = text;

    text->feedback = xim->feedback;

    Xutf8TextListToTextProperty(xim->display,
                                (char **)&preedit_string,
                                1, XCompoundTextStyle, &tp);
    text->encoding_is_wchar = 0;
    text->length = strlen((char*)tp.value);
    text->string.multi_byte = (char*)tp.value;
    XimPendingCall(xim, XCT_CALLCALLBACK, (XPointer) pcb);
    ic->onspot_preedit_length = len;
}
Exemple #16
0
static void
_fcitx_im_context_update_formatted_preedit_cb(FcitxClient* im, GPtrArray* array, int cursor_pos, void* user_data)
{
    FcitxLog(LOG_LEVEL, "_fcitx_im_context_commit_string_cb");
    FcitxIMContext* context =  FCITX_IM_CONTEXT(user_data);

    gboolean visible = false;

    if (context->preedit_string != NULL) {
        if (strlen(context->preedit_string) != 0)
            visible = true;
        g_free(context->preedit_string);
        context->preedit_string = NULL;
    }

    if (context->attrlist != NULL) {
        pango_attr_list_unref(context->attrlist);
    }

    context->attrlist = pango_attr_list_new();

    GString* gstr = g_string_new(NULL);

    int i = 0;
    for (i = 0; i < array->len; i++) {
        size_t bytelen = strlen(gstr->str);
        FcitxPreeditItem* preedit = g_ptr_array_index(array, i);
        const gchar* s = preedit->string;
        gint type = preedit->type;

        PangoAttribute *pango_attr = NULL;
        if ((type & MSG_NOUNDERLINE) == 0) {
            pango_attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
            pango_attr->start_index = bytelen;
            pango_attr->end_index = bytelen + strlen(s);
            pango_attr_list_insert(context->attrlist, pango_attr);
        }

        if (type & MSG_HIGHLIGHT) {
            gboolean hasColor;
            GdkColor fg;
            GdkColor bg;

            if (context->client_window) {
                GtkWidget *widget;
                gdk_window_get_user_data (context->client_window,
                                          (gpointer *)&widget);
                if (GTK_IS_WIDGET(widget)) {
                    hasColor = true;
                    GtkStyle* style = gtk_widget_get_style(widget);
                    fg = style->text[GTK_STATE_SELECTED];
                    bg = style->bg[GTK_STATE_SELECTED];
                }
            }

            if (!hasColor) {
                fg.red = 0xffff;
                fg.green = 0xffff;
                fg.blue = 0xffff;
                bg.red = 0x43ff;
                bg.green = 0xacff;
                bg.blue = 0xe8ff;
            }

            pango_attr = pango_attr_foreground_new(fg.red, fg.green, fg.blue);
            pango_attr->start_index = bytelen;
            pango_attr->end_index = bytelen + strlen(s);
            pango_attr_list_insert(context->attrlist, pango_attr);
            pango_attr = pango_attr_background_new(bg.red, bg.green, bg.blue);
            pango_attr->start_index = bytelen;
            pango_attr->end_index = bytelen + strlen(s);
            pango_attr_list_insert(context->attrlist, pango_attr);
        }
        gstr = g_string_append(gstr, s);
    }

    gchar* str = g_string_free(gstr, FALSE);

    context->preedit_string = g_strdup(str);
    char* tempstr = g_strndup(str, cursor_pos);
    context->cursor_pos =  fcitx_utf8_strlen(tempstr);
    g_free(tempstr);

    gboolean new_visible = false;

    if (context->preedit_string != NULL) {
        if (strlen(context->preedit_string) != 0)
            new_visible = true;
    }
    gboolean flag = new_visible != visible;

    if (new_visible) {
        if (flag) {
            /* invisible => visible */
            g_signal_emit(context, _signal_preedit_start_id, 0);
        }
        g_signal_emit(context, _signal_preedit_changed_id, 0);
    } else {
        if (flag) {
            /* visible => invisible */
            g_signal_emit(context, _signal_preedit_changed_id, 0);
            g_signal_emit(context, _signal_preedit_end_id, 0);
        } else {
            /* still invisible */
            /* do nothing */
        }
    }

    g_signal_emit(context, _signal_preedit_changed_id, 0);
}