Skip to content

Commit eb38f95

Browse files
committed
no_std; move some facilities to libraries
1 parent a3ef9bc commit eb38f95

File tree

8 files changed

+96
-179
lines changed

8 files changed

+96
-179
lines changed

Cargo.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ version = "0.1.0"
44
authors = ["M Farkas-Dyck <[email protected]>"]
55

66
[dependencies]
7-
libc = "0.2"
8-
libreal = "0.11"
9-
rustbox = "0.8"
10-
syscall = "0.2"
7+
containers = { version = "0.7", default-features = false, features = ["default_allocator"] }
8+
curse = "0.1"
9+
i-o = "0.2"
10+
loca = "0.5"
11+
libc = { version = "0.2", default-features = false }
12+
null-terminated = "0.2.6"
13+
unix = "0.2.1"

src/actLog.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use libreal::collections::vec::*;
1+
use super::Vec;
22

33
pub struct Act {
44
pub pt: (usize, usize),
@@ -44,7 +44,7 @@ impl ActLog {
4444

4545
#[inline]
4646
pub fn reag(&mut self) -> Option<&Act> {
47-
if self.pos >= self.acta.length() { None }
47+
if self.pos >= self.acta.len() { None }
4848
else {
4949
self.pos += 1;
5050
Some(&self.acta[self.pos - 1])

src/file.rs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/fs.rs

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/io.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
extern crate core;
1+
extern crate io as _io;
22

3-
use std::io;
4-
use std::io::{ Write };
3+
use core::mem;
4+
pub use self::_io::*;
55

6-
pub fn writeCode<Encode, I, T, W>(mut encode: Encode, w: &mut W, xs : I) -> io::Result<usize>
7-
where Encode: FnMut(T, &mut [u8]) -> Option<usize>, I: Iterator<Item = T>, T: Copy, W: Write {
8-
let mut buf = [0; 4096];
6+
fn fst2<S, T>((x, _): (S, T)) -> S { x }
7+
8+
pub fn writeCode<Codon, Encode, I, T, W>(mut encode: Encode, w: &mut W, xs : I) -> Result<usize, W::Err>
9+
where Codon: Copy, Encode: FnMut(T, &mut [Codon]) -> Option<usize>, I: Iterator<Item = T>, T: Copy, W: Write<Codon>, W::Err: From<EndOfFile> {
10+
let mut buf: [Codon; 4096] = unsafe { mem::uninitialized() };
911
let mut pos = 0;
1012
let mut nBytesWritten = 0;
1113
for x in xs {
@@ -20,7 +22,7 @@ pub fn writeCode<Encode, I, T, W>(mut encode: Encode, w: &mut W, xs : I) -> io::
2022
}
2123
}
2224
}
23-
try!(w.write_all(&buf[0..pos]));
25+
try!(w.write_all(&buf[0..pos]).map_err(fst2));
2426
nBytesWritten += pos;
2527
Ok(nBytesWritten)
2628
}

src/main.rs

Lines changed: 78 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1+
#![feature(decode_utf8)]
2+
#![feature(start)]
13
#![feature(unicode)]
24

3-
extern crate core;
5+
extern crate std as core;
6+
7+
extern crate containers;
8+
extern crate curse;
49
extern crate libc;
5-
extern crate libreal;
6-
#[macro_use]
7-
extern crate syscall;
8-
extern crate rustbox;
10+
extern crate null_terminated;
11+
extern crate unix;
912

1013
mod actLog;
11-
mod file;
12-
mod fs;
1314
mod io;
14-
mod random;
15-
mod sys;
1615

1716
use actLog::{ Act, ActLog };
18-
use core::default::Default;
17+
use containers::collections::*;
18+
use core::char::decode_utf8;
1919
use core::cmp::*;
20-
use fs::*;
21-
use libreal::collections::vec::*;
22-
use rustbox::{ RustBox, Key, RB_NORMAL, RB_REVERSE, RB_BOLD };
23-
use std::io::{ BufRead, Write };
20+
use core::mem;
21+
use curse::{ Key };
22+
use io::*;
23+
use null_terminated::Nul;
24+
use unix::err::OsErr;
25+
use unix::file::*;
26+
use unix::str::OsStr;
2427

2528
use Attitude::*;
2629
use Reach::*;
@@ -59,16 +62,16 @@ impl Buffer {
5962
}
6063

6164
fn deleteForth(&mut self) -> Option<Option<char>> {
62-
if self.pt.0 < self.xss[self.pt.1 - 1].length() {
65+
if self.pt.0 < self.xss[self.pt.1 - 1].len() {
6366
Some(Some(self.xss[self.pt.1 - 1].delete(self.pt.0)))
64-
} else if self.pt.1 <= self.xss.length() {
67+
} else if self.pt.1 <= self.xss.len() {
6568
let n = self.pt.1;
6669
if self.joinRow(n) { Some(Some('\n')) } else { None }
6770
} else { Some(None) }
6871
}
6972

7073
fn joinRow(&mut self, n: usize) -> bool {
71-
let l = self.xss[n].length();
74+
let l = self.xss[n].len();
7275
self.xss[self.pt.1 - 1].reserve(l) && {
7376
let xs = self.xss.delete(n);
7477
let _ = self.xss[n-1].append(xs);
@@ -80,20 +83,20 @@ impl Buffer {
8083
fn mv(&mut self, a: Attitude, r: Reach) {
8184
match (a, r) {
8285
(Left, End) => { self.pt.0 = 0; },
83-
(Right, End) => { self.pt.0 = self.xss[self.pt.1 - 1].length(); },
86+
(Right, End) => { self.pt.0 = self.xss[self.pt.1 - 1].len(); },
8487
(Up, End) => { self.pt.1 = 1; },
85-
(Down, End) => { self.pt.1 = self.xss.length() + 1; },
88+
(Down, End) => { self.pt.1 = self.xss.len() + 1; },
8689
(Left, Unit) => if self.pt.0 > 0 { self.pt.0 -= 1; }
8790
else if self.pt.1 > 1 { self.pt.1 -= 1; self.mv(Right, End); },
88-
(Right, Unit) => if self.pt.0 < self.xss[self.pt.1 - 1].length() { self.pt.0 += 1 }
89-
else if self.pt.1 < self.xss.length() { self.pt.1 += 1; self.mv(Left, End); },
91+
(Right, Unit) => if self.pt.0 < self.xss[self.pt.1 - 1].len() { self.pt.0 += 1 }
92+
else if self.pt.1 < self.xss.len() { self.pt.1 += 1; self.mv(Left, End); },
9093
(Up, Unit) => if self.pt.1 > 1 {
9194
self.pt.1 -= 1;
92-
self.pt.0 = min(self.pt.0, self.xss[self.pt.1 - 1].length());
95+
self.pt.0 = min(self.pt.0, self.xss[self.pt.1 - 1].len());
9396
},
94-
(Down, Unit) => if self.pt.1 < self.xss.length() {
97+
(Down, Unit) => if self.pt.1 < self.xss.len() {
9598
self.pt.1 += 1;
96-
self.pt.0 = min(self.pt.0, self.xss[self.pt.1 - 1].length());
99+
self.pt.0 = min(self.pt.0, self.xss[self.pt.1 - 1].len());
97100
},
98101
}
99102
}
@@ -113,7 +116,7 @@ enum Reach { End, Unit }
113116

114117
fn nextTabStop(logTS: usize, pos: usize) -> usize { (pos + (1 << logTS)) & (!0 << logTS) }
115118

116-
fn draw(ui: &RustBox, b: &EditBuffer, topRow: usize) {
119+
fn draw(ui: &mut curse::Term, b: &EditBuffer, topRow: usize) {
117120
assert!(topRow >= 1);
118121
let logTabStop = 3;
119122
let curse = |curs_x, p: &char| match *p {
@@ -124,37 +127,43 @@ fn draw(ui: &RustBox, b: &EditBuffer, topRow: usize) {
124127
for (curs_y, xs) in b.buffer.xss.iter().skip(topRow - 1).enumerate().take(ui.height() - 1) {
125128
let mut curs_x = 0;
126129
for x in xs.iter() {
127-
ui.print_char(curs_x, curs_y, RB_NORMAL, rustbox::Color::White, rustbox::Color::Black, *x);
130+
ui.print_char(curs_x, curs_y, curse::Face::empty(), curse::Color::White, curse::Color::Black, *x);
128131
curs_x = curse(curs_x, x);
129132
}
130133
}
131134
drawStatus(ui, b.status);
132-
ui.set_cursor(b.buffer.xss[b.buffer.pt.1 - 1].iter().take(b.buffer.pt.0).fold(0, curse) as isize, (b.buffer.pt.1 - topRow) as isize);
133-
ui.present();
135+
ui.set_cursor(b.buffer.xss[b.buffer.pt.1 - 1].iter().take(b.buffer.pt.0).fold(0, curse), b.buffer.pt.1 - topRow);
136+
ui.freshen();
137+
}
138+
139+
fn print_chars<I: Iterator<Item = char>>(ui: &mut curse::Term, x_pos: usize, y_pos: usize, face: curse::Face, fg: curse::Color, bg: curse::Color, xs: I) {
140+
for (i, x) in xs.enumerate() { ui.print_char(x_pos+i, y_pos, face, fg, bg, x) }
134141
}
135142

136-
fn drawStatus(ui: &RustBox, stat: Status) {
137-
let fgcolor = if stat.failure { rustbox::Color::Red } else { rustbox::Color::White };
138-
let bgcolor = rustbox::Color::Black;
143+
fn drawStatus(ui: &mut curse::Term, stat: Status) {
144+
let fgcolor = if stat.failure { curse::Color::Red } else { curse::Color::White };
145+
let bgcolor = curse::Color::Black;
139146
let curs_y = ui.height() - 1;
140147
for curs_x in 0..ui.width() {
141-
ui.print_char(curs_x, curs_y, RB_REVERSE, fgcolor, bgcolor, ' ');
148+
ui.print_char(curs_x, curs_y, curse::REVERSE, fgcolor, bgcolor, ' ');
142149
}
143150
if stat.failure {
144-
ui.print(0, curs_y, RB_REVERSE | RB_BOLD, fgcolor, bgcolor, "OPERATION FAILED");
151+
print_chars(ui, 0, curs_y, curse::REVERSE | curse::BOLD, fgcolor, bgcolor, "OPERATION FAILED".chars());
145152
} else if stat.unsavedWork == UnsavedWorkFlag::Warned {
146-
ui.print(0, curs_y, RB_REVERSE, fgcolor, bgcolor, "WARNING: File modified; work will be lost! (once more to quit)");
153+
print_chars(ui, 0, curs_y, curse::REVERSE, fgcolor, bgcolor, "WARNING: File modified; work will be lost! (once more to quit)".chars());
147154
} else {
148-
ui.print(0, curs_y, RB_REVERSE, fgcolor, bgcolor, stat.filePath);
155+
print_chars(ui, 0, curs_y, curse::REVERSE, fgcolor, bgcolor,
156+
decode_utf8(stat.filePath.iter().map(|&b|b))
157+
.map(|r| r.unwrap_or('\u{FFFD}')));
149158
for (i, &x) in ['[', match stat.unsavedWork { UnsavedWorkFlag::Saved => '-', _ => '*' }, ']'].into_iter().enumerate() {
150-
ui.print_char(stat.filePath.len() + i + 1, curs_y, RB_REVERSE, fgcolor, bgcolor, x);
159+
ui.print_char(stat.filePath.len() + i + 1, curs_y, curse::REVERSE, fgcolor, bgcolor, x);
151160
}
152161
}
153162
}
154163

155164
#[derive(Clone, Copy, PartialEq)]
156165
struct Status<'a> {
157-
filePath: &'a str,
166+
filePath: &'a OsStr,
158167
unsavedWork: UnsavedWorkFlag,
159168
failure: bool,
160169
}
@@ -212,58 +221,53 @@ impl<'a> EditBuffer<'a> {
212221

213222
fn encode_utf8_raw(x: char, b: &mut [u8]) -> Option<usize> {
214223
let l = x.len_utf8();
215-
if b.len() < l { None } else {
216-
for (i, c) in x.encode_utf8().enumerate() { b[i] = c }
217-
Some(l)
218-
}
224+
if b.len() < l { None } else { x.encode_utf8(b); Some(l) }
225+
}
226+
227+
#[start]
228+
fn start(_: isize, c_argv: *const *const u8) -> isize {
229+
extern { static environ: *const *const u8; }
230+
unsafe { main(mem::transmute(c_argv), mem::transmute(environ)) }
219231
}
220232

221-
fn main() {
222-
let (mut b, path_string) = match std::env::args().skip(1).next() {
223-
None => panic!("no file given"),
224-
Some(path) =>
225-
(EditBuffer {
226-
buffer: Buffer {
227-
xss: match std::fs::File::open(&path) {
228-
Err(_) => Vec::new(),
229-
Ok(f) => Vec::from_iter(std::io::BufReader::new(&f).
230-
lines().filter_map(Result::ok).
231-
map(|s| Vec::from_iter(s.chars()).ok().
232-
expect("alloc failed")).
233-
chain(Some(Vec::new()))).ok().
234-
expect("alloc failed"),
235-
},
236-
pt: (0, 1),
237-
},
238-
actLog: ActLog::new(),
239-
status: Status {
240-
filePath: "",
241-
unsavedWork: UnsavedWorkFlag::Saved,
242-
failure: false,
243-
},
244-
}, path),
233+
fn main(args: &'static Nul<&'static Nul<u8>>,
234+
_env: &'static Nul<&'static Nul<u8>>) -> isize {
235+
let path: &'static Nul<u8> = args.iter().skip(1).next().expect("no file given");
236+
let mut b = EditBuffer {
237+
buffer: Buffer {
238+
xss: Vec::from_iter(open_at(None, path, OpenMode::RdOnly, OpenFlags::empty(), FileMode::empty())
239+
.unwrap().split(|x| x == b'\n', false).map(Result::<_, OsErr>::unwrap)
240+
.map(|s| Vec::from_iter(decode_utf8(s.into_iter())
241+
.map(|r| r.unwrap_or('\u{FFFD}'))).ok()
242+
.expect("alloc failed"))).ok().expect("alloc failed"),
243+
pt: (0, 1),
244+
},
245+
actLog: ActLog::new(),
246+
status: Status {
247+
filePath: path,
248+
unsavedWork: UnsavedWorkFlag::Saved,
249+
failure: false,
250+
},
245251
};
246-
let path_bytes = { let mut p = path_string.clone().into_bytes(); p.push(0); p };
247-
b.status.filePath = path_string.as_str();
248-
let ui = RustBox::init(Default::default()).unwrap();
252+
let mut ui = curse::Term::init().unwrap();
249253

250254
loop {
251-
draw(&ui, &b, 1);
252-
b.status.failure = !match ui.poll_event(false) {
253-
Ok(rustbox::Event::KeyEvent(Some(key))) => match key {
255+
draw(&mut ui, &b, 1);
256+
b.status.failure = !match ui.next_event(None) {
257+
Ok(Some(curse::Event::Key(key))) => match key {
254258
Key::Left => { b.mv(Left, Unit); true },
255259
Key::Right => { b.mv(Right, Unit); true },
256260
Key::Up => { b.mv(Up, Unit); true },
257261
Key::Down => { b.mv(Down, Unit); true },
258262
Key::Home => { b.mv(Left, End); true },
259263
Key::End => { b.mv(Right, End); true },
260264
Key::Ctrl('c') => match b.status.unsavedWork {
261-
UnsavedWorkFlag::Saved | UnsavedWorkFlag::Warned => { return },
265+
UnsavedWorkFlag::Saved | UnsavedWorkFlag::Warned => { return 0 },
262266
UnsavedWorkFlag::Modified => { b.status.unsavedWork = UnsavedWorkFlag::Warned; true },
263267
},
264268
Key::Ctrl('x') => {
265-
let c = atomicWriteFileAt(
266-
libc::AT_FDCWD as isize, &path_bytes[0] as *const u8, true,
269+
let c = atomic_write_file_at(
270+
None, path, Clobber, (FilePermission::Read | FilePermission::Write) << USR,
267271
|mut f| {
268272
for (k, xs) in b.buffer.xss.iter().enumerate() {
269273
try!(io::writeCode(
@@ -277,7 +281,6 @@ fn main() {
277281
if c.is_ok() { b.status.unsavedWork = UnsavedWorkFlag::Saved };
278282
c.is_ok()
279283
},
280-
Key::Ctrl('h') |
281284
Key::Backspace => b.deleteBack(),
282285
Key::Tab => b.insert('\t'),
283286
Key::Enter => b.insert('\n'),

0 commit comments

Comments
 (0)