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 get buffer #242

Merged
merged 2 commits into from Jul 19, 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
2 changes: 1 addition & 1 deletion rust_src/remacs-sys/lib.rs
Expand Up @@ -1045,10 +1045,10 @@ extern "C" {
pub static Qfont_entity: Lisp_Object;
pub static Qfont_object: Lisp_Object;
pub static lispsym: Lisp_Symbol;
pub static Vbuffer_alist: Lisp_Object;

pub fn Fcons(car: Lisp_Object, cdr: Lisp_Object) -> Lisp_Object;
pub fn Fcurrent_buffer() -> Lisp_Object;
pub fn Fget_buffer(buffer_or_name: Lisp_Object) -> Lisp_Object;
pub fn Fsignal(error_symbol: Lisp_Object, data: Lisp_Object) -> !;

pub fn make_float(float_value: c_double) -> Lisp_Object;
Expand Down
34 changes: 33 additions & 1 deletion rust_src/src/buffers.rs
Expand Up @@ -3,7 +3,9 @@
use libc::{c_uchar, ptrdiff_t};

use lisp::{LispObject, ExternalPtr};
use remacs_sys::Lisp_Buffer;
use remacs_sys::{Lisp_Buffer, Vbuffer_alist};
use strings::string_equal;
use lists::{car, cdr};

use remacs_macros::lisp_fn;

Expand Down Expand Up @@ -71,3 +73,33 @@ pub fn overlayp(object: LispObject) -> LispObject {
pub fn buffer_live_p(object: LispObject) -> LispObject {
LispObject::from_bool(object.as_buffer().map_or(false, |m| m.is_live()))
}

/// Like Fassoc, but use Fstring_equal to compare
/// (which ignores text properties), and don't ever quit.
fn assoc_ignore_text_properties(key: LispObject, list: LispObject) -> LispObject {
let result = list.iter_tails_safe().find(|&item| {
string_equal(car(item.car()), key).is_not_nil()
});
if let Some(elt) = result {
elt.car()
} else {
LispObject::constant_nil()
}
}

/// Return the buffer named BUFFER-OR-NAME.
/// BUFFER-OR-NAME must be either a string or a buffer. If BUFFER-OR-NAME
/// is a string and there is no buffer with that name, return nil. If
/// BUFFER-OR-NAME is a buffer, return it as given.
#[lisp_fn]
pub fn get_buffer(buffer_or_name: LispObject) -> LispObject {
if buffer_or_name.is_buffer() {
buffer_or_name
} else {
buffer_or_name.as_string_or_error();
cdr(assoc_ignore_text_properties(
buffer_or_name,
LispObject::from_raw(unsafe { Vbuffer_alist }),
))
}
}
12 changes: 7 additions & 5 deletions rust_src/src/crypto/mod.rs
Expand Up @@ -4,7 +4,8 @@ use std::{ptr, slice};
use libc::{c_char, c_void, size_t};

use lisp::LispObject;
use remacs_sys::{nsberror, Fcurrent_buffer, Fget_buffer, EmacsInt, make_uninit_string};
use buffers::get_buffer;
use remacs_sys::{nsberror, Fcurrent_buffer, EmacsInt, make_uninit_string};
use remacs_macros::lisp_fn;

#[no_mangle]
Expand Down Expand Up @@ -79,11 +80,12 @@ pub unsafe extern "C" fn sha512_buffer(
/// disregarding any coding systems. If nil, use the current buffer.
#[lisp_fn(min = "0")]
fn buffer_hash(buffer_or_name: LispObject) -> LispObject {
let buffer = LispObject::from_raw(if buffer_or_name.is_nil() {
unsafe { Fcurrent_buffer() }
let buffer = if buffer_or_name.is_nil() {
LispObject::from_raw(unsafe { Fcurrent_buffer() })
} else {
unsafe { Fget_buffer(buffer_or_name.to_raw()) }
});
get_buffer(buffer_or_name)
};

if buffer.is_nil() {
unsafe { nsberror(buffer_or_name.to_raw()) };
}
Expand Down
2 changes: 2 additions & 0 deletions rust_src/src/lib.rs
Expand Up @@ -107,6 +107,7 @@ pub use strings::Fstring_lessp;
pub use vectors::Flength;
pub use vectors::Fsort;
pub use lists::merge;
pub use buffers::Fget_buffer;

// Cryptographic functions used in the C codebase.
pub use crypto::sha1_buffer;
Expand Down Expand Up @@ -139,6 +140,7 @@ pub extern "C" fn rust_init_syms() {
unsafe {
defsubr(&*buffers::Soverlayp);
defsubr(&*buffers::Sbuffer_live_p);
defsubr(&*buffers::Sget_buffer);
defsubr(&*windows::Swindowp);
defsubr(&*lists::Satom);
defsubr(&*lists::Slistp);
Expand Down
4 changes: 2 additions & 2 deletions rust_src/src/lists.rs
Expand Up @@ -53,7 +53,7 @@ fn setcdr(cell: LispObject, newcdr: LispObject) -> LispObject {
/// See Info node `(elisp)Cons Cells' for a discussion of related basic
/// Lisp concepts such as car, cdr, cons cell and list.
#[lisp_fn]
fn car(list: LispObject) -> LispObject {
pub fn car(list: LispObject) -> LispObject {
if list.is_nil() {
list
} else {
Expand All @@ -67,7 +67,7 @@ fn car(list: LispObject) -> LispObject {
/// See Info node `(elisp)Cons Cells' for a discussion of related basic
/// Lisp concepts such as cdr, car, cons cell and list.
#[lisp_fn]
fn cdr(list: LispObject) -> LispObject {
pub fn cdr(list: LispObject) -> LispObject {
if list.is_nil() {
list
} else {
Expand Down
2 changes: 1 addition & 1 deletion rust_src/src/strings.rs
Expand Up @@ -98,7 +98,7 @@ fn string_bytes(string: LispObject) -> LispObject {
/// Case is significant, but text properties are ignored.
/// Symbols are also allowed; their print names are used instead.
#[lisp_fn]
fn string_equal(mut s1: LispObject, mut s2: LispObject) -> LispObject {
pub fn string_equal(mut s1: LispObject, mut s2: LispObject) -> LispObject {
if s1.is_symbol() {
s1 = LispObject::from_raw(unsafe { SYMBOL_NAME(s1.to_raw()) });
}
Expand Down
31 changes: 0 additions & 31 deletions src/buffer.c
Expand Up @@ -405,36 +405,6 @@ followed by the rest of the buffers. */)
return general;
}

/* Like Fassoc, but use Fstring_equal to compare
(which ignores text properties), and don't ever quit. */

static Lisp_Object
assoc_ignore_text_properties (Lisp_Object key, Lisp_Object list)
{
Lisp_Object tail;
for (tail = list; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object elt = XCAR (tail);
if (!NILP (Fstring_equal (Fcar (elt), key)))
return elt;
}
return Qnil;
}

DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,
doc: /* Return the buffer named BUFFER-OR-NAME.
BUFFER-OR-NAME must be either a string or a buffer. If BUFFER-OR-NAME
is a string and there is no buffer with that name, return nil. If
BUFFER-OR-NAME is a buffer, return it as given. */)
(register Lisp_Object buffer_or_name)
{
if (BUFFERP (buffer_or_name))
return buffer_or_name;
CHECK_STRING (buffer_or_name);

return Fcdr (assoc_ignore_text_properties (buffer_or_name, Vbuffer_alist));
}

DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
doc: /* Return the buffer visiting file FILENAME (a string).
The buffer's `buffer-file-name' must match exactly the expansion of FILENAME.
Expand Down Expand Up @@ -6172,7 +6142,6 @@ Functions running this hook are, `get-buffer-create',
DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");

defsubr (&Sbuffer_list);
defsubr (&Sget_buffer);
defsubr (&Sget_file_buffer);
defsubr (&Sget_buffer_create);
defsubr (&Smake_indirect_buffer);
Expand Down