コード例 #1
0
ファイル: menu.c プロジェクト: ueno/emacs
ptrdiff_t
menu_item_width (const unsigned char *str)
{
  ptrdiff_t len;
  const unsigned char *p;

  for (len = 0, p = str; *p; )
    {
      int ch_len;
      int ch = STRING_CHAR_AND_LENGTH (p, ch_len);

      len += CHAR_WIDTH (ch);
      p += ch_len;
    }
  return len;
}
コード例 #2
0
ファイル: casefiddle.c プロジェクト: mmaruska/emacs
static Lisp_Object
casify_object (enum case_action flag, Lisp_Object obj)
{
  register int c, c1;
  register int inword = flag == CASE_DOWN;

  /* If the case table is flagged as modified, rescan it.  */
  if (NILP (XCHAR_TABLE (BVAR (current_buffer, downcase_table))->extras[1]))
    Fset_case_table (BVAR (current_buffer, downcase_table));

  if (INTEGERP (obj))
    {
      int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER
		      | CHAR_SHIFT | CHAR_CTL | CHAR_META);
      int flags = XINT (obj) & flagbits;
      int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));

      /* If the character has higher bits set
	 above the flags, return it unchanged.
	 It is not a real character.  */
      if ((unsigned) XFASTINT (obj) > (unsigned) flagbits)
	return obj;

      c1 = XFASTINT (obj) & ~flagbits;
      /* FIXME: Even if enable-multibyte-characters is nil, we may
	 manipulate multibyte chars.  This means we have a bug for latin-1
	 chars since when we receive an int 128-255 we can't tell whether
	 it's an eight-bit byte or a latin-1 char.  */
      if (c1 >= 256)
	multibyte = 1;
      if (! multibyte)
	MAKE_CHAR_MULTIBYTE (c1);
      c = downcase (c1);
      if (inword)
	XSETFASTINT (obj, c | flags);
      else if (c == (XFASTINT (obj) & ~flagbits))
	{
	  if (! inword)
	    c = upcase1 (c1);
	  if (! multibyte)
	    MAKE_CHAR_UNIBYTE (c);
	  XSETFASTINT (obj, c | flags);
	}
      return obj;
    }

  if (!STRINGP (obj))
    wrong_type_argument (Qchar_or_string_p, obj);
  else if (!STRING_MULTIBYTE (obj))
    {
      EMACS_INT i;
      EMACS_INT size = SCHARS (obj);

      obj = Fcopy_sequence (obj);
      for (i = 0; i < size; i++)
	{
	  c = SREF (obj, i);
	  MAKE_CHAR_MULTIBYTE (c);
	  c1 = c;
	  if (inword && flag != CASE_CAPITALIZE_UP)
	    c = downcase (c);
	  else if (!uppercasep (c)
		   && (!inword || flag != CASE_CAPITALIZE_UP))
	    c = upcase1 (c1);
	  if ((int) flag >= (int) CASE_CAPITALIZE)
	    inword = (SYNTAX (c) == Sword);
	  if (c != c1)
	    {
		  MAKE_CHAR_UNIBYTE (c);
	      /* If the char can't be converted to a valid byte, just don't
		 change it.  */
	      if (c >= 0 && c < 256)
		SSET (obj, i, c);
	    }
	}
      return obj;
    }
  else
    {
      EMACS_INT i, i_byte, size = SCHARS (obj);
      int len;
      USE_SAFE_ALLOCA;
      unsigned char *dst, *o;
      /* Over-allocate by 12%: this is a minor overhead, but should be
	 sufficient in 99.999% of the cases to avoid a reallocation.  */
      EMACS_INT o_size = SBYTES (obj) + SBYTES (obj) / 8 + MAX_MULTIBYTE_LENGTH;
      SAFE_ALLOCA (dst, void *, o_size);
      o = dst;

      for (i = i_byte = 0; i < size; i++, i_byte += len)
	{
	  if ((o - dst) + MAX_MULTIBYTE_LENGTH > o_size)
	    { /* Not enough space for the next char: grow the destination.  */
	      unsigned char *old_dst = dst;
	      o_size += o_size;	/* Probably overkill, but extremely rare.  */
	      SAFE_ALLOCA (dst, void *, o_size);
	      memcpy (dst, old_dst, o - old_dst);
	      o = dst + (o - old_dst);
	    }
	  c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, len);
	  if (inword && flag != CASE_CAPITALIZE_UP)
	    c = downcase (c);
	  else if (!uppercasep (c)
		   && (!inword || flag != CASE_CAPITALIZE_UP))
	    c = upcase1 (c);
	  if ((int) flag >= (int) CASE_CAPITALIZE)
	    inword = (SYNTAX (c) == Sword);
	  o += CHAR_STRING (c, o);
	}
      eassert (o - dst <= o_size);
      obj = make_multibyte_string ((char *) dst, size, o - dst);
      SAFE_FREE ();
      return obj;
    }
}