Skip to content

Added support to the -q flag #164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions src/b.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,16 @@ pub unsafe fn include_path_if_exists(input_paths: &mut Array<*const c_char>, pat
Some(())
}

static mut QUIET: *mut bool = ptr::null_mut();

macro_rules! log_info {
($($arg:tt)*) => {{
if !*QUIET {
printf($($arg)*);
}
}};
}

pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
let default_target;
if cfg!(target_arch = "aarch64") && cfg!(target_os = "linux") {
Expand All @@ -1159,6 +1169,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
let linker = flag_list(c!("L"), c!("Append a flag to the linker of the target platform"));
let nostdlib = flag_bool(c!("nostdlib"), false, c!("Do not link with standard libraries like libb and/or libc on some platforms"));
let ir = flag_bool(c!("ir"), false, c!("Instead of compiling, dump the IR of the program to stdout"));
QUIET = flag_bool(c!("q"), false, c!("Don't do logging"));
let historical = flag_bool(c!("hist"), false, c!("Makes the compiler strictly follow the description of the B language from the \"Users' Reference to B\" by Ken Thompson as much as possible"));

let mut input_paths: Array<*const c_char> = zeroed();
Expand Down Expand Up @@ -1211,6 +1222,11 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
fprintf(stderr(), c!("ERROR: no inputs are provided\n"));
return None;
}

if *QUIET {
// Didn't know if errors would be ignored, so nob is still logging errors
MINIMAL_LOG_LEVEL = LogLevel::Error;
}

let mut c: Compiler = zeroed();
c.target = target;
Expand Down Expand Up @@ -1246,13 +1262,13 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
// But I do plan to have similar testing tool written in Crust.
//
// - rexim (2025-06-12 20:18:02)
printf(c!("INFO: Compiling files "));
log_info!(c!("INFO: Compiling files "));
for i in 0..input_paths.count {
let input_path = *input_paths.items.add(i);
if i > 0 { printf(c!(" ")); }
printf(c!("%s"), input_path);
if i > 0 { log_info!(c!(" ")); }
log_info!(c!("%s"), input_path);
}
printf(c!("\n"));
log_info!(c!("\n"));

let mut input: String_Builder = zeroed();

Expand All @@ -1279,7 +1295,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
if *ir {
codegen::ir::generate_program(&mut output, &c);
da_append(&mut output, 0);
printf(c!("%s"), output.items);
log_info!(c!("%s"), output.items);
return Some(())
}

Expand All @@ -1300,7 +1316,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {

let output_asm_path = temp_sprintf(c!("%s.s"), effective_output_path);
if !write_entire_file(output_asm_path, output.items as *const c_void, output.count) { return None; }
printf(c!("INFO: Generated %s\n"), output_asm_path);
log_info!(c!("INFO: Generated %s\n"), output_asm_path);

let (gas, cc) = if cfg!(target_arch = "aarch64") && cfg!(target_os = "linux") {
(c!("as"), c!("cc"))
Expand All @@ -1315,7 +1331,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
&mut cmd,
gas, c!("-o"), output_obj_path, output_asm_path,
}
if !cmd_run_sync_and_reset(&mut cmd) { return None; }
if !cmd_with_controlled_output(&mut cmd) { return None; }
cmd_append! {
&mut cmd,
cc, c!("-no-pie"), c!("-o"), effective_output_path, output_obj_path,
Expand All @@ -1332,7 +1348,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
*(*linker).items.add(i),
}
}
if !cmd_run_sync_and_reset(&mut cmd) { return None; }
if !cmd_with_controlled_output(&mut cmd) { return None; }
if *run {
runner::gas_aarch64_linux::run(&mut cmd, effective_output_path, da_slice(run_args))?;
}
Expand All @@ -1353,7 +1369,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {

let output_asm_path = temp_sprintf(c!("%s.asm"), effective_output_path);
if !write_entire_file(output_asm_path, output.items as *const c_void, output.count) { return None; }
printf(c!("INFO: Generated %s\n"), output_asm_path);
log_info!(c!("INFO: Generated %s\n"), output_asm_path);

if !(cfg!(target_arch = "x86_64") && cfg!(target_os = "linux")) {
// TODO: think how to approach cross-compilation
Expand All @@ -1366,7 +1382,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
&mut cmd,
c!("fasm"), output_asm_path, output_obj_path,
}
if !cmd_run_sync_and_reset(&mut cmd) { return None; }
if !cmd_with_controlled_output(&mut cmd) { return None; }
cmd_append! {
&mut cmd,
c!("cc"), c!("-no-pie"), c!("-o"), effective_output_path, output_obj_path,
Expand All @@ -1383,7 +1399,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
*(*linker).items.add(i),
}
}
if !cmd_run_sync_and_reset(&mut cmd) { return None; }
if !cmd_with_controlled_output(&mut cmd) { return None; }
if *run {
runner::fasm_x86_64_linux::run(&mut cmd, effective_output_path, da_slice(run_args))?
}
Expand All @@ -1410,7 +1426,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {

let output_asm_path = temp_sprintf(c!("%s.asm"), base_path);
if !write_entire_file(output_asm_path, output.items as *const c_void, output.count) { return None; }
printf(c!("INFO: Generated %s\n"), output_asm_path);
log_info!(c!("INFO: Generated %s\n"), output_asm_path);

let cc = if cfg!(target_arch = "x86_64") && cfg!(target_os = "windows") {
c!("cc")
Expand All @@ -1423,7 +1439,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
&mut cmd,
c!("fasm"), output_asm_path, output_obj_path,
}
if !cmd_run_sync_and_reset(&mut cmd) { return None; }
if !cmd_with_controlled_output(&mut cmd) { return None; }
cmd_append! {
&mut cmd,
cc, c!("-no-pie"), c!("-o"), effective_output_path, output_obj_path,
Expand All @@ -1440,7 +1456,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
*(*linker).items.add(i),
}
}
if !cmd_run_sync_and_reset(&mut cmd) { return None; }
if !cmd_with_controlled_output(&mut cmd) { return None; }
if *run {
runner::fasm_x86_64_windows::run(&mut cmd, effective_output_path, da_slice(run_args))?;
}
Expand All @@ -1458,7 +1474,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
}

if !write_entire_file(effective_output_path, output.items as *const c_void, output.count) { return None; }
printf(c!("INFO: Generated %s\n"), effective_output_path);
log_info!(c!("INFO: Generated %s\n"), effective_output_path);
if *run {
runner::uxn::run(&mut cmd, c!("uxnemu"), effective_output_path, da_slice(run_args))?;
}
Expand All @@ -1477,7 +1493,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
}

if !write_entire_file(effective_output_path, output.items as *const c_void, output.count) { return None; }
printf(c!("INFO: Generated %s\n"), effective_output_path);
log_info!(c!("INFO: Generated %s\n"), effective_output_path);
if *run {
runner::mos6502::run(&mut output, config, effective_output_path)?;
}
Expand Down
44 changes: 44 additions & 0 deletions src/nob.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::ffi::*;
use core::slice;
use core::ptr;
use crate::crust::libc;

#[repr(C)]
Expand Down Expand Up @@ -83,9 +84,27 @@ macro_rules! cmd_append {
}
}

#[repr(C)]
pub struct CmdRedirect {
pub fdin: *mut Fd,
pub fdout: *mut Fd,
pub fderr: *mut Fd,
}

#[repr(C)]
pub enum LogLevel {
Info,
Warning,
Error,
NoLogs,
}

extern "C" {
#[link_name = "nob_cmd_run_sync_and_reset"]
pub fn cmd_run_sync_and_reset(cmd: *mut Cmd) -> bool;

#[link_name = "nob_cmd_run_sync_redirect_and_reset"]
pub fn cmd_run_sync_redirect_and_reset(cmd: *mut Cmd, redirect: CmdRedirect) -> bool;
}

pub type String_Builder = Array<c_char>;
Expand All @@ -98,6 +117,7 @@ pub struct String_View {
}

pub type File_Paths = Array<*const c_char>;
pub type Fd = c_int;

extern "C" {
#[link_name = "nob_read_entire_file"]
Expand All @@ -124,6 +144,30 @@ extern "C" {
pub fn mkdir_if_not_exists(path: *const c_char) -> bool;
#[link_name = "nob_read_entire_dir"]
pub fn read_entire_dir(parent: *const c_char, children: *mut File_Paths) -> bool;
#[link_name = "nob_minimal_log_level"]
pub static mut MINIMAL_LOG_LEVEL: LogLevel;
#[link_name = "nob_fd_open_for_write"]
pub fn fd_open_for_write(path: *const c_char) -> Fd;
#[link_name = "nob_fd_close"]
pub fn fd_close(fd: Fd);
}

pub unsafe fn cmd_with_controlled_output(cmd: *mut Cmd) -> bool {
if !matches!(MINIMAL_LOG_LEVEL, LogLevel::Error | LogLevel::NoLogs) {
cmd_run_sync_and_reset(cmd)
} else {
// Someone could optimize this to only open /dev/null at the start of the program
// but I'm not sure if the performance increase would be worth it
let mut out_fd = fd_open_for_write("/dev/null".as_ptr() as *const c_char);
let redirect = CmdRedirect {
fdin: ptr::null_mut(),
fdout: &mut out_fd,
fderr: ptr::null_mut(),
};
let res = cmd_run_sync_redirect_and_reset(cmd, redirect);
fd_close(out_fd);
res
}
}

// TODO: This is a generally useful function. Consider making it a part of nob.h
Expand Down