Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port unibyte-char-to-multibyte function #218

Merged
merged 5 commits into from Jul 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions rust_src/remacs-sys/lib.rs
Expand Up @@ -702,6 +702,7 @@ extern "C" {
pub static Qwholenump: Lisp_Object;
pub static Qvectorp: Lisp_Object;
pub static Qsequencep: Lisp_Object;
pub static Qcharacterp: Lisp_Object;

pub static Qinteger: Lisp_Object;
pub static Qsymbol: Lisp_Object;
Expand Down
16 changes: 14 additions & 2 deletions rust_src/src/character.rs
@@ -1,9 +1,9 @@
//! Operations on characters.

use lisp::LispObject;
use multibyte::MAX_CHAR;
use multibyte::{MAX_CHAR, make_char_multibyte};
use remacs_macros::lisp_fn;
use remacs_sys::EmacsInt;
use remacs_sys::{EmacsInt, error};

/// Return the character of the maximum code.
#[lisp_fn]
Expand All @@ -26,3 +26,15 @@ fn characterp(object: LispObject, _ignore: LispObject) -> LispObject {
fn char_or_string_p(object: LispObject) -> LispObject {
LispObject::from_bool(object.is_character() || object.is_string())
}

/// Convert the byte CH to multibyte character.
#[lisp_fn]
fn unibyte_char_to_multibyte(ch: LispObject) -> LispObject {
let c = ch.as_character_or_error();
if c >= 0x100 {
unsafe {
error("Not a unibyte character: %d\0".as_ptr(), c);
}
}
LispObject::from_fixnum(make_char_multibyte(c) as EmacsInt)
}
1 change: 1 addition & 0 deletions rust_src/src/lib.rs
Expand Up @@ -193,6 +193,7 @@ pub extern "C" fn rust_init_syms() {
defsubr(&*character::Smax_char);
defsubr(&*character::Scharacterp);
defsubr(&*character::Schar_or_string_p);
defsubr(&*character::Sunibyte_char_to_multibyte);
defsubr(&*vectors::Sarrayp);
defsubr(&*vectors::Sbool_vector_p);
defsubr(&*vectors::Sbufferp);
Expand Down
25 changes: 23 additions & 2 deletions rust_src/src/lisp.rs
Expand Up @@ -13,7 +13,7 @@ use std::fmt::{Debug, Formatter, Error};
use libc::{c_void, intptr_t};

use marker::{LispMarker, marker_position};
use multibyte::{LispStringRef, MAX_CHAR};
use multibyte::{Codepoint, LispStringRef, MAX_CHAR};
use symbols::LispSymbolRef;
use vectors::LispVectorlikeRef;
use buffers::LispBufferRef;
Expand All @@ -22,7 +22,7 @@ use remacs_sys::{EmacsInt, EmacsUint, EmacsDouble, EMACS_INT_MAX, EMACS_INT_SIZE
EMACS_FLOAT_SIZE, USE_LSB_TAG, GCTYPEBITS, wrong_type_argument, Qstringp,
Qsymbolp, Qnumber_or_marker_p, Qt, make_float, Qlistp, Qintegerp, Qconsp,
circular_list, internal_equal, Fcons, CHECK_IMPURE, Qnumberp, Qfloatp,
Qwholenump, Qvectorp, SYMBOL_NAME, PseudovecType, lispsym};
Qwholenump, Qvectorp, Qcharacterp, SYMBOL_NAME, PseudovecType, lispsym};
use remacs_sys::Lisp_Object as CLisp_Object;

// TODO: tweak Makefile to rebuild C files if this changes.
Expand Down Expand Up @@ -148,6 +148,17 @@ impl LispObject {
pub fn get_untaggedptr(self) -> *mut c_void {
(self.to_raw() & VALMASK) as intptr_t as *mut c_void
}

// Same as CHECK_TYPE macro,
// order of arguments changed
#[inline]
fn check_type_or_error(self, ok: bool, predicate: CLisp_Object) -> () {
if !ok {
unsafe {
wrong_type_argument(predicate, self.to_raw());
}
}
}
}

// Symbol support (LispType == Lisp_Symbol == 0)
Expand Down Expand Up @@ -881,6 +892,16 @@ impl LispObject {
)
}

/// Check if Lisp object is a character or not and return the codepoint
/// Similar to CHECK_CHARACTER
#[inline]
pub fn as_character_or_error(self) -> Codepoint {
unsafe {
self.check_type_or_error(self.is_character(), Qcharacterp);
}
self.as_fixnum().unwrap() as Codepoint
}

#[inline]
pub fn is_overlay(self) -> bool {
self.as_misc().map_or(
Expand Down
17 changes: 17 additions & 0 deletions rust_src/src/multibyte.rs
Expand Up @@ -191,6 +191,23 @@ fn raw_byte_from_codepoint(cp: Codepoint) -> c_uchar {
(cp - 0x3F_FF00) as c_uchar
}

/// UNIBYTE_TO_CHAR macro
#[inline]
pub fn unibyte_to_char(cp: Codepoint) -> Codepoint {
if cp < 0x80 {
cp
} else {
raw_byte_codepoint(cp as c_uchar)
}
}

/// MAKE_CHAR_MULTIBYTE macro
#[inline]
pub fn make_char_multibyte(cp: Codepoint) -> Codepoint {
debug_assert!(cp < 256);
unibyte_to_char(cp)
}

/// Same as the CHAR_STRING macro.
#[inline]
fn write_codepoint(to: &mut [c_uchar], cp: Codepoint) -> usize {
Expand Down
17 changes: 0 additions & 17 deletions src/character.c
Expand Up @@ -67,22 +67,6 @@ translate_char (Lisp_Object table, int c)
return c;
}


DEFUN ("unibyte-char-to-multibyte", Funibyte_char_to_multibyte,
Sunibyte_char_to_multibyte, 1, 1, 0,
doc: /* Convert the byte CH to multibyte character. */)
(Lisp_Object ch)
{
int c;

CHECK_CHARACTER (ch);
c = XFASTINT (ch);
if (c >= 0x100)
error ("Not a unibyte character: %d", c);
MAKE_CHAR_MULTIBYTE (c);
return make_number (c);
}

DEFUN ("multibyte-char-to-unibyte", Fmultibyte_char_to_unibyte,
Smultibyte_char_to_unibyte, 1, 1, 0,
doc: /* Convert the multibyte character CH to a byte.
Expand Down Expand Up @@ -631,7 +615,6 @@ syms_of_character (void)
staticpro (&Vchar_unify_table);
Vchar_unify_table = Qnil;

defsubr (&Sunibyte_char_to_multibyte);
defsubr (&Smultibyte_char_to_unibyte);
defsubr (&Schar_width);
defsubr (&Sstring_width);
Expand Down