From cbe8d222a82c14485cf416c4b85fd5e58363c0e0 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 21 Feb 2011 00:56:09 -0500 Subject: Implement sha-1 in standard library. Closes #228 --- src/lib/sha1.rs | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/std.rc | 1 + 2 files changed, 285 insertions(+) create mode 100644 src/lib/sha1.rs (limited to 'src/lib') diff --git a/src/lib/sha1.rs b/src/lib/sha1.rs new file mode 100644 index 00000000..8be969aa --- /dev/null +++ b/src/lib/sha1.rs @@ -0,0 +1,284 @@ +/* + * A SHA-1 implementation derived from Paul E. Jones's reference + * implementation, which is written for clarity, not speed. At some + * point this will want to be rewritten. + */ + +import std._vec; +import std._str; + +export sha1; +export mk_sha1; + +state type sha1 = state obj { + // Provide message input as bytes + fn input(&vec[u8]); + + // Provide message input as string + fn input_str(&str); + + // Read the digest as a vector of 20 bytes. After + // calling this no further input may provided + // until reset is called + fn result() -> vec[u8]; + + // Reset the sha1 state for reuse. This is called + // automatically during construction + fn reset(); +}; + +// Some unexported constants +const uint digest_buf_len = 5; +const uint msg_block_len = 64; + +// Builds a sha1 object +fn mk_sha1() -> sha1 { + + state type sha1state = rec(vec[mutable u32] h, + mutable u32 len_low, + mutable u32 len_high, + vec[mutable u8] msg_block, + mutable uint msg_block_idx, + mutable bool computed); + + impure fn add_input(&sha1state st, &vec[u8] msg) { + // FIXME: Should be typestate precondition + check (!st.computed); + + for (u8 element in msg) { + st.msg_block.(st.msg_block_idx) = element; + st.msg_block_idx += 1u; + + st.len_low += 8u32; + if (st.len_low == 0u32) { + st.len_high += 1u32; + if (st.len_high == 0u32) { + // FIXME: Need better failure mode + fail; + } + } + + if (st.msg_block_idx == msg_block_len) { + process_msg_block(st); + } + } + } + + impure fn process_msg_block(&sha1state st) { + + // FIXME: Make precondition + check (_vec.len[mutable u32](st.h) == digest_buf_len); + + // Constants + auto k = vec(0x5A827999u32, + 0x6ED9EBA1u32, + 0x8F1BBCDCu32, + 0xCA62C1D6u32); + + let int t; // Loop counter + let vec[mutable u32] w = _vec.init_elt[mutable u32](0u32, 80u); + + // Initialize the first 16 words of the vector w + t = 0; + while (t < 16) { + w.(t) = (st.msg_block.(t * 4) as u32) << 24u32; + w.(t) = w.(t) | ((st.msg_block.(t * 4 + 1) as u32) << 16u32); + w.(t) = w.(t) | ((st.msg_block.(t * 4 + 2) as u32) << 8u32); + w.(t) = w.(t) | (st.msg_block.(t * 4 + 3) as u32); + t += 1; + } + + // Initialize the rest of vector w + while (t < 80) { + auto val = w.(t-3) ^ w.(t-8) ^ w.(t-14) ^ w.(t-16); + w.(t) = circular_shift(1u32, val); + t += 1; + } + + auto a = st.h.(0); + auto b = st.h.(1); + auto c = st.h.(2); + auto d = st.h.(3); + auto e = st.h.(4); + + let u32 temp; + + t = 0; + while (t < 20) { + temp = circular_shift(5u32, a) + + ((b & c) | ((~b) & d)) + e + w.(t) + k.(0); + e = d; + d = c; + c = circular_shift(30u32, b); + b = a; + a = temp; + t += 1; + } + + while (t < 40) { + temp = circular_shift(5u32, a) + + (b ^ c ^ d) + e + w.(t) + k.(1); + e = d; + d = c; + c = circular_shift(30u32, b); + b = a; + a = temp; + t += 1; + } + + while (t < 60) { + temp = circular_shift(5u32, a) + + ((b & c) | (b & d) | (c & d)) + e + w.(t) + k.(2); + e = d; + d = c; + c = circular_shift(30u32, b); + b = a; + a = temp; + t += 1; + } + + while (t < 80) { + temp = circular_shift(5u32, a) + + (b ^ c ^ d) + e + w.(t) + k.(3); + e = d; + d = c; + c = circular_shift(30u32, b); + b = a; + a = temp; + t += 1; + } + + st.h.(0) = st.h.(0) + a; + st.h.(1) = st.h.(1) + b; + st.h.(2) = st.h.(2) + c; + st.h.(3) = st.h.(3) + d; + st.h.(4) = st.h.(4) + e; + + st.msg_block_idx = 0u; + } + + fn circular_shift(u32 bits, u32 word) -> u32 { + // FIXME: This is a workaround for a rustboot + // "unrecognized quads" codegen bug + auto bits_hack = bits; + ret (word << bits_hack) | (word >> (32u32 - bits)); + } + + impure fn mk_result(&sha1state st) -> vec[u8] { + if (!st.computed) { + pad_msg(st); + st.computed = true; + } + + let vec[u8] res = vec(); + for (u32 hpart in st.h) { + res += (hpart >> 24u32) & 0xFFu32 as u8; + res += (hpart >> 16u32) & 0xFFu32 as u8; + res += (hpart >> 8u32) & 0xFFu32 as u8; + res += hpart & 0xFFu32 as u8; + } + ret res; + } + + /* + * According to the standard, the message must be padded to an even + * 512 bits. The first padding bit must be a '1'. The last 64 bits + * represent the length of the original message. All bits in between + * should be 0. This function will pad the message according to those + * rules by filling the message_block array accordingly. It will also + * call ProcessMessageBlock() appropriately. When it returns, it + * can be assumed that the message digest has been computed. + */ + impure fn pad_msg(&sha1state st) { + // FIXME: Should be a precondition + check (_vec.len[mutable u8](st.msg_block) == msg_block_len); + + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second block. + */ + if (st.msg_block_idx > 55u) { + st.msg_block.(st.msg_block_idx) = 0x80u8; + st.msg_block_idx += 1u; + + while (st.msg_block_idx < msg_block_len) { + st.msg_block.(st.msg_block_idx) = 0u8; + st.msg_block_idx += 1u; + } + + process_msg_block(st); + } else { + st.msg_block.(st.msg_block_idx) = 0x80u8; + st.msg_block_idx += 1u; + } + + while (st.msg_block_idx < 56u) { + st.msg_block.(st.msg_block_idx) = 0u8; + st.msg_block_idx += 1u; + } + + // Store the message length as the last 8 octets + st.msg_block.(56) = (st.len_high >> 24u32) & 0xFFu32 as u8; + st.msg_block.(57) = (st.len_high >> 16u32) & 0xFFu32 as u8; + st.msg_block.(58) = (st.len_high >> 8u32) & 0xFFu32 as u8; + st.msg_block.(59) = st.len_high & 0xFFu32 as u8; + st.msg_block.(60) = (st.len_low >> 24u32) & 0xFFu32 as u8; + st.msg_block.(61) = (st.len_low >> 16u32) & 0xFFu32 as u8; + st.msg_block.(62) = (st.len_low >> 8u32) & 0xFFu32 as u8; + st.msg_block.(63) = st.len_low & 0xFFu32 as u8; + + process_msg_block(st); + } + + state obj sha1(sha1state st) { + + fn reset() { + // FIXME: Should be typestate precondition + check (_vec.len[mutable u32](st.h) == digest_buf_len); + + st.len_low = 0u32; + st.len_high = 0u32; + st.msg_block_idx = 0u; + + st.h.(0) = 0x67452301u32; + st.h.(1) = 0xEFCDAB89u32; + st.h.(2) = 0x98BADCFEu32; + st.h.(3) = 0x10325476u32; + st.h.(4) = 0xC3D2E1F0u32; + + st.computed = false; + } + + fn input(&vec[u8] msg) { + add_input(st, msg); + } + + fn input_str(&str msg) { + add_input(st, _str.bytes(msg)); + } + + fn result() -> vec[u8] { + ret mk_result(st); + } + } + + auto st = rec(h = _vec.init_elt[mutable u32](0u32, digest_buf_len), + mutable len_low = 0u32, + mutable len_high = 0u32, + msg_block = _vec.init_elt[mutable u8](0u8, msg_block_len), + mutable msg_block_idx = 0u, + mutable computed = false); + auto sh = sha1(st); + sh.reset(); + ret sh; +} + +// Local Variables: +// mode: rust; +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: diff --git a/src/lib/std.rc b/src/lib/std.rc index 102aa4d1..3500c4b3 100644 --- a/src/lib/std.rc +++ b/src/lib/std.rc @@ -57,6 +57,7 @@ mod dbg; mod bitv; mod sort; mod path; +mod sha1; // Local Variables: // mode: rust; -- cgit v1.2.3 From c4df39609c9c09c450dd8fe5905a8e6fbeb5f181 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 22 Feb 2011 18:58:07 -0500 Subject: Rename std._io to std.io since 'io' is no longer a keyword --- src/lib/_io.rs | 183 --------------------------------------------------------- src/lib/io.rs | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/std.rc | 4 +- 3 files changed, 185 insertions(+), 185 deletions(-) delete mode 100644 src/lib/_io.rs create mode 100644 src/lib/io.rs (limited to 'src/lib') diff --git a/src/lib/_io.rs b/src/lib/_io.rs deleted file mode 100644 index f285f6c8..00000000 --- a/src/lib/_io.rs +++ /dev/null @@ -1,183 +0,0 @@ -import std.os.libc; -import std._str; -import std._vec; - - -type stdio_reader = state obj { - fn getc() -> int; - fn ungetc(int i); -}; - -fn new_stdio_reader(str path) -> stdio_reader { - state obj stdio_FILE_reader(os.libc.FILE f) { - fn getc() -> int { - ret os.libc.fgetc(f); - } - fn ungetc(int i) { - os.libc.ungetc(i, f); - } - drop { - os.libc.fclose(f); - } - } - auto FILE = os.libc.fopen(_str.buf(path), _str.buf("r")); - check (FILE as uint != 0u); - ret stdio_FILE_reader(FILE); -} - - -type buf_reader = state obj { - fn read() -> vec[u8]; -}; - -type buf_writer = state obj { - fn write(vec[u8] v); -}; - -fn default_bufsz() -> uint { - ret 4096u; -} - -fn new_buf() -> vec[u8] { - ret _vec.alloc[u8](default_bufsz()); -} - -fn new_buf_reader(str path) -> buf_reader { - - state obj fd_buf_reader(int fd, mutable vec[u8] buf) { - - fn read() -> vec[u8] { - - // Ensure our buf is singly-referenced. - if (_vec.rustrt.refcount[u8](buf) != 1u) { - buf = new_buf(); - } - - auto len = default_bufsz(); - auto vbuf = _vec.buf[u8](buf); - auto count = os.libc.read(fd, vbuf, len); - - if (count < 0) { - log "error filling buffer"; - log sys.rustrt.last_os_error(); - fail; - } - - _vec.len_set[u8](buf, count as uint); - ret buf; - } - - drop { - os.libc.close(fd); - } - } - - auto fd = os.libc.open(_str.buf(path), - os.libc_constants.O_RDONLY() | - os.libc_constants.O_BINARY(), - 0u); - - if (fd < 0) { - log "error opening file for reading"; - log sys.rustrt.last_os_error(); - fail; - } - ret fd_buf_reader(fd, new_buf()); -} - -/** - * FIXME (issue #150): This should be - * - * type fileflag = tag(append(), create(), truncate()); - * - * but then the tag value ctors are not found from crate-importers of std, so - * we manually simulate the enum below. - */ -type fileflag = uint; -fn append() -> uint { ret 0u; } -fn create() -> uint { ret 1u; } -fn truncate() -> uint { ret 2u; } - -fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer { - - state obj fd_buf_writer(int fd) { - - fn write(vec[u8] v) { - auto len = _vec.len[u8](v); - auto count = 0u; - auto vbuf; - while (count < len) { - vbuf = _vec.buf_off[u8](v, count); - auto nout = os.libc.write(fd, vbuf, len); - if (nout < 0) { - log "error dumping buffer"; - log sys.rustrt.last_os_error(); - fail; - } - count += nout as uint; - } - } - - drop { - os.libc.close(fd); - } - } - - let int fflags = - os.libc_constants.O_WRONLY() | - os.libc_constants.O_BINARY(); - - for (fileflag f in flags) { - alt (f) { - // FIXME (issue #150): cf comment above defn of fileflag type - //case (append()) { fflags |= os.libc_constants.O_APPEND(); } - //case (create()) { fflags |= os.libc_constants.O_CREAT(); } - //case (truncate()) { fflags |= os.libc_constants.O_TRUNC(); } - case (0u) { fflags |= os.libc_constants.O_APPEND(); } - case (1u) { fflags |= os.libc_constants.O_CREAT(); } - case (2u) { fflags |= os.libc_constants.O_TRUNC(); } - } - } - - auto fd = os.libc.open(_str.buf(path), - fflags, - os.libc_constants.S_IRUSR() | - os.libc_constants.S_IWUSR()); - - if (fd < 0) { - log "error opening file for writing"; - log sys.rustrt.last_os_error(); - fail; - } - ret fd_buf_writer(fd); -} - -type writer = - state obj { - fn write_str(str s); - fn write_int(int n); - fn write_uint(uint n); - }; - -fn file_writer(str path, - vec[fileflag] flags) - -> writer -{ - state obj fw(buf_writer out) { - fn write_str(str s) { out.write(_str.bytes(s)); } - fn write_int(int n) { out.write(_str.bytes(_int.to_str(n, 10u))); } - fn write_uint(uint n) { out.write(_str.bytes(_uint.to_str(n, 10u))); } - } - ret fw(new_buf_writer(path, flags)); -} - -// -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; -// End: -// diff --git a/src/lib/io.rs b/src/lib/io.rs new file mode 100644 index 00000000..f285f6c8 --- /dev/null +++ b/src/lib/io.rs @@ -0,0 +1,183 @@ +import std.os.libc; +import std._str; +import std._vec; + + +type stdio_reader = state obj { + fn getc() -> int; + fn ungetc(int i); +}; + +fn new_stdio_reader(str path) -> stdio_reader { + state obj stdio_FILE_reader(os.libc.FILE f) { + fn getc() -> int { + ret os.libc.fgetc(f); + } + fn ungetc(int i) { + os.libc.ungetc(i, f); + } + drop { + os.libc.fclose(f); + } + } + auto FILE = os.libc.fopen(_str.buf(path), _str.buf("r")); + check (FILE as uint != 0u); + ret stdio_FILE_reader(FILE); +} + + +type buf_reader = state obj { + fn read() -> vec[u8]; +}; + +type buf_writer = state obj { + fn write(vec[u8] v); +}; + +fn default_bufsz() -> uint { + ret 4096u; +} + +fn new_buf() -> vec[u8] { + ret _vec.alloc[u8](default_bufsz()); +} + +fn new_buf_reader(str path) -> buf_reader { + + state obj fd_buf_reader(int fd, mutable vec[u8] buf) { + + fn read() -> vec[u8] { + + // Ensure our buf is singly-referenced. + if (_vec.rustrt.refcount[u8](buf) != 1u) { + buf = new_buf(); + } + + auto len = default_bufsz(); + auto vbuf = _vec.buf[u8](buf); + auto count = os.libc.read(fd, vbuf, len); + + if (count < 0) { + log "error filling buffer"; + log sys.rustrt.last_os_error(); + fail; + } + + _vec.len_set[u8](buf, count as uint); + ret buf; + } + + drop { + os.libc.close(fd); + } + } + + auto fd = os.libc.open(_str.buf(path), + os.libc_constants.O_RDONLY() | + os.libc_constants.O_BINARY(), + 0u); + + if (fd < 0) { + log "error opening file for reading"; + log sys.rustrt.last_os_error(); + fail; + } + ret fd_buf_reader(fd, new_buf()); +} + +/** + * FIXME (issue #150): This should be + * + * type fileflag = tag(append(), create(), truncate()); + * + * but then the tag value ctors are not found from crate-importers of std, so + * we manually simulate the enum below. + */ +type fileflag = uint; +fn append() -> uint { ret 0u; } +fn create() -> uint { ret 1u; } +fn truncate() -> uint { ret 2u; } + +fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer { + + state obj fd_buf_writer(int fd) { + + fn write(vec[u8] v) { + auto len = _vec.len[u8](v); + auto count = 0u; + auto vbuf; + while (count < len) { + vbuf = _vec.buf_off[u8](v, count); + auto nout = os.libc.write(fd, vbuf, len); + if (nout < 0) { + log "error dumping buffer"; + log sys.rustrt.last_os_error(); + fail; + } + count += nout as uint; + } + } + + drop { + os.libc.close(fd); + } + } + + let int fflags = + os.libc_constants.O_WRONLY() | + os.libc_constants.O_BINARY(); + + for (fileflag f in flags) { + alt (f) { + // FIXME (issue #150): cf comment above defn of fileflag type + //case (append()) { fflags |= os.libc_constants.O_APPEND(); } + //case (create()) { fflags |= os.libc_constants.O_CREAT(); } + //case (truncate()) { fflags |= os.libc_constants.O_TRUNC(); } + case (0u) { fflags |= os.libc_constants.O_APPEND(); } + case (1u) { fflags |= os.libc_constants.O_CREAT(); } + case (2u) { fflags |= os.libc_constants.O_TRUNC(); } + } + } + + auto fd = os.libc.open(_str.buf(path), + fflags, + os.libc_constants.S_IRUSR() | + os.libc_constants.S_IWUSR()); + + if (fd < 0) { + log "error opening file for writing"; + log sys.rustrt.last_os_error(); + fail; + } + ret fd_buf_writer(fd); +} + +type writer = + state obj { + fn write_str(str s); + fn write_int(int n); + fn write_uint(uint n); + }; + +fn file_writer(str path, + vec[fileflag] flags) + -> writer +{ + state obj fw(buf_writer out) { + fn write_str(str s) { out.write(_str.bytes(s)); } + fn write_int(int n) { out.write(_str.bytes(_int.to_str(n, 10u))); } + fn write_uint(uint n) { out.write(_str.bytes(_uint.to_str(n, 10u))); } + } + ret fw(new_buf_writer(path, flags)); +} + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: +// diff --git a/src/lib/std.rc b/src/lib/std.rc index 3500c4b3..4ad422a3 100644 --- a/src/lib/std.rc +++ b/src/lib/std.rc @@ -14,7 +14,7 @@ mod _str; // General IO and system-services modules. -mod _io; +mod io; mod sys; mod _task; @@ -25,7 +25,7 @@ mod util; // Authorize various rule-bendings. -auth _io = unsafe; +auth io = unsafe; auth _str = unsafe; auth _vec = unsafe; auth _task = unsafe; -- cgit v1.2.3 From 3b7e9dc393c7b015bb06a8cc1213c25b8911362f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 22 Feb 2011 18:50:39 -0500 Subject: Rustify some comments lifted directly from the sha-1 reference implementation --- src/lib/sha1.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/sha1.rs b/src/lib/sha1.rs index 8be969aa..2a6b74d4 100644 --- a/src/lib/sha1.rs +++ b/src/lib/sha1.rs @@ -185,8 +185,8 @@ fn mk_sha1() -> sha1 { * 512 bits. The first padding bit must be a '1'. The last 64 bits * represent the length of the original message. All bits in between * should be 0. This function will pad the message according to those - * rules by filling the message_block array accordingly. It will also - * call ProcessMessageBlock() appropriately. When it returns, it + * rules by filling the msg_block vector accordingly. It will also + * call process_msg_block() appropriately. When it returns, it * can be assumed that the message digest has been computed. */ impure fn pad_msg(&sha1state st) { -- cgit v1.2.3 From 330c9c6c3592496462dbf9aa716a37e048b00172 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 6 Mar 2011 13:42:50 -0500 Subject: Make _str.bytes use _vec.init_fn. Remove FIXME. --- src/lib/_str.rs | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'src/lib') diff --git a/src/lib/_str.rs b/src/lib/_str.rs index 6b7ac018..0e0e7650 100644 --- a/src/lib/_str.rs +++ b/src/lib/_str.rs @@ -96,25 +96,10 @@ fn buf(str s) -> sbuf { } fn bytes(str s) -> vec[u8] { - /* FIXME (issue #58): - * Should be... - * - * fn ith(str s, uint i) -> u8 { - * ret s.(i); - * } - * ret _vec.init_fn[u8](bind ith(s, _), byte_len(s)); - * - * but we do not correctly decrement refcount of s when - * the binding dies, so we have to do this manually. - */ - let uint n = _str.byte_len(s); - let vec[u8] v = _vec.alloc[u8](n); - let uint i = 0u; - while (i < n) { - v += vec(s.(i)); - i += 1u; + fn ith(str s, uint i) -> u8 { + ret s.(i); } - ret v; + ret _vec.init_fn[u8](bind ith(s, _), byte_len(s)); } fn from_bytes(vec[u8] v) : is_utf8(v) -> str { -- cgit v1.2.3 From bed457d3a7244b317c54962d80b460294b846c27 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 6 Mar 2011 13:51:42 -0500 Subject: Change io.fileflag to a tag type. Remove FIXME --- src/lib/io.rs | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) (limited to 'src/lib') diff --git a/src/lib/io.rs b/src/lib/io.rs index f285f6c8..9f428cee 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -85,18 +85,11 @@ fn new_buf_reader(str path) -> buf_reader { ret fd_buf_reader(fd, new_buf()); } -/** - * FIXME (issue #150): This should be - * - * type fileflag = tag(append(), create(), truncate()); - * - * but then the tag value ctors are not found from crate-importers of std, so - * we manually simulate the enum below. - */ -type fileflag = uint; -fn append() -> uint { ret 0u; } -fn create() -> uint { ret 1u; } -fn truncate() -> uint { ret 2u; } +tag fileflag { + append; + create; + truncate; +} fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer { @@ -129,13 +122,9 @@ fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer { for (fileflag f in flags) { alt (f) { - // FIXME (issue #150): cf comment above defn of fileflag type - //case (append()) { fflags |= os.libc_constants.O_APPEND(); } - //case (create()) { fflags |= os.libc_constants.O_CREAT(); } - //case (truncate()) { fflags |= os.libc_constants.O_TRUNC(); } - case (0u) { fflags |= os.libc_constants.O_APPEND(); } - case (1u) { fflags |= os.libc_constants.O_CREAT(); } - case (2u) { fflags |= os.libc_constants.O_TRUNC(); } + case (append) { fflags |= os.libc_constants.O_APPEND(); } + case (create) { fflags |= os.libc_constants.O_CREAT(); } + case (truncate) { fflags |= os.libc_constants.O_TRUNC(); } } } -- cgit v1.2.3 From 0624f9db4aeaa5681941750c3a1a17ca5fbb7e72 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 4 Mar 2011 07:22:43 +0100 Subject: Add a pretty-printer Adds a -pp option to the compiler which will cause it to simply pretty-print the given file. --- src/lib/io.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/lib') diff --git a/src/lib/io.rs b/src/lib/io.rs index 9f428cee..0c4eb39e 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -91,24 +91,28 @@ tag fileflag { truncate; } +fn writefd(int fd, vec[u8] v) { + auto len = _vec.len[u8](v); + auto count = 0u; + auto vbuf; + while (count < len) { + vbuf = _vec.buf_off[u8](v, count); + auto nout = os.libc.write(fd, vbuf, len); + if (nout < 0) { + log "error dumping buffer"; + log sys.rustrt.last_os_error(); + fail; + } + count += nout as uint; + } +} + fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer { state obj fd_buf_writer(int fd) { fn write(vec[u8] v) { - auto len = _vec.len[u8](v); - auto count = 0u; - auto vbuf; - while (count < len) { - vbuf = _vec.buf_off[u8](v, count); - auto nout = os.libc.write(fd, vbuf, len); - if (nout < 0) { - log "error dumping buffer"; - log sys.rustrt.last_os_error(); - fail; - } - count += nout as uint; - } + writefd(fd, v); } drop { -- cgit v1.2.3