on my way to get rid of C IO

master
Lukáš Hozda 4 years ago
parent d3e9a6788b
commit c145d691d0

@ -22,7 +22,7 @@ use std::time::Duration;
use std::ffi::{CStr, CString};
use std::fs::{self, File};
use std::mem;
use std::io::{Write};
use std::io::{Write, BufReader, BufRead};
use simple_input::input;
use tempfile::NamedTempFile;
@ -249,7 +249,7 @@ pub struct BrowserState {
pub parsed_host: String,
pub parsed_port: usize,
pub parsed_selector: String,
pub bookmarks: [[u8; 512]; 20],
pub bookmarks: Vec<String>,
pub config: Config,
}
@ -266,7 +266,7 @@ impl BrowserState {
parsed_host: String::new(),
parsed_port: 0,
parsed_selector: String::new(),
bookmarks: [[0; 512]; 20],
bookmarks: Vec::new(),
config: Config {
start_uri: String::from("gopher://gopher.floodgap.com:70"),
cmd_text: String::from("less"),
@ -280,198 +280,45 @@ impl BrowserState {
}
}
unsafe fn parse_config_line(&mut self, mut line: *const libc::c_char) {
let mut token: [libc::c_char; 1024] = [0; 1024];
let mut bkey: [libc::c_char; 128] = [0; 128];
let mut value: *mut libc::c_char = 0 as *mut libc::c_char;
let mut i: libc::c_int = 0;
let mut j: libc::c_int = 0;
while *line as libc::c_int == ' ' as i32 || *line as libc::c_int == '\t' as i32 {
line = line.offset(1)
}
i = 0 as libc::c_int;
while *line as libc::c_int != 0
&& *line as libc::c_int != ' ' as i32
&& *line as libc::c_int != '\t' as i32
{
if (i as libc::c_ulong)
< (mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong)
.wrapping_sub(1 as libc::c_int as libc::c_ulong)
{
let fresh0 = i;
i = i + 1;
token[fresh0 as usize] = *line
}
line = line.offset(1)
}
token[i as usize] = 0 as libc::c_int as libc::c_char;
if strcmp(
token.as_mut_ptr(),
b"start_uri\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.start_uri.clone()).unwrap().into_raw();
} else if strcmp(
token.as_mut_ptr(),
b"cmd_text\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.cmd_text.clone()).unwrap().into_raw();
} else if strcmp(
token.as_mut_ptr(),
b"cmd_browser\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.cmd_browser.clone()).unwrap().into_raw();
} else if strcmp(
token.as_mut_ptr(),
b"cmd_image\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.cmd_image.clone()).unwrap().into_raw();
} else if strcmp(
token.as_mut_ptr(),
b"cmd_player\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.cmd_player.clone()).unwrap().into_raw();
} else if strcmp(
token.as_mut_ptr(),
b"color_prompt\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.color_prompt.clone()).unwrap().into_raw();
} else if strcmp(
token.as_mut_ptr(),
b"color_selector\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.color_selector.clone()).unwrap().into_raw();
} else if strcmp(
token.as_mut_ptr(),
b"verbose\x00" as *const u8 as *const libc::c_char,
) == 0
{
value = CString::new(self.config.verbose.clone()).unwrap().into_raw();
} else {
j = 0 as libc::c_int;
while j < 20 as libc::c_int {
snprintf(
bkey.as_mut_ptr(),
mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong,
b"bookmark%d\x00" as *const u8 as *const libc::c_char,
j + 1 as libc::c_int,
);
if strcmp(token.as_mut_ptr(), bkey.as_mut_ptr()) == 0 {
value = CString::new(self.bookmarks[j as usize]).unwrap().into_raw();
break;
} else {
j += 1
}
}
if value.is_null() {
return;
}
}
while *line as libc::c_int == ' ' as i32 || *line as libc::c_int == '\t' as i32 {
line = line.offset(1)
}
i = 0 as libc::c_int;
while *line != 0 {
if i < 512 as libc::c_int - 1 as libc::c_int {
let fresh1 = i;
i = i + 1;
*value.offset(fresh1 as isize) = *line
}
line = line.offset(1)
}
i -= 1;
while i > 0 as libc::c_int
&& (*value.offset(i as isize) as libc::c_int == ' ' as i32
|| *value.offset(i as isize) as libc::c_int == '\t' as i32)
{
i -= 1
unsafe fn parse_config_line(&mut self, line: &str) {
let trimmed_line = line.trim_start();
let words = trimmed_line.split_whitespace().take(2).collect::<Vec<_>>();
match words[0] {
"start_uri" => self.config.start_uri = words[1].to_string(),
"cmd_text" => self.config.cmd_text = words[1].to_string(),
"cmd_browser" => self.config.cmd_browser = words[1].to_string(),
"cmd_image" => self.config.cmd_image = words[1].to_string(),
"cmd_player" => self.config.cmd_player = words[1].to_string(),
"color_prompt" => self.config.color_prompt = words[1].to_string(),
"color_selector" => self.config.color_selector = words[1].to_string(),
"verbose" => self.config.verbose = words[1].to_string(),
x if x.starts_with("bookmark") => self.bookmarks.push(words[1].to_string()),
x => {
eprintln!("invalid key in config: {}", x);
exit(1)
},
}
i += 1;
*value.offset(i as isize) = 0 as libc::c_int as libc::c_char;
}
pub unsafe fn load_config(&mut self, mut filename: *const libc::c_char) {
let mut fp: *mut FILE = 0 as *mut FILE;
let mut ch: libc::c_int = 0;
let mut i: libc::c_int = 0;
let mut line: [libc::c_char; 1024] = [0; 1024];
fp = fopen(filename, b"r\x00" as *const u8 as *const libc::c_char);
if fp.is_null() {
return;
}
memset(
line.as_mut_ptr() as *mut libc::c_void,
0 as libc::c_int,
mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
);
i = 0 as libc::c_int;
ch = fgetc(fp);
loop {
match ch {
35 =>
while ch != '\n' as i32 && ch != -(1 as libc::c_int) {
ch = fgetc(fp)
},
-1 => {
self.parse_config_line(line.as_mut_ptr());
fclose(fp);
return;
}
13 => ch = fgetc(fp),
10 => {
self.parse_config_line(line.as_mut_ptr());
memset(
line.as_mut_ptr() as *mut libc::c_void,
0 as libc::c_int,
mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
);
i = 0 as libc::c_int;
ch = fgetc(fp)
}
_ => {
if (i as libc::c_ulong)
< (mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong)
.wrapping_sub(1 as libc::c_int as libc::c_ulong)
{
let fresh2 = i;
i = i + 1;
line[fresh2 as usize] = ch as libc::c_char
}
ch = fgetc(fp)
}
pub unsafe fn load_config<P: AsRef<Path>>(&mut self, filename: P) {
let mut file = match File::open(filename) {
Ok(f) => BufReader::new(f),
Err(_) => {
return;
}
}
};
file.lines().filter_map(|x| x.ok()).filter(|x| !x.starts_with('#')).for_each(|line| {
self.parse_config_line(&line)
})
}
pub unsafe fn init_config(&mut self) {
let mut filename: [libc::c_char; 1024] = [0; 1024];
let mut home: *const libc::c_char = 0 as *const libc::c_char;
let mut i: libc::c_int = 0;
/* copy defaults */
i = 0 as libc::c_int;
while i < 20 as libc::c_int {
self.bookmarks[i as usize][0 as libc::c_int as usize] = 0;
i += 1
}
/* read configs */
self.load_config(b"/etc/cgorc\x00" as *const u8 as *const libc::c_char); /* ignore incomplete selectors */
home = getenv(b"HOME\x00" as *const u8 as *const libc::c_char); /* not needed for history...just clear them */
if !home.is_null() {
snprintf(
filename.as_mut_ptr(),
mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
b"%s%s\x00" as *const u8 as *const libc::c_char,
home,
b"/.cgorc\x00" as *const u8 as *const libc::c_char,
);
self.load_config(filename.as_mut_ptr());
};
self.load_config("/etc/cgorc"); /* ignore incomplete selectors */
if let Some(dir) = env::home_dir() {
self.load_config(dir.join(".cgorc"));
}
}
pub unsafe fn download_file(
@ -958,44 +805,20 @@ impl BrowserState {
if key.is_none() {
println!("(bookmarks)");
i = 0;
while i < 20 {
if self.bookmarks[i as usize][0] != 0 {
make_key_str(i, &mut a, &mut b, &mut c);
println!(
"{}{}{} {}",
a,
b,
c,
CString::new(
self.bookmarks[i as usize]
.iter()
.take_while(|x| **x != 0)
.cloned()
.collect::<Vec<_>>()
)
.unwrap()
.into_string()
.unwrap()
);
}
i += 1
for bookmark in &self.bookmarks {
make_key_str(i, &mut a, &mut b, &mut c);
println!(
"{}{}{} {}",
a,
b,
c,
bookmark
);
}
} else if let Some(key) = key {
i = 0;
while i < 20 {
if self.bookmarks[i][0] != 0 && i == key {
if self.parse_uri(
CString::new(
self.bookmarks[i]
.iter()
.take_while(|x| **x != 0)
.cloned()
.collect::<Vec<_>>(),
)
.unwrap()
.into_string()
.unwrap(),
) {
for (i, bookmark) in self.bookmarks.clone().iter().enumerate() {
if i == key {
if self.parse_uri(bookmark) {
self.view_directory(
&self.parsed_host.clone(),
self.parsed_port.clone(),
@ -1005,21 +828,11 @@ impl BrowserState {
} else {
println!(
"invalid gopher URI: {}",
CString::new(
self.bookmarks[i]
.iter()
.take_while(|x| **x != 0)
.cloned()
.collect::<Vec<_>>()
)
.unwrap()
.into_string()
.unwrap()
bookmark,
);
}
return;
}
i += 1
}
};
}
@ -1133,7 +946,7 @@ impl BrowserState {
}
/* function prototypes */
pub unsafe fn parse_uri(&mut self, mut uri: String) -> bool {
pub unsafe fn parse_uri(&mut self, uri: &str) -> bool {
let mut tmp: &str = &uri[..];
/* strip gopher:// */
if uri.starts_with("gopher://") {
@ -1205,7 +1018,7 @@ impl BrowserState {
i += 1
}
/* parse uri */
if !self.parse_uri(uri) {
if !self.parse_uri(&uri) {
banner(false);
eprintln!("invalid gopher URI: {}", argv[i],);
exit(1);
@ -1285,7 +1098,7 @@ impl BrowserState {
},
71 => {
if self.parse_uri(
CString::from_raw(
&CString::from_raw(
&mut *line.as_mut_ptr().offset(1 as libc::c_int as isize)
as *mut u8 as *mut i8,
)

Loading…
Cancel
Save