make it work with musl (the _nox target does not link the screen module that wouldn't build)

pull/21/head
Ondřej Hruška 4 years ago
parent 4cf24f0382
commit 7efa04054c
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 16
      Cargo.lock
  2. 1
      Cargo.toml
  3. 14
      crsn_stdio/src/lib.rs
  4. 21
      launcher_nox/Cargo.toml
  5. 172
      launcher_nox/src/main.rs
  6. 14
      launcher_nox/src/read_file.rs
  7. 18
      launcher_nox/src/serde_duration_millis.rs

16
Cargo.lock generated

@ -365,6 +365,22 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "launcher_nox"
version = "0.1.0"
dependencies = [
"anyhow",
"clappconfig",
"crsn",
"crsn_arith",
"crsn_buf",
"crsn_stdio",
"log",
"serde",
"simple_logger",
"thiserror",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"

@ -1,6 +1,7 @@
[workspace] [workspace]
members = [ members = [
"launcher", "launcher",
"launcher_nox",
"crsn", "crsn",
"crsn_arith", "crsn_arith",
"crsn_screen", "crsn_screen",

@ -9,6 +9,7 @@ use crsn::sexp::SourcePosition;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::io; use std::io;
use crsn::asm::instr::cond::Flag; use crsn::asm::instr::cond::Flag;
use std::fmt;
mod console { mod console {
use std::{io}; use std::{io};
@ -98,7 +99,7 @@ mod console {
} }
} }
#[derive(Debug, Clone)] #[derive(Clone)]
pub struct StdioOps { pub struct StdioOps {
old_tio: Option<libc::termios>, old_tio: Option<libc::termios>,
hdl_stdin : Value, hdl_stdin : Value,
@ -107,6 +108,17 @@ pub struct StdioOps {
hdl_stdout_raw : Value, hdl_stdout_raw : Value,
} }
impl fmt::Debug for StdioOps {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("StdioOps")
.field("hdl_stdin", &format_args!("0x{:08x}", self.hdl_stdin))
.field("hdl_stdin_raw", &format_args!("0x{:08x}", self.hdl_stdin_raw))
.field("hdl_stdout", &format_args!("0x{:08x}", self.hdl_stdout))
.field("hdl_stdout_raw", &format_args!("0x{:08x}", self.hdl_stdout_raw))
.finish()
}
}
impl StdioOps { impl StdioOps {
pub fn new() -> Box<dyn CrsnExtension> { pub fn new() -> Box<dyn CrsnExtension> {
Box::new(Self { Box::new(Self {

@ -0,0 +1,21 @@
[package]
name = "launcher_nox"
version = "0.1.0"
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
crsn = { path = "../crsn" }
crsn_arith = { path = "../crsn_arith" }
crsn_buf = { path = "../crsn_buf" }
crsn_stdio = { path = "../crsn_stdio" }
simple_logger = "1.9.0"
log = "0.4.11"
thiserror = "1.0.20"
anyhow = "1.0.32"
clappconfig = "0.4.0"
serde = { version = "1.0.116", features = ["derive"] }

@ -0,0 +1,172 @@
#[macro_use]
extern crate log;
use std::collections::HashMap;
use std::time::Duration;
use clappconfig::{AppConfig, clap};
use clappconfig::clap::ArgMatches;
use serde::{Deserialize, Serialize};
use crsn::asm::data::literal::Addr;
use crsn::module::{OpTrait, CrsnUniq};
use crsn::runtime::run_thread::{RunThread, ThreadToken, ThreadParams};
use crsn_arith::ArithOps;
use crsn_stdio::StdioOps;
use crsn_buf::BufOps;
mod read_file;
mod serde_duration_millis;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct LogConfig {
level: String,
modules: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
struct Config {
log: LogConfig,
#[serde(skip)]
program_file: String,
#[serde(skip)]
assemble_only: bool,
#[serde(with = "serde_duration_millis")]
cycle_time: Duration,
}
impl Default for Config {
fn default() -> Self {
Self {
log: LogConfig {
level: "warn".to_string(),
modules: Default::default(),
},
program_file: "".to_string(),
assemble_only: false,
cycle_time: Duration::default(),
}
}
}
impl AppConfig for Config {
type Init = Self;
fn logging(&self) -> &str {
&self.log.level
}
fn logging_mod_levels(&self) -> Option<&HashMap<String, String>> {
Some(&self.log.modules)
}
fn pre_log_println(_message: String) {
// shut up
}
fn print_banner(_name: &str, _version: &str) {
// No banner
}
/// Add args to later use in the `configure` method.
fn add_args<'a: 'b, 'b>(clap: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
// Default impl
clap
.arg(
clap::Arg::with_name("input")
.value_name("FILE")
.help("Program to run")
.required_unless("default-config")
.takes_value(true),
)
.arg(
clap::Arg::with_name("asm-only")
.short("P")
.long("asm")
.help("Only assemble, do not run."),
)
.arg(
clap::Arg::with_name("cycle")
.long("cycle")
.short("C")
.value_name("MICROS")
.help("Cycle time (us, append \"s\" or \"ms\" for coarser time)")
.takes_value(true),
)
}
fn configure(mut self, clap: &ArgMatches) -> anyhow::Result<Self> {
self.program_file = clap.value_of("input").unwrap().to_string();
self.assemble_only = clap.is_present("asm-only");
if let Some(t) = clap.value_of("cycle") {
let (t, mul) = if t.ends_with("us") {
(&t[..(t.len()-2)], 1)
} else if t.ends_with("ms") {
(&t[..(t.len()-2)], 1000)
} else if t.ends_with("m") {
(&t[..(t.len()-1)], 1000)
} else if t.ends_with("u") {
(&t[..(t.len()-1)], 1)
} else if t.ends_with("s") {
(&t[..(t.len()-1)], 1000_000)
} else {
(t, 1)
};
self.cycle_time = Duration::from_micros(t.parse::<u64>().expect("parse -C value") * mul);
println!("ct = {:?}", self.cycle_time);
}
Ok(self)
}
}
fn main() -> anyhow::Result<()> {
let config = Config::init("crsn", "crsn.json5", env!("CARGO_PKG_VERSION"))?;
debug!("Loading {}", config.program_file);
let source = read_file::read_file(&config.program_file)?;
let uniq = CrsnUniq::new();
let parsed = crsn::asm::assemble(&source, &uniq, vec![
ArithOps::new(),
BufOps::new(),
StdioOps::new(),
])?;
if config.assemble_only {
for (n, op) in parsed.ops.iter().enumerate() {
println!("{:04} : {}", n, op.to_sexp());
}
return Ok(());
} else {
trace!("--- Compiled program ---");
for (n, op) in parsed.ops.iter().enumerate() {
trace!("{:04} : {}", n, op.to_sexp());
}
trace!("------------------------");
}
debug!("Start runtime");
let args = &[];
let thread = RunThread::new(ThreadParams {
id: ThreadToken(0),
uniq,
program: parsed,
pc: Addr(0),
cycle_time: config.cycle_time,
args
});
// run without spawning, so it is on the main thread - required by some extensions
thread.run();
debug!("Runtime shut down.");
Ok(())
}

@ -0,0 +1,14 @@
use std::fs::File;
use std::io;
use std::io::Read;
use std::path::Path;
/// Read a file to string
pub fn read_file<P: AsRef<Path>>(path: P) -> io::Result<String> {
let path = path.as_ref();
let mut file = File::open(path)?;
let mut buf = String::new();
file.read_to_string(&mut buf)?;
Ok(buf)
}

@ -0,0 +1,18 @@
use std::time::Duration;
use serde::{self, Deserialize, Deserializer, Serializer};
pub fn serialize<S>(value: &Duration, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
se.serialize_u64(value.as_secs() * 1000 + value.subsec_millis() as u64)
}
pub fn deserialize<'de, D>(de: D) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,
{
let s: u64 = u64::deserialize(de)?;
Ok(Duration::from_millis(s))
}
Loading…
Cancel
Save