Browse Source

Merge branch 'master' into feature/split-top-screen

pull/76/head
Ian Chamberlain 2 years ago
parent
commit
dd39cc36d9
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 14
      .github/workflows/ci.yml
  2. 1
      ctru-rs/Cargo.toml
  3. 213
      ctru-rs/src/error.rs
  4. 26
      ctru-rs/src/test_runner.rs
  5. 2
      ctru-sys/build.rs

14
.github/workflows/ci.yml

@ -27,6 +27,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: devkitpro/devkitarm container: devkitpro/devkitarm
steps: steps:
# https://github.com/nektos/act/issues/917#issuecomment-1074421318
- if: ${{ env.ACT }}
name: Hack container for local development
run: |
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
- name: Checkout branch - name: Checkout branch
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -56,9 +63,10 @@ jobs:
- name: Cargo check - name: Cargo check
run: cargo 3ds clippy --color=always --workspace --verbose --all-targets run: cargo 3ds clippy --color=always --workspace --verbose --all-targets
env: # --deny=warnings would be nice, but can easily break CI for new clippy
RUSTFLAGS: # lints getting added. I'd also like to use Github's "inline warnings"
--deny=warnings # feature, but https://github.com/actions/runner/issues/2341 means we
# can't have both that *and* colored output.
# TODO: it would be nice to actually build 3dsx for examples/tests, etc. # TODO: it would be nice to actually build 3dsx for examples/tests, etc.
# and run it somehow, but exactly how remains to be seen. # and run it somehow, but exactly how remains to be seen.

1
ctru-rs/Cargo.toml

@ -5,6 +5,7 @@ license = "https://en.wikipedia.org/wiki/Zlib_License"
name = "ctru-rs" name = "ctru-rs"
version = "0.7.1" version = "0.7.1"
edition = "2021" edition = "2021"
rust-version = "1.64"
[lib] [lib]
crate-type = ["rlib"] crate-type = ["rlib"]

213
ctru-rs/src/error.rs

@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::error; use std::error;
use std::ffi::CStr; use std::ffi::CStr;
use std::fmt; use std::fmt;
@ -9,7 +10,7 @@ pub type Result<T> = ::std::result::Result<T, Error>;
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord)]
#[repr(transparent)] #[repr(transparent)]
pub(crate) struct ResultCode(pub ctru_sys::Result); pub struct ResultCode(pub ctru_sys::Result);
impl Try for ResultCode { impl Try for ResultCode {
type Output = (); type Output = ();
@ -88,10 +89,10 @@ impl fmt::Debug for Error {
&Self::Os(err) => f &Self::Os(err) => f
.debug_struct("Error") .debug_struct("Error")
.field("raw", &format_args!("{err:#08X}")) .field("raw", &format_args!("{err:#08X}"))
.field("description", &R_DESCRIPTION(err)) .field("level", &result_code_level_str(err))
.field("module", &R_MODULE(err)) .field("module", &result_code_module_str(err))
.field("summary", &R_SUMMARY(err)) .field("summary", &result_code_summary_str(err))
.field("level", &R_LEVEL(err)) .field("description", &result_code_description_str(err))
.finish(), .finish(),
Self::Libc(err) => f.debug_tuple("Libc").field(err).finish(), Self::Libc(err) => f.debug_tuple("Libc").field(err).finish(),
Self::ServiceAlreadyActive => f.debug_tuple("ServiceAlreadyActive").finish(), Self::ServiceAlreadyActive => f.debug_tuple("ServiceAlreadyActive").finish(),
@ -121,3 +122,205 @@ impl error::Error for Error {
"error originating from a libctru function" "error originating from a libctru function"
} }
} }
fn result_code_level_str(result: ctru_sys::Result) -> Cow<'static, str> {
use ctru_sys::{
RL_FATAL, RL_INFO, RL_PERMANENT, RL_REINITIALIZE, RL_RESET, RL_STATUS, RL_SUCCESS,
RL_TEMPORARY, RL_USAGE,
};
Cow::Borrowed(match R_LEVEL(result) as u32 {
RL_SUCCESS => "success",
RL_INFO => "info",
RL_FATAL => "fatal",
RL_RESET => "reset",
RL_REINITIALIZE => "reinitialize",
RL_USAGE => "usage",
RL_PERMANENT => "permanent",
RL_TEMPORARY => "temporary",
RL_STATUS => "status",
code => return Cow::Owned(format!("(unknown: {code:#x})")),
})
}
fn result_code_summary_str(result: ctru_sys::Result) -> Cow<'static, str> {
use ctru_sys::{
RS_CANCELED, RS_INTERNAL, RS_INVALIDARG, RS_INVALIDRESVAL, RS_INVALIDSTATE, RS_NOP,
RS_NOTFOUND, RS_NOTSUPPORTED, RS_OUTOFRESOURCE, RS_STATUSCHANGED, RS_SUCCESS,
RS_WOULDBLOCK, RS_WRONGARG,
};
Cow::Borrowed(match R_SUMMARY(result) as u32 {
RS_SUCCESS => "success",
RS_NOP => "nop",
RS_WOULDBLOCK => "would_block",
RS_OUTOFRESOURCE => "out_of_resource",
RS_NOTFOUND => "not_found",
RS_INVALIDSTATE => "invalid_state",
RS_NOTSUPPORTED => "not_supported",
RS_INVALIDARG => "invalid_arg",
RS_WRONGARG => "wrong_arg",
RS_CANCELED => "canceled",
RS_STATUSCHANGED => "status_changed",
RS_INTERNAL => "internal",
RS_INVALIDRESVAL => "invalid_res_val",
code => return Cow::Owned(format!("(unknown: {code:#x})")),
})
}
fn result_code_description_str(result: ctru_sys::Result) -> Cow<'static, str> {
use ctru_sys::{
RD_ALREADY_DONE, RD_ALREADY_EXISTS, RD_ALREADY_INITIALIZED, RD_BUSY, RD_CANCEL_REQUESTED,
RD_INVALID_ADDRESS, RD_INVALID_COMBINATION, RD_INVALID_ENUM_VALUE, RD_INVALID_HANDLE,
RD_INVALID_POINTER, RD_INVALID_RESULT_VALUE, RD_INVALID_SELECTION, RD_INVALID_SIZE,
RD_MISALIGNED_ADDRESS, RD_MISALIGNED_SIZE, RD_NOT_AUTHORIZED, RD_NOT_FOUND,
RD_NOT_IMPLEMENTED, RD_NOT_INITIALIZED, RD_NO_DATA, RD_OUT_OF_MEMORY, RD_OUT_OF_RANGE,
RD_SUCCESS, RD_TIMEOUT, RD_TOO_LARGE,
};
Cow::Borrowed(match R_DESCRIPTION(result) as u32 {
RD_SUCCESS => "success",
RD_INVALID_RESULT_VALUE => "invalid_result_value",
RD_TIMEOUT => "timeout",
RD_OUT_OF_RANGE => "out_of_range",
RD_ALREADY_EXISTS => "already_exists",
RD_CANCEL_REQUESTED => "cancel_requested",
RD_NOT_FOUND => "not_found",
RD_ALREADY_INITIALIZED => "already_initialized",
RD_NOT_INITIALIZED => "not_initialized",
RD_INVALID_HANDLE => "invalid_handle",
RD_INVALID_POINTER => "invalid_pointer",
RD_INVALID_ADDRESS => "invalid_address",
RD_NOT_IMPLEMENTED => "not_implemented",
RD_OUT_OF_MEMORY => "out_of_memory",
RD_MISALIGNED_SIZE => "misaligned_size",
RD_MISALIGNED_ADDRESS => "misaligned_address",
RD_BUSY => "busy",
RD_NO_DATA => "no_data",
RD_INVALID_COMBINATION => "invalid_combination",
RD_INVALID_ENUM_VALUE => "invalid_enum_value",
RD_INVALID_SIZE => "invalid_size",
RD_ALREADY_DONE => "already_done",
RD_NOT_AUTHORIZED => "not_authorized",
RD_TOO_LARGE => "too_large",
RD_INVALID_SELECTION => "invalid_selection",
code => return Cow::Owned(format!("(unknown: {code:#x})")),
})
}
fn result_code_module_str(result: ctru_sys::Result) -> Cow<'static, str> {
use ctru_sys::{
RM_AC, RM_ACC, RM_ACT, RM_AM, RM_AM_LOW, RM_APPLET, RM_APPLICATION, RM_AVD, RM_BOSS,
RM_CAM, RM_CARD, RM_CARDNOR, RM_CARD_SPI, RM_CEC, RM_CODEC, RM_COMMON, RM_CONFIG, RM_CSND,
RM_CUP, RM_DBG, RM_DBM, RM_DD, RM_DI, RM_DLP, RM_DMNT, RM_DSP, RM_EC, RM_ENC, RM_FATFS,
RM_FILE_SERVER, RM_FND, RM_FRIENDS, RM_FS, RM_FSI, RM_GD, RM_GPIO, RM_GSP, RM_GYROSCOPE,
RM_HID, RM_HIO, RM_HIO_LOW, RM_HTTP, RM_I2C, RM_INVALIDRESVAL, RM_IR, RM_KERNEL, RM_L2B,
RM_LDR, RM_LOADER_SERVER, RM_MC, RM_MCU, RM_MIC, RM_MIDI, RM_MP, RM_MPWL, RM_MVD, RM_NDM,
RM_NEIA, RM_NEWS, RM_NEX, RM_NFC, RM_NFP, RM_NGC, RM_NIM, RM_NPNS, RM_NS, RM_NWM, RM_OLV,
RM_OS, RM_PDN, RM_PI, RM_PIA, RM_PL, RM_PM, RM_PM_LOW, RM_PS, RM_PTM, RM_PXI, RM_QTM,
RM_RDT, RM_RO, RM_ROMFS, RM_SDMC, RM_SND, RM_SOC, RM_SPI, RM_SPM, RM_SRV, RM_SSL, RM_SWC,
RM_TCB, RM_TEST, RM_UART, RM_UDS, RM_UPDATER, RM_UTIL, RM_VCTL, RM_WEB_BROWSER,
};
Cow::Borrowed(match R_MODULE(result) as u32 {
RM_COMMON => "common",
RM_KERNEL => "kernel",
RM_UTIL => "util",
RM_FILE_SERVER => "file_server",
RM_LOADER_SERVER => "loader_server",
RM_TCB => "tcb",
RM_OS => "os",
RM_DBG => "dbg",
RM_DMNT => "dmnt",
RM_PDN => "pdn",
RM_GSP => "gsp",
RM_I2C => "i2c",
RM_GPIO => "gpio",
RM_DD => "dd",
RM_CODEC => "codec",
RM_SPI => "spi",
RM_PXI => "pxi",
RM_FS => "fs",
RM_DI => "di",
RM_HID => "hid",
RM_CAM => "cam",
RM_PI => "pi",
RM_PM => "pm",
RM_PM_LOW => "pm_low",
RM_FSI => "fsi",
RM_SRV => "srv",
RM_NDM => "ndm",
RM_NWM => "nwm",
RM_SOC => "soc",
RM_LDR => "ldr",
RM_ACC => "acc",
RM_ROMFS => "romfs",
RM_AM => "am",
RM_HIO => "hio",
RM_UPDATER => "updater",
RM_MIC => "mic",
RM_FND => "fnd",
RM_MP => "mp",
RM_MPWL => "mpwl",
RM_AC => "ac",
RM_HTTP => "http",
RM_DSP => "dsp",
RM_SND => "snd",
RM_DLP => "dlp",
RM_HIO_LOW => "hio_low",
RM_CSND => "csnd",
RM_SSL => "ssl",
RM_AM_LOW => "am_low",
RM_NEX => "nex",
RM_FRIENDS => "friends",
RM_RDT => "rdt",
RM_APPLET => "applet",
RM_NIM => "nim",
RM_PTM => "ptm",
RM_MIDI => "midi",
RM_MC => "mc",
RM_SWC => "swc",
RM_FATFS => "fatfs",
RM_NGC => "ngc",
RM_CARD => "card",
RM_CARDNOR => "cardnor",
RM_SDMC => "sdmc",
RM_BOSS => "boss",
RM_DBM => "dbm",
RM_CONFIG => "config",
RM_PS => "ps",
RM_CEC => "cec",
RM_IR => "ir",
RM_UDS => "uds",
RM_PL => "pl",
RM_CUP => "cup",
RM_GYROSCOPE => "gyroscope",
RM_MCU => "mcu",
RM_NS => "ns",
RM_NEWS => "news",
RM_RO => "ro",
RM_GD => "gd",
RM_CARD_SPI => "card_spi",
RM_EC => "ec",
RM_WEB_BROWSER => "web_browser",
RM_TEST => "test",
RM_ENC => "enc",
RM_PIA => "pia",
RM_ACT => "act",
RM_VCTL => "vctl",
RM_OLV => "olv",
RM_NEIA => "neia",
RM_NPNS => "npns",
RM_AVD => "avd",
RM_L2B => "l2b",
RM_MVD => "mvd",
RM_NFC => "nfc",
RM_UART => "uart",
RM_SPM => "spm",
RM_QTM => "qtm",
RM_NFP => "nfp",
RM_APPLICATION => "application",
RM_INVALIDRESVAL => "invalid_res_val",
code => return Cow::Owned(format!("(unknown: {code:#x})")),
})
}

26
ctru-rs/src/test_runner.rs

@ -4,7 +4,7 @@ extern crate test;
use std::io; use std::io;
use test::{ColorConfig, Options, OutputFormat, RunIgnored, TestDescAndFn, TestFn, TestOpts}; use test::{ColorConfig, OutputFormat, TestDescAndFn, TestFn, TestOpts};
use crate::console::Console; use crate::console::Console;
use crate::gfx::Gfx; use crate::gfx::Gfx;
@ -25,34 +25,18 @@ pub(crate) fn run(tests: &[&TestDescAndFn]) {
top_screen.set_wide_mode(true); top_screen.set_wide_mode(true);
let _console = Console::init(top_screen); let _console = Console::init(top_screen);
// TODO: it would be nice to have a way of specifying argv to make these
// configurable at runtime, but I can't figure out how to do it easily,
// so for now, just hardcode everything.
let opts = TestOpts { let opts = TestOpts {
list: false,
filters: Vec::new(),
filter_exact: false,
// Forking is not supported
force_run_in_process: true, force_run_in_process: true,
exclude_should_panic: false,
run_ignored: RunIgnored::No,
run_tests: true, run_tests: true,
// Don't run benchmarks. We may want to create a separate runner for them in the future
bench_benchmarks: false,
logfile: None,
nocapture: false,
// TODO: color doesn't work because of TERM/TERMINFO. // TODO: color doesn't work because of TERM/TERMINFO.
// With RomFS we might be able to fake this out nicely... // With RomFS we might be able to fake this out nicely...
color: ColorConfig::AutoColor, color: ColorConfig::AutoColor,
format: OutputFormat::Pretty, format: OutputFormat::Pretty,
shuffle: false, // Hopefully this interface is more stable vs specifying individual options,
shuffle_seed: None, // and parsing the empty list of args should always work, I think.
test_threads: None, // TODO Ideally we could pass actual std::env::args() here too
skip: Vec::new(), ..test::test::parse_opts(&[]).unwrap().unwrap()
time_options: None,
options: Options::new(),
}; };
// Use the default test implementation with our hardcoded options // Use the default test implementation with our hardcoded options
let _success = run_static_tests(&opts, tests).unwrap(); let _success = run_static_tests(&opts, tests).unwrap();

2
ctru-sys/build.rs

@ -6,7 +6,7 @@ fn main() {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=DEVKITPRO"); println!("cargo:rerun-if-env-changed=DEVKITPRO");
println!("cargo:rustc-link-search=native={}/libctru/lib", dkp_path); println!("cargo:rustc-link-search=native={dkp_path}/libctru/lib");
println!( println!(
"cargo:rustc-link-lib=static={}", "cargo:rustc-link-lib=static={}",
match profile.as_str() { match profile.as_str() {

Loading…
Cancel
Save