コード例 #1
0
ファイル: setup.c プロジェクト: ueno/ibus-m17n
static MPlist *
parse_m17n_value (MPlist *plist, gchar *text)
{
    MPlist *value;

    if (mplist_key (plist) == Msymbol) {
        value = mplist ();
        mplist_add (value, Msymbol, msymbol (text));
        return value;
    }

    if (mplist_key (plist) == Mtext) {
        MText *mtext;

        mtext = mtext_from_data (text, strlen (text), MTEXT_FORMAT_UTF_8);
        value = mplist ();
        mplist_add (value, Mtext, mtext);
        return value;
    }

    if (mplist_key (plist) == Minteger) {
        long val;

        errno = 0;
        val = strtol (text, NULL, 10);
        if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
            || (errno != 0 && val == 0))
            return NULL;
        value = mplist ();
        mplist_add (value, Minteger, (void *)val);
        return value;
    }

    return NULL;
}
コード例 #2
0
ファイル: mimx-table.c プロジェクト: ueno/mimx-tables
static MPlist *
add_action (MPlist *actions, MSymbol name, MSymbol key, void *val)
{
  MPlist *action = mplist ();

  mplist_add (action, Msymbol, name);
  if (key != Mnil)
    mplist_add (action, key, val);
  mplist_add (actions, Mplist, action);
  m17n_object_unref (action);
  return actions;
}
コード例 #3
0
ファイル: mimx-table.c プロジェクト: ueno/mimx-tables
static MPlist *
paginate (MPlist *candidates)
{
  MPlist *p = candidates, *pl = mplist (), *plist = mplist ();
  int i;

  for (i = 0; mplist_key (p) == Mtext; p = mplist_next (p), i++)
    {
      mplist_add (pl, Mtext, mplist_value (p));
      if (i % 10 == 9)
	{
	  mplist_add (plist, Mplist, pl);
	  m17n_object_unref (pl);
	  pl = mplist ();
	}
    }

  if (mplist_key (pl) != Mnil)
    mplist_add (plist, Mplist, pl);
  m17n_object_unref (pl);
  return plist;
}
コード例 #4
0
static MPlist *
parse_m17n_value (MPlist *plist, gchar *text)
{
    MPlist *value;

    if (mplist_key (plist) == Msymbol) {
        value = mplist ();
        mplist_add (value, Msymbol, msymbol (text));
        return value;
    }

    if (mplist_key (plist) == Mtext) {
        MText *mtext;

        mtext = mconv_decode_buffer (Mcoding_utf_8,
                                     (const unsigned char *) text,
                                     strlen (text));
        value = mplist ();
        mplist_add (value, Mtext, mtext);
        return value;
    }

    if (mplist_key (plist) == Minteger) {
        long val;

        errno = 0;
        val = strtol (text, NULL, 10);
        if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
            || (errno != 0 && val == 0))
            return NULL;
        value = mplist ();
        mplist_add (value, Minteger, (void *)val);
        return value;
    }

    return NULL;
}
コード例 #5
0
ファイル: mimx-table.c プロジェクト: ueno/mimx-tables
MPlist *
lookup (MPlist *args)
{
  MInputContext *ic;
  MPlist *actions = NULL, *candidates, *plist;
  MSymbol init_state;
  MSymbol select_state;
  TableContext *context;
  MText *mt;

  ic = mplist_value (args);
  context = get_context (ic);

  args = mplist_next (args);
  init_state = (MSymbol) mplist_value (args);
  args = mplist_next (args);
  select_state = (MSymbol) mplist_value (args);

  if (context->desc)
    candidates = (*context->desc->lookup) (context, args);
  else
    candidates = mplist ();

  if (mplist_length (candidates) == 0) {
    m17n_object_unref (candidates);
    return NULL;
  }

#if 0
  /* FIXME: if only one candidate is matching, we should insert it and
     commit immediately.  However, this feature is disabled for now
     since users would type extra characters after the match.  For
     example, with mr-inscript-typing-booster, an Indic word
     "Epgyepgne" is only one candidate when a user type "Epgyepgn",
     but the user will likely to type "e" after commit.
  */
  if (mplist_length (candidates) == 1) {
    actions = mplist ();
    add_action (actions, msymbol ("delete"), Msymbol,  msymbol ("@<"));
    add_action (actions, msymbol ("insert"), Mtext, mplist_value (candidates));
    add_action (actions, msymbol ("commit"), Mnil, NULL);
    m17n_object_unref (candidates);
    return actions;
  }
#endif

  actions = mplist ();

  mt = mtext_dup (ic->preedit);
  mplist_push (candidates, Mtext, mt);
  m17n_object_unref (mt);
  plist = paginate (candidates);
  m17n_object_unref (candidates);

  add_action (actions, msymbol ("delete"), Msymbol,  msymbol ("@<"));
  mplist_add (actions, Mplist, plist);
  m17n_object_unref (plist);
  add_action (actions, msymbol ("select"), Minteger, (void *)1);
  add_action (actions, msymbol ("show"), Mnil, NULL);
  add_action (actions, msymbol ("shift"), Msymbol, select_state);

  return actions;
}
コード例 #6
0
ファイル: mimx-table.c プロジェクト: ueno/mimx-tables
static MPlist *
lookup_ibus (TableContext *context, MPlist *args)
{
  unsigned char buf[256];
  char *word = NULL, *sql = NULL, *msql = NULL;
  MPlist *candidates = mplist ();
  int len, xlen, wlen, mlen;
  int i, rc;
  int *m = NULL;
  sqlite3_stmt *stmt;
  MText *mt;

  if (!context->db)
    goto out;

  rc = mtext_to_utf8 (context, context->ic->preedit, buf, sizeof (buf));
  if (rc < 0)
    goto out;
  word = strdup ((const char *)buf);
  len = rc;

  mlen = CLAMP(context->mlen, 0, 99);

  rc = encode_phrase ((const unsigned char *)word, &m);
  if (rc)
    goto out;

  /* strlen(" AND mXX = XX") = 13 */
  if (len > mlen)
    len = mlen;
  msql = calloc (sizeof (char), 13 * len + 1);
  if (!msql)
    goto out;
  for (i = 0; i < len; i++)
    {
      char s[14];
      sqlite3_snprintf (13, s, " AND m%d = %d", i, m[i]);
      strcat (msql, s);
    }

  sql = calloc (sizeof (char), 128 + strlen (msql) + 1);
  if (!sql)
    goto out;

  /* issue query repeatedly until at least one candidates are found or
     the key length is exceeds mlen */
  xlen = context->xlen;
  wlen = mlen - len + 1;
  for (; xlen <= wlen + 1; xlen++)
    {
      sqlite3_snprintf (128,
			sql,
			"SELECT id, phrase FROM phrases WHERE mlen < %lu",
			len + xlen);
      strcat (sql, msql);
      strcat (sql, " ORDER BY mlen ASC, user_freq DESC, freq DESC, id ASC");
      if (context->max_candidates)
	sqlite3_snprintf (128,
			  sql + strlen (sql),
			  " LIMIT %lu",
			  context->max_candidates);

#ifdef DEBUG
      fprintf (stderr, "%s\n", sql);
#endif
      rc = sqlite3_prepare (context->db, sql, strlen (sql), &stmt, NULL);
      if (rc != SQLITE_OK)
	{
	  sqlite3_finalize (stmt);
	  goto out;
	}

      while (sqlite3_step (stmt) == SQLITE_ROW)
	{
	  const unsigned char *text;

	  text = sqlite3_column_text (stmt, 1);
#ifdef DEBUG
	  fprintf (stderr, " %s\n", text);
#endif
	  mt = mtext_from_utf8 (context, text, strlen ((const char *)text));
	  mplist_add (candidates, Mtext, mt);
	  m17n_object_unref (mt);
	}
      sqlite3_finalize (stmt);
      if (mplist_length (candidates) > 0)
	break;
    }

 out:
  if (word)
    free (word);
  if (m)
    free (m);
  if (sql)
    free (sql);
  if (msql)
    free (msql);

  return candidates;
}