<commit_before>use extra::treemap::TreeMap;
use super::methods::Method;
use super::status;
use super::server::TcpStream;
use std::rt::io::Reader;
use std::{str, uint};
use super::rfc2616::{CR, LF, SP, HT, COLON};
use super::headers::{Headers, normalise_header_name};

pub enum HeaderLineErr { EndOfFile, EndOfHeaders, MalformedHeader }

////////////////////////////////////////////////////////////////////////////////////////////////////
pub struct RequestBuffer<'self> {
    priv stream: &'self mut TcpStream,
    priv bytes: ~[u8],
    priv peeked_byte: Option<u8>,
    priv read_buf: [u8, ..1],
}

static SIZE: uint = 1024;

impl<'self> RequestBuffer<'self> {
    pub fn new<'a> (stream: &'a mut TcpStream) -> RequestBuffer<'a> {
        RequestBuffer {
            stream: stream,
            bytes: ~[0u8, ..SIZE],
            peeked_byte: None,
            read_buf: [0u8],
        }
    }

    /*pub fn peek_byte(&mut self) -> Option<u8> {
        if self.peeked_byte.is_some() {
            fail!("Already called peek_byte() without having called read_byte()");
            // ... sorry, VERY nasty quick hack.
        }
    }*/

    pub fn read_byte(&mut self) -> Option<u8> {
        match self.peeked_byte {
            Some(byte) => {
                self.peeked_byte = None;
                Some(byte)
            },
            None => {
                match self.stream.read(self.read_buf) {
                    None => return None,
                    Some(1) => Some(self.read_buf[0]),
                    Some(i) => fail!("TcpStream.read() returned %u!?", i),
                }
            },
        }
    }

    /// Read a line ending in CRLF
    pub fn read_crlf_line(&mut self) -> ~str {
        self.bytes.clear();

        enum State { Normal, GotCR };
        let mut state = Normal;

        loop {
            state = match self.read_byte() {
                None => fail!("EOF"),
                Some(b) => match state {
                    Normal if b == CR => {
                        GotCR
                    },
                    GotCR if b == LF => {
                        break;
                    },
                    GotCR => {
                        self.bytes.push(CR);
                        self.bytes.push(b);
                        Normal
                    },
                    Normal => {
                        self.bytes.push(b);
                        Normal
                    }
                }
            };
        }
        str::from_bytes(self.bytes)
    }

    /// Read a header (name, value) pair.
    ///
    /// This is not necessarily just a line ending with CRLF; there are much fancier rules at work.
    /// Where appropriate (TODO, it's everywhere at present) linear whitespace is collapsed into a
    /// single space.
    ///
    /// # Error values
    ///
    /// - `EndOfHeaders`: I have no more headers to give; go forth and conquer on the body!
    /// - `EndOfFile`: socket was closed unexpectedly; probable best behavour is to drop the request
    /// - `MalformedHeader`: request is bad; you could drop it or try returning 400 Bad Request
    pub fn read_header_line(&mut self) -> Result<(~str, ~str), HeaderLineErr> {
        enum State2 { Normal, CompactingLWS, GotCR, GotCRLF };
        // XXX: not called State because of https://github.com/mozilla/rust/issues/7770
        // TODO: investigate quoted strings

        let mut state = Normal;
        let mut in_name = true;
        let mut header_name = ~"";
        self.bytes.clear();

        loop {
            state = match self.read_byte() {
                None => return Err(EndOfFile),
                Some(b) => match state {
                    Normal | CompactingLWS if b == CR => {
                        // It's OK to go to GotCR on CompactingLWS: if it ends up CRLFSP it'll get
                        // back to CompactingLWS, and if it ends up CRLF we didn't need the trailing
                        // whitespace anyway.
                        GotCR
                    },
                    Normal | CompactingLWS if in_name && b == COLON => {
                        // As above, don't worry about trailing whitespace.
                        // Found the colon, so switch across to value.
                        in_name = false;
                        header_name = str::from_bytes(self.bytes);
                        self.bytes.clear();
                        Normal
                    },
                    GotCR if b == LF && in_name && self.bytes.len() == 0 => {
                        return Err(EndOfHeaders);
                    },
                    GotCR if b == LF => {
                        GotCRLF
                    },
                    GotCR => {
                        // False alarm, CR without LF
                        self.bytes.push(CR);
                        self.bytes.push(b);
                        Normal
                    },
                    GotCRLF if b == SP || b == HT => {
                        // CR LF SP is a suitable linear whitespace, so don't stop yet
                        CompactingLWS
                    },
                    GotCRLF if in_name => {
                        // Don't worry about poking b; the request is being aborted
                        return Err(MalformedHeader);
                    },
                    GotCRLF => {
                        // Ooh! We got to a genuine end of line, so we're done
                        // But sorry, we don't want that byte after all...
                        self.peeked_byte = Some(b);
                        break;
                    },
                    Normal | CompactingLWS if b == SP || b == HT => {
                        // Start or continue to compact linear whitespace
                        CompactingLWS
                    },
                    CompactingLWS => {
                        // End of LWS, compact it down to a single space, unless it's at the start
                        // (saves a trim_left() call later)
                        if self.bytes.len() > 0 {
                            self.bytes.push(SP);
                        }
                        self.bytes.push(b);
                        Normal
                    },
                    Normal => {
                        self.bytes.push(b);
                        Normal
                    }
                },
            };
        }
        return Ok((header_name, str::from_bytes(self.bytes)));
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////

/// A HTTP request.
///
/// * `host`: The originating IP of the request
/// * `headers`: The headers of the request
/// * `body`: The body of the request as a string
/// * `method`: The method of the request
/// * `path`: The path of the request
/// * `close_connection`: whether the connection should be closed (or kept open waiting for more requests)
/// * `version`: The HTTP version
pub struct Request {
    //host: ip::IpAddr,
    headers: ~Headers,
    body: ~str,
    method: Method,
    path: ~str,
    close_connection: bool,
    version: (uint, uint)
}

/// Parse an HTTP request line into its parts.
///
/// `parse_request_line("GET /foo HTTP/1.1") == Ok((methods::GET, "/foo", (1, 1)))`
fn parse_request_line(line: ~str) -> Option<(Method, ~str, (uint, uint))> {
    // TODO: this probably isn't compliant
    /* * /let words : ~[&str] = line.word_iter().collect();
    if words.len() != 3 {
        return None;
    }
    let method = Method::from_str_or_new(words[0]);
    let path = words[1].to_owned();
    let http_version = parse_http_version(words[2]);
    match http_version {
        None => None,
        Some(v) => Some((method, path, v)),
    }
    /*/
    let mut words = line.word_iter();
    let method = match words.next() {
        Some(s) => Method::from_str_or_new(s),
        None => return None,
    };
    let path = match words.next() {
        Some(s) => s.to_owned(),
        None => return None,
    };
    let http_version = match words.next() {
        Some(s) => parse_http_version(s),
        None => return None,
    };
    match (words.next(), http_version) {
        (None, Some(v)) => Some((method, path, v)),
        _ => None,  // More words or invalid HTTP version
    }
    /**/
}

/// Parse an HTTP version string into the two X.Y parts.
///
/// At present, HTTP versions the server does not know about are rejected.
///
/// ~~~ {.rust}
/// assert_eq!(parse_http_version(~"HTTP/1.0"), Some((1, 0)))
/// assert_eq!(parse_http_version(~"HTTP/1.1"), Some((1, 1)))
/// assert_eq!(parse_http_version(~"HTTP/2.0"), Some((2, 0)))
/// ~~~
fn parse_http_version(version: &str) -> Option<(uint, uint)> {
    match version {
        // These two are efficiency shortcuts; they're expected to be all that we ever receive,
        // but naturally we mustn't let it crash on other inputs.
        "HTTP/1.0" => Some((1, 0)),
        "HTTP/1.1" => Some((1, 1)),
        v if v.starts_with("HTTP/") => {
            // This commented-out variant would fail! if given non-integers
            //let ints: ~[uint] = v.slice_from(5).split_iter('.').map(
            //    |&num| uint::from_str_radix(num, 10).get()).collect();
            let mut ints = [0u, 0u];
            for v.slice_from(5).split_iter('.').enumerate().advance |(i, strnum)| {
                if i > 1 {
                    // More than two numbers, e.g. HTTP/1.2.3
                    return None;
                }
                match uint::from_str_radix(strnum, 10) {
                    Some(num) => ints[i] = num,
                    None => return None,
                }
            }
            Some((ints[0], ints[1]))
        }
        _ => None
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_http_version() {
        assert_eq!(parse_http_version(~"HTTP/1.1"), Ok((1, 1)));
        assert_eq!(parse_http_version(~"HTTP/1.0"), Ok((1, 0)));
        assert_eq!(parse_http_version(~"HTTP/2.0"), Err(()));
    }

    #[test]
    fn test_parse_request_line() {
        assert_eq!(parse_request_line(~"GET /foo HTTP/1.1"), Ok((methods::GET, "/foo", (1, 1))));
        assert_eq!(parse_request_line(~"POST / HTTP/1.0"), Ok((methods::POST, "/", (1, 0))));
        assert_eq!(parse_request_line(~"POST / HTTP/2.0"), Err(()));
    }
}

/**/
impl Request {

    /// Get a response from an open socket.
    pub fn get(buffer: &mut RequestBuffer) -> Result<Request, status::Status> {

        let (method, path, version) = match parse_request_line(buffer.read_crlf_line()) {
            Some(vals) => vals,
            None => return Err(status::BadRequest),
        };

        let close_connection = match version {
            (1, 0) => true,
            (1, 1) => false,
            _ => return Err(status::HttpVersionNotSupported),
        };

        let mut headers = TreeMap::new();

        loop {
            match buffer.read_header_line() {
                Err(EndOfFile) => fail!("client disconnected, nowhere to send response"),
                Err(EndOfHeaders) => break,
                Err(MalformedHeader) => return Err(status::BadRequest),
                Ok((name, value)) => { headers.insert(normalise_header_name(name), value); },
            }
        }

        let close_connection = match headers.find(&~"Connection") {
            Some(s) => match s.to_ascii().to_lower().to_str_ascii() {
                ~"close" => true,
                ~"keep-alive" => false,
                _ => close_connection,
            },
            None => close_connection,
        };

        Ok(Request {
            //host: socket.get_peer_addr(),
            headers: ~headers,
            body: ~"",
            //body: str::connect_slices(lines, "\r\n"),
            method: method,
            path: path.to_owned(),
            close_connection: close_connection,
            version: version
        })
    }
}
/**/

/* What follows is most of Go's net/http module's definition of Request.

pub struct Request {
    // GET, POST, etc.
    method: ~Method,

    // The URL requested, constructed from the request line and (if available)
    // the Host header.
    url: ~Url,

    // The HTTP protocol version used; typically (1, 1)
    protocol: (uint, uint),

    // Request headers, all nicely and correctly parsed.
    headers: ~Headers,

    // The message body.
    body: Reader,

    // ContentLength records the length of the associated content.
    // The value -1 indicates that the length is unknown.
    // Values >= 0 indicate that the given number of bytes may
    // be read from Body.
    // For outgoing requests, a value of 0 means unknown if Body is not nil.
    content_length: i64,

    // TransferEncoding lists the transfer encodings from outermost to
    // innermost. An empty list denotes the "identity" encoding.
    // TransferEncoding can usually be ignored; chunked encoding is
    // automatically added and removed as necessary when sending and
    // receiving requests.
    transfer_encoding: ~[~str],

    // Close indicates whether to close the connection after
    // replying to this request.
    close: bool,

    // The host on which the URL is sought.
    // Per RFC 2616, this is either the value of the Host: header
    // or the host name given in the URL itself.
    // It may be of the form "host:port".
    host: ~str,

    // Form contains the parsed form data, including both the URL
    // field's query parameters and the POST or PUT form data.
    // This field is only available after ParseForm is called.
    // The HTTP client ignores Form and uses Body instead.
    form: url.Values,

    // PostForm contains the parsed form data from POST or PUT
    // body parameters.
    // This field is only available after ParseForm is called.
    // The HTTP client ignores PostForm and uses Body instead.
    post_form: url.Values,

    // MultipartForm is the parsed multipart form, including file uploads.
    // This field is only available after ParseMultipartForm is called.
    // The HTTP client ignores MultipartForm and uses Body instead.
    multipart_form: *multipart.Form,

    // Trailer maps trailer keys to values.  Like for Header, if the
    // response has multiple trailer lines with the same key, they will be
    // concatenated, delimited by commas.
    // For server requests, Trailer is only populated after Body has been
    // closed or fully consumed.
    // Trailer support is only partially complete.
    trailer: ~Headers,

    // RemoteAddr allows HTTP servers and other software to record
    // the network address that sent the request, usually for
    // logging. This field is not filled in by ReadRequest and
    // has no defined format. The HTTP server in this package
    // sets RemoteAddr to an "IP:port" address before invoking a
    // handler.
    // This field is ignored by the HTTP client.
    remote_addr: string,

    // RequestURI is the unmodified Request-URI of the
    // Request-Line (RFC 2616, Section 5.1) as sent by the client
    // to a server. Usually the URL field should be used instead.
    // It is an error to set this field in an HTTP client request.
    request_uri: string,

    // TLS allows HTTP servers and other software to record
    // information about the TLS connection on which the request
    // was received. This field is not filled in by ReadRequest.
    // The HTTP server in this package sets the field for
    // TLS-enabled connections before invoking a handler;
    // otherwise it leaves the field nil.
    // This field is ignored by the HTTP client.
    tls: *tls.ConnectionState,
}*/
<commit_msg>Buffer request reads for better performance.<commit_after>use extra::treemap::TreeMap;
use super::methods::Method;
use super::status;
use super::server::TcpStream;
use std::rt::io::Reader;
use std::{str, uint};
use super::rfc2616::{CR, LF, SP, HT, COLON};
use super::headers::{Headers, normalise_header_name};

pub enum HeaderLineErr { EndOfFile, EndOfHeaders, MalformedHeader }

/// Line/header can't be more than 4KB long (note that with the compacting of LWS the actual source
/// data could be longer than 4KB)
static MAX_LINE_LEN: uint = 0x1000;

/// Moderately arbitrary figure: read in 64KB chunks. GET requests should never be this large.
static BUF_SIZE: uint = 0x10000;  // Let's try 64KB chunks

pub struct RequestBuffer<'self> {
    /// The socket connection to read from
    priv stream: &'self mut TcpStream,

    /// A working space for
    priv line_bytes: ~[u8],

    /// Header reading takes the first byte of the next line in its search for linear white space;
    /// clearly, we mustn't lose it...
    priv peeked_byte: Option<u8>,

    /// A buffer because TcpStream.read() is SLOW.
    priv read_buf: [u8, .. BUF_SIZE],
    priv read_buf_pos: uint,
    priv read_buf_max: uint,
}

impl<'self> RequestBuffer<'self> {
    pub fn new<'a> (stream: &'a mut TcpStream) -> RequestBuffer<'a> {
        RequestBuffer {
            stream: stream,
            line_bytes: ~[0u8, .. MAX_LINE_LEN],
            peeked_byte: None,
            read_buf: [0u8, .. BUF_SIZE],
            read_buf_pos: 0u,
            read_buf_max: 0u,
        }
    }

    /*pub fn peek_byte(&mut self) -> Option<u8> {
        if self.peeked_byte.is_some() {
            fail!("Already called peek_byte() without having called read_byte()");
            // ... sorry, VERY nasty quick hack.
        }
    }*/

    #[inline]
    fn read_byte(&mut self) -> Option<u8> {
        match self.peeked_byte {
            Some(byte) => {
                self.peeked_byte = None;
                Some(byte)
            },
            None => {
                if self.read_buf_pos == self.read_buf_max {
                    match self.stream.read(self.read_buf) {
                        // Not sure if Some(0) can happen. Hope not!
                        None | Some(0) => {
                            self.read_buf_pos = 0;
                            self.read_buf_max = 0;
                            None
                        },
                        Some(i) => {
                            self.read_buf_pos = 1;
                            self.read_buf_max = i;
                            Some(self.read_buf[0])
                        },
                    }
                } else {
                    self.read_buf_pos += 1;
                    Some(self.read_buf[self.read_buf_pos - 1])
                }
            },
        }
    }

    /// Read a line ending in CRLF
    pub fn read_crlf_line(&mut self) -> ~str {
        self.line_bytes.clear();

        enum State { Normal, GotCR };
        let mut state = Normal;

        loop {
            state = match self.read_byte() {
                None => fail!("EOF"),
                Some(b) => match state {
                    Normal if b == CR => {
                        GotCR
                    },
                    GotCR if b == LF => {
                        break;
                    },
                    GotCR => {
                        self.line_bytes.push(CR);
                        self.line_bytes.push(b);
                        Normal
                    },
                    Normal => {
                        self.line_bytes.push(b);
                        Normal
                    }
                }
            };
        }
        str::from_bytes(self.line_bytes)
    }

    /// Read a header (name, value) pair.
    ///
    /// This is not necessarily just a line ending with CRLF; there are much fancier rules at work.
    /// Where appropriate (TODO, it's everywhere at present) linear whitespace is collapsed into a
    /// single space.
    ///
    /// # Error values
    ///
    /// - `EndOfHeaders`: I have no more headers to give; go forth and conquer on the body!
    /// - `EndOfFile`: socket was closed unexpectedly; probable best behavour is to drop the request
    /// - `MalformedHeader`: request is bad; you could drop it or try returning 400 Bad Request
    pub fn read_header_line(&mut self) -> Result<(~str, ~str), HeaderLineErr> {
        enum State2 { Normal, CompactingLWS, GotCR, GotCRLF };
        // XXX: not called State because of https://github.com/mozilla/rust/issues/7770
        // TODO: investigate quoted strings

        let mut state = Normal;
        let mut in_name = true;
        let mut header_name = ~"";
        self.line_bytes.clear();

        loop {
            state = match self.read_byte() {
                None => return Err(EndOfFile),
                Some(b) => match state {
                    Normal | CompactingLWS if b == CR => {
                        // It's OK to go to GotCR on CompactingLWS: if it ends up CRLFSP it'll get
                        // back to CompactingLWS, and if it ends up CRLF we didn't need the trailing
                        // whitespace anyway.
                        GotCR
                    },
                    Normal | CompactingLWS if in_name && b == COLON => {
                        // As above, don't worry about trailing whitespace.
                        // Found the colon, so switch across to value.
                        in_name = false;
                        header_name = str::from_bytes(self.line_bytes);
                        self.line_bytes.clear();
                        Normal
                    },
                    GotCR if b == LF && in_name && self.line_bytes.len() == 0 => {
                        return Err(EndOfHeaders);
                    },
                    GotCR if b == LF => {
                        GotCRLF
                    },
                    GotCR => {
                        // False alarm, CR without LF
                        self.line_bytes.push(CR);
                        self.line_bytes.push(b);
                        Normal
                    },
                    GotCRLF if b == SP || b == HT => {
                        // CR LF SP is a suitable linear whitespace, so don't stop yet
                        CompactingLWS
                    },
                    GotCRLF if in_name => {
                        // Don't worry about poking b; the request is being aborted
                        return Err(MalformedHeader);
                    },
                    GotCRLF => {
                        // Ooh! We got to a genuine end of line, so we're done
                        // But sorry, we don't want that byte after all...
                        self.peeked_byte = Some(b);
                        break;
                    },
                    Normal | CompactingLWS if b == SP || b == HT => {
                        // Start or continue to compact linear whitespace
                        CompactingLWS
                    },
                    CompactingLWS => {
                        // End of LWS, compact it down to a single space, unless it's at the start
                        // (saves a trim_left() call later)
                        if self.line_bytes.len() > 0 {
                            self.line_bytes.push(SP);
                        }
                        self.line_bytes.push(b);
                        Normal
                    },
                    Normal => {
                        self.line_bytes.push(b);
                        Normal
                    }
                },
            };
        }
        return Ok((header_name, str::from_bytes(self.line_bytes)));
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////

/// A HTTP request.
///
/// * `host`: The originating IP of the request
/// * `headers`: The headers of the request
/// * `body`: The body of the request as a string
/// * `method`: The method of the request
/// * `path`: The path of the request
/// * `close_connection`: whether the connection should be closed (or kept open waiting for more requests)
/// * `version`: The HTTP version
pub struct Request {
    //host: ip::IpAddr,
    headers: ~Headers,
    body: ~str,
    method: Method,
    path: ~str,
    close_connection: bool,
    version: (uint, uint)
}

/// Parse an HTTP request line into its parts.
///
/// `parse_request_line("GET /foo HTTP/1.1") == Ok((methods::GET, "/foo", (1, 1)))`
fn parse_request_line(line: ~str) -> Option<(Method, ~str, (uint, uint))> {
    // TODO: this probably isn't compliant
    /* * /let words : ~[&str] = line.word_iter().collect();
    if words.len() != 3 {
        return None;
    }
    let method = Method::from_str_or_new(words[0]);
    let path = words[1].to_owned();
    let http_version = parse_http_version(words[2]);
    match http_version {
        None => None,
        Some(v) => Some((method, path, v)),
    }
    /*/
    let mut words = line.word_iter();
    let method = match words.next() {
        Some(s) => Method::from_str_or_new(s),
        None => return None,
    };
    let path = match words.next() {
        Some(s) => s.to_owned(),
        None => return None,
    };
    let http_version = match words.next() {
        Some(s) => parse_http_version(s),
        None => return None,
    };
    match (words.next(), http_version) {
        (None, Some(v)) => Some((method, path, v)),
        _ => None,  // More words or invalid HTTP version
    }
    /**/
}

/// Parse an HTTP version string into the two X.Y parts.
///
/// At present, HTTP versions the server does not know about are rejected.
///
/// ~~~ {.rust}
/// assert_eq!(parse_http_version(~"HTTP/1.0"), Some((1, 0)))
/// assert_eq!(parse_http_version(~"HTTP/1.1"), Some((1, 1)))
/// assert_eq!(parse_http_version(~"HTTP/2.0"), Some((2, 0)))
/// ~~~
fn parse_http_version(version: &str) -> Option<(uint, uint)> {
    match version {
        // These two are efficiency shortcuts; they're expected to be all that we ever receive,
        // but naturally we mustn't let it crash on other inputs.
        "HTTP/1.0" => Some((1, 0)),
        "HTTP/1.1" => Some((1, 1)),
        v if v.starts_with("HTTP/") => {
            // This commented-out variant would fail! if given non-integers
            //let ints: ~[uint] = v.slice_from(5).split_iter('.').map(
            //    |&num| uint::from_str_radix(num, 10).get()).collect();
            let mut ints = [0u, 0u];
            for v.slice_from(5).split_iter('.').enumerate().advance |(i, strnum)| {
                if i > 1 {
                    // More than two numbers, e.g. HTTP/1.2.3
                    return None;
                }
                match uint::from_str_radix(strnum, 10) {
                    Some(num) => ints[i] = num,
                    None => return None,
                }
            }
            Some((ints[0], ints[1]))
        }
        _ => None
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_http_version() {
        assert_eq!(parse_http_version(~"HTTP/1.1"), Ok((1, 1)));
        assert_eq!(parse_http_version(~"HTTP/1.0"), Ok((1, 0)));
        assert_eq!(parse_http_version(~"HTTP/2.0"), Err(()));
    }

    #[test]
    fn test_parse_request_line() {
        assert_eq!(parse_request_line(~"GET /foo HTTP/1.1"), Ok((methods::GET, "/foo", (1, 1))));
        assert_eq!(parse_request_line(~"POST / HTTP/1.0"), Ok((methods::POST, "/", (1, 0))));
        assert_eq!(parse_request_line(~"POST / HTTP/2.0"), Err(()));
    }
}

/**/
impl Request {

    /// Get a response from an open socket.
    pub fn get(buffer: &mut RequestBuffer) -> Result<Request, status::Status> {

        let (method, path, version) = match parse_request_line(buffer.read_crlf_line()) {
            Some(vals) => vals,
            None => return Err(status::BadRequest),
        };

        let close_connection = match version {
            (1, 0) => true,
            (1, 1) => false,
            _ => return Err(status::HttpVersionNotSupported),
        };

        let mut headers = TreeMap::new();

        loop {
            match buffer.read_header_line() {
                Err(EndOfFile) => fail!("client disconnected, nowhere to send response"),
                Err(EndOfHeaders) => break,
                Err(MalformedHeader) => return Err(status::BadRequest),
                Ok((name, value)) => { headers.insert(normalise_header_name(name), value); },
            }
        }

        let close_connection = match headers.find(&~"Connection") {
            Some(s) => match s.to_ascii().to_lower().to_str_ascii() {
                ~"close" => true,
                ~"keep-alive" => false,
                _ => close_connection,
            },
            None => close_connection,
        };

        Ok(Request {
            //host: socket.get_peer_addr(),
            headers: ~headers,
            body: ~"",
            //body: str::connect_slices(lines, "\r\n"),
            method: method,
            path: path.to_owned(),
            close_connection: close_connection,
            version: version
        })
    }
}
/**/

/* What follows is most of Go's net/http module's definition of Request.

pub struct Request {
    // GET, POST, etc.
    method: ~Method,

    // The URL requested, constructed from the request line and (if available)
    // the Host header.
    url: ~Url,

    // The HTTP protocol version used; typically (1, 1)
    protocol: (uint, uint),

    // Request headers, all nicely and correctly parsed.
    headers: ~Headers,

    // The message body.
    body: Reader,

    // ContentLength records the length of the associated content.
    // The value -1 indicates that the length is unknown.
    // Values >= 0 indicate that the given number of bytes may
    // be read from Body.
    // For outgoing requests, a value of 0 means unknown if Body is not nil.
    content_length: i64,

    // TransferEncoding lists the transfer encodings from outermost to
    // innermost. An empty list denotes the "identity" encoding.
    // TransferEncoding can usually be ignored; chunked encoding is
    // automatically added and removed as necessary when sending and
    // receiving requests.
    transfer_encoding: ~[~str],

    // Close indicates whether to close the connection after
    // replying to this request.
    close: bool,

    // The host on which the URL is sought.
    // Per RFC 2616, this is either the value of the Host: header
    // or the host name given in the URL itself.
    // It may be of the form "host:port".
    host: ~str,

    // Form contains the parsed form data, including both the URL
    // field's query parameters and the POST or PUT form data.
    // This field is only available after ParseForm is called.
    // The HTTP client ignores Form and uses Body instead.
    form: url.Values,

    // PostForm contains the parsed form data from POST or PUT
    // body parameters.
    // This field is only available after ParseForm is called.
    // The HTTP client ignores PostForm and uses Body instead.
    post_form: url.Values,

    // MultipartForm is the parsed multipart form, including file uploads.
    // This field is only available after ParseMultipartForm is called.
    // The HTTP client ignores MultipartForm and uses Body instead.
    multipart_form: *multipart.Form,

    // Trailer maps trailer keys to values.  Like for Header, if the
    // response has multiple trailer lines with the same key, they will be
    // concatenated, delimited by commas.
    // For server requests, Trailer is only populated after Body has been
    // closed or fully consumed.
    // Trailer support is only partially complete.
    trailer: ~Headers,

    // RemoteAddr allows HTTP servers and other software to record
    // the network address that sent the request, usually for
    // logging. This field is not filled in by ReadRequest and
    // has no defined format. The HTTP server in this package
    // sets RemoteAddr to an "IP:port" address before invoking a
    // handler.
    // This field is ignored by the HTTP client.
    remote_addr: string,

    // RequestURI is the unmodified Request-URI of the
    // Request-Line (RFC 2616, Section 5.1) as sent by the client
    // to a server. Usually the URL field should be used instead.
    // It is an error to set this field in an HTTP client request.
    request_uri: string,

    // TLS allows HTTP servers and other software to record
    // information about the TLS connection on which the request
    // was received. This field is not filled in by ReadRequest.
    // The HTTP server in this package sets the field for
    // TLS-enabled connections before invoking a handler;
    // otherwise it leaves the field nil.
    // This field is ignored by the HTTP client.
    tls: *tls.ConnectionState,
}*/
<|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0533: r##"
The export_name attribute was badly formatted.

Erroneous code example:

```compile_fail,E0533
#[export_name] // error: export_name attribute has invalid format
pub fn something() {}

fn main() {}
```

The export_name attribute expects a string in order to determine the name of
the exported symbol. Example:

```
#[export_name = "some function"] // ok!
pub fn something() {}

fn main() {}
```
"##,

E0534: r##"
The inline attribute was badly used.

Erroneous code example:

```compile_fail,E0534
#[inline()] // error: expected one argument
pub fn something() {}

fn main() {}
```

The inline attribute can be used without arguments:

```
#[inline] // ok!
pub fn something() {}

fn main() {}
```

Or with arguments (and parens have to be used for this case!):

```
#[inline(always)] // ok!
pub fn something() {}

fn main() {}
```

For more information about the inline attribute, take a look here:
https://doc.rust-lang.org/reference.html#inline-attributes)
"##,

E0535: r##"
An unknown argument was given to inline attribute.

Erroneous code example:

```compile_fail,E0535
#[inline(unknown)] // error: invalid argument
pub fn something() {}

fn main() {}
```

The inline attribute only knows two arguments:

 * always
 * never

All other arguments given to the inline attribute will return this error.
Example:

```
#[inline(never)] // ok!
pub fn something() {}

fn main() {}
```

For more information about the inline attribute, take a look here:
https://doc.rust-lang.org/reference.html#inline-attributes)
"##,

}

register_diagnostics! {
    E0536, // expected 1 cfg-pattern
    E0537, // invalid predicate
    E0538, // multiple [same] items
    E0539, // incorrect meta item
    E0540, // multiple rustc_deprecated attributes
    E0541, // unknown meta item
    E0542, // missing 'since'
    E0543, // missing 'reason'
    E0544, // multiple stability levels
    E0545, // incorrect 'issue'
    E0546, // missing 'feature'
    E0547, // missing 'issue'
    E0548, // incorrect stability attribute type
    E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
    E0550, // multiple deprecated attributes
    E0551, // incorrect meta item
    E0552, // unrecognized representation hint
    E0553, // unrecognized enum representation hint
    E0554, // #[feature] may not be used on the [] release channel
    E0555, // malformed feature attribute, expected #![feature(...)]
    E0556, // malformed feature, expected just one word
    E0557, // feature has been removed
}
<commit_msg>Add E0536 error explanation<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0533: r##"
The export_name attribute was badly formatted.

Erroneous code example:

```compile_fail,E0533
#[export_name] // error: export_name attribute has invalid format
pub fn something() {}

fn main() {}
```

The export_name attribute expects a string in order to determine the name of
the exported symbol. Example:

```
#[export_name = "some function"] // ok!
pub fn something() {}

fn main() {}
```
"##,

E0534: r##"
The inline attribute was badly used.

Erroneous code example:

```compile_fail,E0534
#[inline()] // error: expected one argument
pub fn something() {}

fn main() {}
```

The inline attribute can be used without arguments:

```
#[inline] // ok!
pub fn something() {}

fn main() {}
```

Or with arguments (and parens have to be used for this case!):

```
#[inline(always)] // ok!
pub fn something() {}

fn main() {}
```

For more information about the inline attribute, take a look here:
https://doc.rust-lang.org/reference.html#inline-attributes
"##,

E0535: r##"
An unknown argument was given to inline attribute.

Erroneous code example:

```compile_fail,E0535
#[inline(unknown)] // error: invalid argument
pub fn something() {}

fn main() {}
```

The inline attribute only knows two arguments:

 * always
 * never

All other arguments given to the inline attribute will return this error.
Example:

```
#[inline(never)] // ok!
pub fn something() {}

fn main() {}
```

For more information about the inline attribute, take a look here:
https://doc.rust-lang.org/reference.html#inline-attributes
"##,

E0536: r##"
No cfg-pattern was found for `not` statement.

Erroneous code example:

```compile_fail,E0536
#[cfg(not())] // error: expected 1 cfg-pattern
pub fn something() {}

pub fn main() {}
```

The `not` statement expects at least one cfg-pattern. Example:

```
#[cfg(not(target_os = "linux"))] // ok!
pub fn something() {}

pub fn main() {}
```

For more information about the cfg attribute, take a look here:
https://doc.rust-lang.org/reference.html#conditional-compilation
"##,

}

register_diagnostics! {
    E0537, // invalid predicate
    E0538, // multiple [same] items
    E0539, // incorrect meta item
    E0540, // multiple rustc_deprecated attributes
    E0541, // unknown meta item
    E0542, // missing 'since'
    E0543, // missing 'reason'
    E0544, // multiple stability levels
    E0545, // incorrect 'issue'
    E0546, // missing 'feature'
    E0547, // missing 'issue'
    E0548, // incorrect stability attribute type
    E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
    E0550, // multiple deprecated attributes
    E0551, // incorrect meta item
    E0552, // unrecognized representation hint
    E0553, // unrecognized enum representation hint
    E0554, // #[feature] may not be used on the [] release channel
    E0555, // malformed feature attribute, expected #![feature(...)]
    E0556, // malformed feature, expected just one word
    E0557, // feature has been removed
}
<|endoftext|>


<commit_before>use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead};
use std::str::FromStr;

#[macro_use]
extern crate lazy_static;
extern crate if_chain;

struct State<'a, T>(Box<dyn 'a + Iterator<Item = T>>, Option<T>);

pub struct Merge<'a, T> {
    count: usize,
    states: Vec<State<'a, T>>,
}

impl<'a, T: 'a + FromStr> Merge<'a, T> {
    pub fn new(filename: &str) -> Self {
        let count = get_number(filename).unwrap();
        let states = (0..count)
            .map(|i| {
                let collection = Box::new(get_collection(filename, i).unwrap());
                State(collection, None)
            })
            .collect();
        Merge {
            count: count,
            states: states,
        }
    }
}

impl<'a, T: PartialOrd> Iterator for Merge<'a, T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let count = self.count;
        let states = &mut self.states;
        for i in 0..count {
            let state = &mut states[i];
            if state.1.is_none() {
                state.1 = state.0.next();
            }
        }
        let mut min_index: Option<usize> = None;
        for i in 0..count {
            if_chain::if_chain! {
                if let Some(_) = states[i].1.as_ref();
                if min_index.is_none();
                then {
                    min_index.replace(i);
                }
            }
            if_chain::if_chain! {
                if let Some(val) = states[i].1.as_ref();
                if let Some(m) = min_index;
                if let Some(min) = states[m].1.as_ref();
                if val < min;
                then {
                    min_index.replace(i);
                }
            }
        }
        if let Some(m) = min_index {
            return states[m].1.take();
        }
        return None;
    }
}

pub fn get_number(filename: &str) -> io::Result<usize> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    if_chain::if_chain! {
        if let Some(m) = matches.next();
        if let Ok(number) = m.parse();
        then {
            Ok(number)
        }
        else {
            Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
        }
    }
}

pub fn get_output<T: FromStr>(filename: &str) -> io::Result<impl Iterator<Item = T>> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    get_numbers(filename, &*RE)
}

pub fn get_collection<T: FromStr>(
    filename: &str,
    idx: usize,
) -> io::Result<impl Iterator<Item = T>> {
    let regex: Regex = {
        let r = format!("COLLECTION{}:(.*)", idx);
        Regex::new(&r).unwrap()
    };
    get_numbers(filename, &regex)
}

fn get_numbers<T: FromStr>(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = T>> {
    let matches = match_lines(filename, regex)?;
    let to_int = |v: &str| -> Option<T> {
        if let Ok(i) = v.parse::<T>() {
            Some(i)
        } else {
            None
        }
    };
    let values = matches
        .map(move |s| {
            let numbers = s.split(',').filter_map(|v| to_int(&v));
            numbers.collect::<Vec<_>>()
        })
        .flatten();
    Ok(values)
}

fn match_lines(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = String>> {
    let read_lines = move || -> io::Result<_> {
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines().map(|line| line.unwrap()))
    };
    let lines = read_lines()?;
    let r = regex.clone(); // TODO
    let matches =
        lines.filter_map(move |line| r.captures(&line).map(|captures| captures[1].to_string()));
    Ok(matches)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap(), 3);
    }

    #[test]
    fn test_output() {
        let output = [1, 1, 2, 2, 3, 4, 4, 6, 7, 9, 9, 20, 21];
        assert_eq!(
            get_output("../data/test.txt")
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    #[test]
    fn test_collection() {
        let output = [2, 4, 6, 9, 20];
        assert_eq!(
            get_collection("../data/test.txt", 1)
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    fn merge<'a, T: 'a + FromStr + PartialOrd>(
        filename: &str,
    ) -> (impl 'a + Iterator<Item = T>, impl Iterator<Item = T>) {
        let result = Merge::new(filename);
        let output = get_output(filename).unwrap();
        (result, output)
    }

    fn assert_iterator<T: PartialEq>(
        iter1: &mut impl Iterator<Item = T>,
        iter2: &mut impl Iterator<Item = T>,
    ) -> bool {
        loop {
            match (iter1.next(), iter2.next()) {
                (None, None) => return true,
                (Some(v1), Some(v2)) if v1 == v2 => continue,
                _ => return false,
            }
        }
    }

    #[test]
    fn test_merge() {
        let filename = "../data/test.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(assert_iterator(&mut result, &mut output));
    }

    #[test]
    #[should_panic]
    fn test_bad_merge() {
        let filename = "../data/bad.txt";
        let (_result, _output) = merge::<u32>(filename);
    }

    #[test]
    fn test_zero_merge() {
        let filename = "../data/zero.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(result.next().is_none());
        assert!(output.next().is_none());
    }

    #[test]
    fn test_err() {
        let filename = "../data/err.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(!assert_iterator(&mut result, &mut output));
    }
}
<commit_msg>test for assert<commit_after>use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead};
use std::str::FromStr;

#[macro_use]
extern crate lazy_static;
extern crate if_chain;

struct State<'a, T>(Box<dyn 'a + Iterator<Item = T>>, Option<T>);

pub struct Merge<'a, T> {
    count: usize,
    states: Vec<State<'a, T>>,
}

impl<'a, T: 'a + FromStr> Merge<'a, T> {
    pub fn new(filename: &str) -> Self {
        let count = get_number(filename).unwrap();
        let states = (0..count)
            .map(|i| {
                let collection = Box::new(get_collection(filename, i).unwrap());
                State(collection, None)
            })
            .collect();
        Merge {
            count: count,
            states: states,
        }
    }
}

impl<'a, T: PartialOrd> Iterator for Merge<'a, T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let count = self.count;
        let states = &mut self.states;
        for i in 0..count {
            let state = &mut states[i];
            if state.1.is_none() {
                state.1 = state.0.next();
            }
        }
        let mut min_index: Option<usize> = None;
        for i in 0..count {
            if_chain::if_chain! {
                if let Some(_) = states[i].1.as_ref();
                if min_index.is_none();
                then {
                    min_index.replace(i);
                }
            }
            if_chain::if_chain! {
                if let Some(val) = states[i].1.as_ref();
                if let Some(m) = min_index;
                if let Some(min) = states[m].1.as_ref();
                if val < min;
                then {
                    min_index.replace(i);
                }
            }
        }
        if let Some(m) = min_index {
            return states[m].1.take();
        }
        return None;
    }
}

pub fn get_number(filename: &str) -> io::Result<usize> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    if_chain::if_chain! {
        if let Some(m) = matches.next();
        if let Ok(number) = m.parse();
        then {
            Ok(number)
        }
        else {
            Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
        }
    }
}

pub fn get_output<T: FromStr>(filename: &str) -> io::Result<impl Iterator<Item = T>> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    get_numbers(filename, &*RE)
}

pub fn get_collection<T: FromStr>(
    filename: &str,
    idx: usize,
) -> io::Result<impl Iterator<Item = T>> {
    let regex: Regex = {
        let r = format!("COLLECTION{}:(.*)", idx);
        Regex::new(&r).unwrap()
    };
    get_numbers(filename, &regex)
}

fn get_numbers<T: FromStr>(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = T>> {
    let matches = match_lines(filename, regex)?;
    let to_int = |v: &str| -> Option<T> {
        if let Ok(i) = v.parse::<T>() {
            Some(i)
        } else {
            None
        }
    };
    let values = matches
        .map(move |s| {
            let numbers = s.split(',').filter_map(|v| to_int(&v));
            numbers.collect::<Vec<_>>()
        })
        .flatten();
    Ok(values)
}

fn match_lines(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = String>> {
    let read_lines = move || -> io::Result<_> {
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines().map(|line| line.unwrap()))
    };
    let lines = read_lines()?;
    let r = regex.clone(); // TODO
    let matches =
        lines.filter_map(move |line| r.captures(&line).map(|captures| captures[1].to_string()));
    Ok(matches)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap(), 3);
    }

    #[test]
    fn test_output() {
        let output = [1, 1, 2, 2, 3, 4, 4, 6, 7, 9, 9, 20, 21];
        assert_eq!(
            get_output("../data/test.txt")
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    #[test]
    fn test_collection() {
        let output = [2, 4, 6, 9, 20];
        assert_eq!(
            get_collection("../data/test.txt", 1)
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    fn merge<'a, T: 'a + FromStr + PartialOrd>(
        filename: &str,
    ) -> (impl 'a + Iterator<Item = T>, impl Iterator<Item = T>) {
        let result = Merge::new(filename);
        let output = get_output(filename).unwrap();
        (result, output)
    }

    fn assert_iterator<T: PartialEq>(
        iter1: &mut impl Iterator<Item = T>,
        iter2: &mut impl Iterator<Item = T>,
    ) -> bool {
        loop {
            match (iter1.next(), iter2.next()) {
                (None, None) => return true,
                (Some(v1), Some(v2)) if v1 == v2 => continue,
                _ => return false,
            }
        }
    }

    #[test]
    fn test_assert_iterator() {
        // TODO  let mut result = (0..3).into_iter().cloned();
        let mut result = [0, 1, 2].iter().cloned();
        let mut output = [0, 1, 2].iter().cloned();
        assert!(assert_iterator(&mut result, &mut output));
        let mut result = [1].iter().cloned();
        let mut output = [0, 1, 2].iter().cloned();
        assert!(!assert_iterator(&mut result, &mut output));
    }

    #[test]
    fn test_merge() {
        let filename = "../data/test.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(assert_iterator(&mut result, &mut output));
    }

    #[test]
    #[should_panic]
    fn test_bad_merge() {
        let filename = "../data/bad.txt";
        let (_result, _output) = merge::<u32>(filename);
    }

    #[test]
    fn test_zero_merge() {
        let filename = "../data/zero.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(result.next().is_none());
        assert!(output.next().is_none());
    }

    #[test]
    fn test_err() {
        let filename = "../data/err.txt";
        let (mut result, mut output) = merge::<u32>(filename);
        assert!(!assert_iterator(&mut result, &mut output));
    }
}
<|endoftext|>


<commit_before>//! Allocator shim
// Adapted from rustc

use crate::prelude::*;

use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
use rustc_span::symbol::sym;

/// Returns whether an allocator shim was created
pub(crate) fn codegen(
    tcx: TyCtxt<'_>,
    module: &mut impl Module,
    unwind_context: &mut UnwindContext,
) -> bool {
    let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| {
        use rustc_middle::middle::dependency_format::Linkage;
        list.iter().any(|&linkage| linkage == Linkage::Dynamic)
    });
    if any_dynamic_crate {
        false
    } else if let Some(kind) = tcx.allocator_kind(()) {
        codegen_inner(module, unwind_context, kind);
        true
    } else {
        false
    }
}

fn codegen_inner(
    module: &mut impl Module,
    unwind_context: &mut UnwindContext,
    kind: AllocatorKind,
) {
    let usize_ty = module.target_config().pointer_type();

    for method in ALLOCATOR_METHODS {
        let mut arg_tys = Vec::with_capacity(method.inputs.len());
        for ty in method.inputs.iter() {
            match *ty {
                AllocatorTy::Layout => {
                    arg_tys.push(usize_ty); // size
                    arg_tys.push(usize_ty); // align
                }
                AllocatorTy::Ptr => arg_tys.push(usize_ty),
                AllocatorTy::Usize => arg_tys.push(usize_ty),

                AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
            }
        }
        let output = match method.output {
            AllocatorTy::ResultPtr => Some(usize_ty),
            AllocatorTy::Unit => None,

            AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
                panic!("invalid allocator output")
            }
        };

        let sig = Signature {
            call_conv: CallConv::triple_default(module.isa().triple()),
            params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
            returns: output.into_iter().map(AbiParam::new).collect(),
        };

        let caller_name = format!("__rust_{}", method.name);
        let callee_name = kind.fn_name(method.name);
        //eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);

        let func_id = module.declare_function(&caller_name, Linkage::Export, &sig).unwrap();

        let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();

        let mut ctx = Context::new();
        ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone());
        {
            let mut func_ctx = FunctionBuilderContext::new();
            let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

            let block = bcx.create_block();
            bcx.switch_to_block(block);
            let args = arg_tys
                .into_iter()
                .map(|ty| bcx.append_block_param(block, ty))
                .collect::<Vec<Value>>();

            let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func);
            let call_inst = bcx.ins().call(callee_func_ref, &args);
            let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error

            bcx.ins().return_(&results);
            bcx.seal_all_blocks();
            bcx.finalize();
        }
        module
            .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {})
            .unwrap();
        unwind_context.add_function(func_id, &ctx, module.isa());
    }

    let sig = Signature {
        call_conv: CallConv::triple_default(module.isa().triple()),
        params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
        returns: vec![],
    };

    let callee_name = kind.fn_name(sym::oom);
    //eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);

    let func_id =
        module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap();

    let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();

    let mut ctx = Context::new();
    ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig);
    {
        let mut func_ctx = FunctionBuilderContext::new();
        let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

        let block = bcx.create_block();
        bcx.switch_to_block(block);
        let args = (&[usize_ty, usize_ty])
            .iter()
            .map(|&ty| bcx.append_block_param(block, ty))
            .collect::<Vec<Value>>();

        let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func);
        bcx.ins().call(callee_func_ref, &args);

        bcx.ins().trap(TrapCode::UnreachableCodeReached);
        bcx.seal_all_blocks();
        bcx.finalize();
    }
    module
        .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {})
        .unwrap();
    unwind_context.add_function(func_id, &ctx, module.isa());
}
<commit_msg>Implement "default_alloc_error_handler" feature<commit_after>//! Allocator shim
// Adapted from rustc

use crate::prelude::*;

use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};

/// Returns whether an allocator shim was created
pub(crate) fn codegen(
    tcx: TyCtxt<'_>,
    module: &mut impl Module,
    unwind_context: &mut UnwindContext,
) -> bool {
    let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| {
        use rustc_middle::middle::dependency_format::Linkage;
        list.iter().any(|&linkage| linkage == Linkage::Dynamic)
    });
    if any_dynamic_crate {
        false
    } else if let Some(kind) = tcx.allocator_kind(()) {
        codegen_inner(module, unwind_context, kind, tcx.lang_items().oom().is_some());
        true
    } else {
        false
    }
}

fn codegen_inner(
    module: &mut impl Module,
    unwind_context: &mut UnwindContext,
    kind: AllocatorKind,
    has_alloc_error_handler: bool,
) {
    let usize_ty = module.target_config().pointer_type();

    for method in ALLOCATOR_METHODS {
        let mut arg_tys = Vec::with_capacity(method.inputs.len());
        for ty in method.inputs.iter() {
            match *ty {
                AllocatorTy::Layout => {
                    arg_tys.push(usize_ty); // size
                    arg_tys.push(usize_ty); // align
                }
                AllocatorTy::Ptr => arg_tys.push(usize_ty),
                AllocatorTy::Usize => arg_tys.push(usize_ty),

                AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
            }
        }
        let output = match method.output {
            AllocatorTy::ResultPtr => Some(usize_ty),
            AllocatorTy::Unit => None,

            AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
                panic!("invalid allocator output")
            }
        };

        let sig = Signature {
            call_conv: CallConv::triple_default(module.isa().triple()),
            params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
            returns: output.into_iter().map(AbiParam::new).collect(),
        };

        let caller_name = format!("__rust_{}", method.name);
        let callee_name = kind.fn_name(method.name);

        let func_id = module.declare_function(&caller_name, Linkage::Export, &sig).unwrap();

        let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();

        let mut ctx = Context::new();
        ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone());
        {
            let mut func_ctx = FunctionBuilderContext::new();
            let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

            let block = bcx.create_block();
            bcx.switch_to_block(block);
            let args = arg_tys
                .into_iter()
                .map(|ty| bcx.append_block_param(block, ty))
                .collect::<Vec<Value>>();

            let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func);
            let call_inst = bcx.ins().call(callee_func_ref, &args);
            let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error

            bcx.ins().return_(&results);
            bcx.seal_all_blocks();
            bcx.finalize();
        }
        module
            .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {})
            .unwrap();
        unwind_context.add_function(func_id, &ctx, module.isa());
    }

    let sig = Signature {
        call_conv: CallConv::triple_default(module.isa().triple()),
        params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
        returns: vec![],
    };

    let callee_name = if has_alloc_error_handler { "__rg_oom" } else { "__rdl_oom" };

    let func_id =
        module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap();

    let callee_func_id = module.declare_function(callee_name, Linkage::Import, &sig).unwrap();

    let mut ctx = Context::new();
    ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig);
    {
        let mut func_ctx = FunctionBuilderContext::new();
        let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

        let block = bcx.create_block();
        bcx.switch_to_block(block);
        let args = (&[usize_ty, usize_ty])
            .iter()
            .map(|&ty| bcx.append_block_param(block, ty))
            .collect::<Vec<Value>>();

        let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func);
        bcx.ins().call(callee_func_ref, &args);

        bcx.ins().trap(TrapCode::UnreachableCodeReached);
        bcx.seal_all_blocks();
        bcx.finalize();
    }
    module
        .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {})
        .unwrap();
    unwind_context.add_function(func_id, &ctx, module.isa());
}
<|endoftext|>


<commit_before>use super::{ApiLinks, ApiMeta};
use super::{HasPagination, HasResponse, HasValue};
use chrono::{DateTime, Utc};
use method::{Delete, Get, List, Update};
use request::ImageRequest;
use request::Request;
use serde::Serialize;
use std::fmt::Display;
use url::Url;
use {ROOT_URL, STATIC_URL_ERROR};

const IMAGES_SEGMENT: &'static str = "images";

/// Images in DigitalOcean may refer to one of a few different kinds of objects.
///
/// An image may refer to a snapshot that has been taken of a Droplet instance.
/// It may also mean an image representing an automatic backup of a Droplet.
/// The third category that it can represent is a public Linux distribution or
/// application image that is used as a base to create Droplets.
///
/// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#domains)
#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
pub struct Image {
    /// A unique number that can be used to identify and reference a specific
    /// image.
    #[get = "pub"]
    id: usize,
    /// The display name that has been given to an image. This is what is shown
    /// in the control panel and is generally a descriptive title for the image
    /// in question.
    #[get = "pub"]
    name: String,
    /// The kind of image, describing the duration of how long the image is
    /// stored. This is either "snapshot" or "backup".
    ///
    /// *Note:* Since `type` is a keyword in Rust `kind` is used instead.
    #[serde(rename = "type")]
    #[get = "pub"]
    kind: String, // 'type' is reserved in Rust.
    /// This attribute describes the base distribution used for this image.
    #[get = "pub"]
    distribution: String,
    /// A uniquely identifying string that is associated with each of the
    /// DigitalOcean-provided public images. These can be used to reference
    /// a public image as an alternative to the numeric id.
    #[get = "pub"]
    slug: Option<String>,
    /// This is a boolean value that indicates whether the image in question
    /// is public or not. An image that is public is available to all accounts.
    /// A non-public image is only accessible from your account.
    #[get = "pub"]
    public: bool,
    /// This attribute is an array of the regions that the image is available
    /// in. The regions are represented by their identifying slug values.
    #[get = "pub"]
    regions: Vec<String>,
    /// The minimum 'disk' required for a size to use this image.
    #[get = "pub"]
    min_disk_size: usize,
    /// The size of the image in gigabytes.
    #[get = "pub"]
    size_gigabytes: Option<f32>,
    /// A time value given in ISO8601 combined date and time format that
    /// represents when the Image was created.
    #[get = "pub"]
    created_at: DateTime<Utc>,
}

impl Image {
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-images)
    pub fn list() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        Request::new(url)
    }

    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-distribution-images)
    pub fn distributions() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        url.query_pairs_mut().append_pair("type", "distribution");

        Request::new(url)
    }

    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-application-images)
    pub fn applications() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        url.query_pairs_mut().append_pair("type", "application");

        Request::new(url)
    }

    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-a-user-s-images)
    pub fn user() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        url.query_pairs_mut().append_pair("private", "true");

        Request::new(url)
    }

    /// `id` is either an `id` (numeric) or a `slug` (string).
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-image-by-id)
    pub fn get<S>(id: S) -> ImageRequest<Get, Image>
    where
        S: Display,
    {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT)
            .push(&format!("{}", id));

        Request::new(url)
    }

    /// `id` is either an `id` (numeric) or a `slug` (string).
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#update-an-image)
    pub fn update<S>(id: S) -> ImageRequest<Update, Image>
    where
        S: Display,
    {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT)
            .push(&format!("{}", id));

        Request::new(url)
    }

    /// `id` is either an `id` (numeric) or a `slug` (string).
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#delete-an-image)
    pub fn delete<S>(id: S) -> ImageRequest<Delete, ()>
    where
        S: Display,
    {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT)
            .push(&format!("{}", id));

        Request::new(url)
    }

}

impl ImageRequest<Update, Image> {
    /// The new name that you would like to use for the image.
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#images)
    pub fn name<S>(mut self, val: S) -> ImageRequest<Update, Image>
    where
        S: Display + Serialize,
    {
        self.body_mut()["name"] = json!(val);
        self
    }
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ImageResponse {
    image: Image,
}

impl HasResponse for Image {
    type Response = ImageResponse;
}

impl HasValue for ImageResponse {
    type Value = Image;
    fn value(self) -> Image {
        self.image
    }
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ImageListResponse {
    images: Vec<Image>,
    links: ApiLinks,
    meta: ApiMeta,
}

impl HasResponse for Vec<Image> {
    type Response = ImageListResponse;
}

impl HasPagination for ImageListResponse {
    fn next_page(&self) -> Option<Url> {
        self.links.next()
    }
}

impl HasValue for ImageListResponse {
    type Value = Vec<Image>;
    fn value(self) -> Vec<Image> {
        self.images
    }
}
<commit_msg>Remove newline from api/image.rs<commit_after>use super::{ApiLinks, ApiMeta};
use super::{HasPagination, HasResponse, HasValue};
use chrono::{DateTime, Utc};
use method::{Delete, Get, List, Update};
use request::ImageRequest;
use request::Request;
use serde::Serialize;
use std::fmt::Display;
use url::Url;
use {ROOT_URL, STATIC_URL_ERROR};

const IMAGES_SEGMENT: &'static str = "images";

/// Images in DigitalOcean may refer to one of a few different kinds of objects.
///
/// An image may refer to a snapshot that has been taken of a Droplet instance.
/// It may also mean an image representing an automatic backup of a Droplet.
/// The third category that it can represent is a public Linux distribution or
/// application image that is used as a base to create Droplets.
///
/// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#domains)
#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
pub struct Image {
    /// A unique number that can be used to identify and reference a specific
    /// image.
    #[get = "pub"]
    id: usize,
    /// The display name that has been given to an image. This is what is shown
    /// in the control panel and is generally a descriptive title for the image
    /// in question.
    #[get = "pub"]
    name: String,
    /// The kind of image, describing the duration of how long the image is
    /// stored. This is either "snapshot" or "backup".
    ///
    /// *Note:* Since `type` is a keyword in Rust `kind` is used instead.
    #[serde(rename = "type")]
    #[get = "pub"]
    kind: String, // 'type' is reserved in Rust.
    /// This attribute describes the base distribution used for this image.
    #[get = "pub"]
    distribution: String,
    /// A uniquely identifying string that is associated with each of the
    /// DigitalOcean-provided public images. These can be used to reference
    /// a public image as an alternative to the numeric id.
    #[get = "pub"]
    slug: Option<String>,
    /// This is a boolean value that indicates whether the image in question
    /// is public or not. An image that is public is available to all accounts.
    /// A non-public image is only accessible from your account.
    #[get = "pub"]
    public: bool,
    /// This attribute is an array of the regions that the image is available
    /// in. The regions are represented by their identifying slug values.
    #[get = "pub"]
    regions: Vec<String>,
    /// The minimum 'disk' required for a size to use this image.
    #[get = "pub"]
    min_disk_size: usize,
    /// The size of the image in gigabytes.
    #[get = "pub"]
    size_gigabytes: Option<f32>,
    /// A time value given in ISO8601 combined date and time format that
    /// represents when the Image was created.
    #[get = "pub"]
    created_at: DateTime<Utc>,
}

impl Image {
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-images)
    pub fn list() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        Request::new(url)
    }

    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-distribution-images)
    pub fn distributions() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        url.query_pairs_mut().append_pair("type", "distribution");

        Request::new(url)
    }

    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-application-images)
    pub fn applications() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        url.query_pairs_mut().append_pair("type", "application");

        Request::new(url)
    }

    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-a-user-s-images)
    pub fn user() -> ImageRequest<List, Vec<Image>> {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT);

        url.query_pairs_mut().append_pair("private", "true");

        Request::new(url)
    }

    /// `id` is either an `id` (numeric) or a `slug` (string).
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-image-by-id)
    pub fn get<S>(id: S) -> ImageRequest<Get, Image>
    where
        S: Display,
    {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT)
            .push(&format!("{}", id));

        Request::new(url)
    }

    /// `id` is either an `id` (numeric) or a `slug` (string).
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#update-an-image)
    pub fn update<S>(id: S) -> ImageRequest<Update, Image>
    where
        S: Display,
    {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT)
            .push(&format!("{}", id));

        Request::new(url)
    }

    /// `id` is either an `id` (numeric) or a `slug` (string).
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#delete-an-image)
    pub fn delete<S>(id: S) -> ImageRequest<Delete, ()>
    where
        S: Display,
    {
        let mut url = ROOT_URL.clone();
        url.path_segments_mut()
            .expect(STATIC_URL_ERROR)
            .push(IMAGES_SEGMENT)
            .push(&format!("{}", id));

        Request::new(url)
    }
}

impl ImageRequest<Update, Image> {
    /// The new name that you would like to use for the image.
    ///
    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#images)
    pub fn name<S>(mut self, val: S) -> ImageRequest<Update, Image>
    where
        S: Display + Serialize,
    {
        self.body_mut()["name"] = json!(val);
        self
    }
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ImageResponse {
    image: Image,
}

impl HasResponse for Image {
    type Response = ImageResponse;
}

impl HasValue for ImageResponse {
    type Value = Image;
    fn value(self) -> Image {
        self.image
    }
}

/// Response type returned from Digital Ocean.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ImageListResponse {
    images: Vec<Image>,
    links: ApiLinks,
    meta: ApiMeta,
}

impl HasResponse for Vec<Image> {
    type Response = ImageListResponse;
}

impl HasPagination for ImageListResponse {
    fn next_page(&self) -> Option<Url> {
        self.links.next()
    }
}

impl HasValue for ImageListResponse {
    type Value = Vec<Image>;
    fn value(self) -> Vec<Image> {
        self.images
    }
}
<|endoftext|>


<commit_before>extern crate doubly;

use doubly::DoublyLinkedList;

fn main() {
    test_len();
}

fn test_len() {
    let mut nums = DoublyLinkedList::new_singleton(4i32);

    for x in 0..100 { nums.push_front(x); }
    for x in 0..100 { nums.push_back(x); }

    //nums.insert(40,8);

    println!("LENGTH: {}", nums.len());

    nums.insert(196,56);

    //assert_eq!(nums.len(), 202);
}
<commit_msg>stop building a binary<commit_after><|endoftext|>


<commit_before>#![deny(warnings)]

extern crate extra;

use std::env;
use std::fs;
use std::io::{stdout, stderr, Write};
use extra::io::fail;
use extra::option::OptionalExt;

const MAN_PAGE: &'static str = /* @MANSTART{mkdir} */ r#"
NAME
    mkdir - make directories

SYNOPSIS
    mkdir DIRECTORIES...

DESCRIPTION
    The mkdir utility creates the directories named as operands.
"#; /* @MANEND */

fn main() {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let mut stderr = stderr();

    if env::args().count() < 2 {
        fail("No arguments. Use --help to see the usage.", &mut stderr);
    }

    if env::args().count() == 2 {
        if let Some(arg) = env::args().last() {
            if arg == "--help" {
                stdout.write_all(MAN_PAGE.as_bytes()).try(&mut stderr);
                stdout.flush().try(&mut stderr);
                return;
            }
        }
    }

    for ref path in env::args().skip(1) {
        fs::create_dir(path).try(&mut stderr);
    }
}
<commit_msg>Add --help to mkdir's MANPAGE options section. Slightly improved checking if --help option was passed.<commit_after>#![deny(warnings)]

extern crate extra;

use std::env;
use std::fs;
use std::io::{stdout, stderr, Write};
use extra::io::fail;
use extra::option::OptionalExt;

const MAN_PAGE: &'static str = /* @MANSTART{mkdir} */ r#"
NAME
    mkdir - make directories

SYNOPSIS
    mkdir DIRECTORIES...

DESCRIPTION
    The mkdir utility creates the directories named as operands.

OPTIONS
    --help
        print this message
"#; /* @MANEND */

fn main() {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let mut stderr = stderr();

    if env::args().count() < 2 {
        fail("No arguments. Use --help to see the usage.", &mut stderr);
    }

    if env::args().count() == 2 {
        if let Some(arg) = env::args().nth(1) {
            if arg == "--help" {
                stdout.write_all(MAN_PAGE.as_bytes()).try(&mut stderr);
                stdout.flush().try(&mut stderr);
                return;
            }
        }
    }

    for ref path in env::args().skip(1) {
        fs::create_dir(path).try(&mut stderr);
    }
}
<|endoftext|>