1
0
forked from bonsai/harakit

Compare commits

...

34 Commits

Author SHA1 Message Date
c75bb93001 Makefile: directory specification changes 2024-03-24 13:28:42 -06:00
31ae3d1997 Revert "Merge branch 'main' into strerror (not PGP signed)"
This reverts commit 7e45af1bca, reversing
changes made to d87b5d0958.
2024-03-24 13:15:55 -06:00
dtb
7e45af1bca Merge branch 'main' into strerror 2024-03-24 00:18:15 +00:00
d87b5d0958 hru(1), fop(1): changed to reflect strerror changes 2024-03-18 21:31:25 -06:00
1891c3e1aa strerror(3): created strerror() method 2024-03-18 21:30:43 -06:00
127192185f Merge branch 'dj-fix' (closes #66) 2024-03-18 21:01:48 -06:00
f81232685a Merge branch 'mm' 2024-03-18 20:56:06 -06:00
05b5a4480c Merge branch 'swab' (closes #22) 2024-03-18 20:53:08 -06:00
b356ac522f strerror(3): changed panic to 0 2024-03-18 20:45:53 -06:00
b2d56bbc9a Makefile: even more changes 2024-03-09 22:02:19 -07:00
2ad7140e1e Makefile: DESTDIR 2024-03-09 11:53:03 -07:00
8193e471f0 changes redundant .unwrap_or_else(panic!()) to .unwrap() 2024-03-03 17:26:40 -07:00
c392dbc680 Makefile: better deps; fop(1), hru(1), strerror(3): changed strerror wrapper function name 2024-03-02 10:16:32 -07:00
898044cd43 Makefile: better macro assignment 2024-03-01 23:51:36 -07:00
ca01ca4074 rpn(1): remove erroneous strerror(3) dependency 2024-03-01 23:14:58 -07:00
3e6dc5cc46 rpn(1): make error messages consistent with other tools 2024-03-01 23:14:18 -07:00
cf1d16f860 hru(1): changed to use strerror(3) 2024-03-01 23:12:44 -07:00
8f956d775c fop(1): changed to use strerror(3) 2024-03-01 23:10:28 -07:00
e81703c6e1 sterror(3): added library for C-like error messages; Makefile: some efficiency changes 2024-03-01 23:04:53 -07:00
DTB
135bf2a8eb mm(1), mm.1: bring source in line with documentation 2024-02-26 09:11:47 -07:00
DTB
d74bc715cf mm(1): fix full file handling 2024-02-26 09:02:58 -07:00
DTB
f14877118d Makefile: add swab(1) 2024-02-26 08:43:03 -07:00
DTB
bbac85daf8 swab(1): add copyright notice 2024-02-26 08:42:06 -07:00
DTB
1e041a52a2 swab.1: add swab(1) man page 2024-02-24 03:21:20 -07:00
DTB
e788947fc4 swab(1): add argument parsing 2024-02-24 03:04:05 -07:00
c97201fca9 Merge branch 'contributing-changes' 2024-02-23 23:20:16 -07:00
06fc461985 CONTRIBUTING: fixed random "utils" 2024-02-23 23:19:28 -07:00
DTB
3f0d95fe8f swab(1): minimum viable program 2024-02-23 20:49:24 -07:00
DTB
58245c9484 dj(1): remove function pointer hijinks (fixes #66) 2024-02-22 19:27:14 -07:00
DTB
395205d4c6 mm.1: fix case in copyright thingy 2024-02-22 19:14:38 -07:00
0d445c71f4 CONTRIBUTING: fixed wording and updated 2024-02-18 15:09:09 -07:00
DTB
194b19f94b mm(1): add 2024-02-17 23:43:22 -07:00
d45e3410f8 CONTRIBUTING: fixed some small issues 2024-02-07 22:03:08 -07:00
452a1295e6 CONTRIBUTING: updated and added copyright info 2024-02-07 21:54:46 -07:00
7 changed files with 128 additions and 57 deletions

View File

@@ -90,26 +90,44 @@ notice:
* USE OR OTHER DEALINGS IN THE SOFTWARE. * USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
When writing code, make sure lines never exceed 80 characters in width when Make sure lines never exceed 80 columns in width when using four-character
using four-character-wide indentation steps. indentation steps. This helps contributors with smaller screens, those using
side-by-side editor windows or panes, and those who have no text wrapping in
their editor or terminal.
For usage text and help messages, please do not implement a -h option. Just For usage text and help messages, do not implement a -h option. Instead, print
print usage information when any erroneous option is specified. Follow the usage information when any erroneous option is specified. Follow the NetBSD
NetBSD style guide for usage text output format [1]. style guide for the usage texts output format [1].
If committing a new source file for a utility, format the commit message like [1] <http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/share/misc/style>
this:
$ git commit -m 'tool(1): <information>' If committing a new source file, format the commit message following these
guidelines:
$ git commit -m 'tool(1): add feature x'
If committing a new library or header file: If committing a new library or header file:
$ git commit -m 'library(1): <information>' $ git commit -m 'library(3): fix overflow'
$ git commit -m 'header.h(3): add header.h(3)'
If committing a new manual page:
$ git commit -m 'tool.1: add author details'
If modifying some other file or directory: If modifying some other file or directory:
$ git commit -m 'README: clarification' $ git commit -m 'README: clarify'
$ git commit -m 'tests: posix: fixed bug #47' $ git commit -m 'tests/posix: fix bug #47'
$ git commit -m 'docs: tool(1): added author information'
etc. For multiple of these:
$ git commit -m 'Makefile, tool(1): add tool(1)'
$ git commit -m 'tool(1): add tool(1); library(3), library.3: add library(3)'
$ git commit -m 'tool(1): fix #42 & add feature x'
Commit messages should be written in the present tense.
--
This work © 20232024 by Emma Tebibyte is licensed under CC BY-SA 4.0. To view a
copy of this license, visit <http://creativecommons.org/licenses/by-sa/4.0/>

View File

@@ -8,13 +8,23 @@
# notice are preserved. This file is offered as-is, without any warranty. # notice are preserved. This file is offered as-is, without any warranty.
.POSIX: .POSIX:
# if using BSD make(1), remove these pragmas because they break it
.PRAGMA: posix_202x # future POSIX standard support à la pdpmake(1) .PRAGMA: posix_202x # future POSIX standard support à la pdpmake(1)
.PRAGMA: command_comment # breaks without this? .PRAGMA: command_comment # breaks without this?
PREFIX=/usr/local DESTDIR ?= dist
PREFIX ?= /usr/local
CC=cc SYSEXITS != printf '\043include <sysexits.h>\n' | cpp -M - | sed 's/ /\n/g' \
RUSTC=rustc | sed -n 's/sysexits\.h//p' || printf 'include\n'
CC ?= cc
RUSTC ?= rustc
RUSTLIBS = --extern getopt=build/o/libgetopt.rlib \
--extern sysexits=build/o/libsysexits.rlib \
--extern strerror=build/o/libstrerror.rlib
CFLAGS += -I$(SYSEXITS)
.PHONY: all .PHONY: all
all: dj false fop hru intcmp rpn scrut str strcmp true all: dj false fop hru intcmp rpn scrut str strcmp true
@@ -26,36 +36,40 @@ build:
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf build/ dist/ rm -rf build dist
dist: all dist: all
mkdir -p dist/bin dist/share/man/man1 mkdir -p $(DESTDIR)/$(PREFIX)/bin $(DESTDIR)/$(PREFIX)/share/man/man1
cp build/bin/* dist/bin/ cp build/bin/* $(DESTDIR)/$(PREFIX)/bin
cp docs/*.1 dist/share/man/man1/ cp docs/*.1 $(DESTDIR)/$(PREFIX)/share/man/man1
.PHONY: install .PHONY: install
install: dist install: dist
mkdir -p $(PREFIX) cp -r $(DESTDIR)/* /
cp -r dist/* $(PREFIX)/
.PHONY: test .PHONY: test
test: build test: build
tests/posix-compat.sh tests/posix-compat.sh
$(RUSTC) --test src/getopt-rs/lib.rs -o build/test/getopt $(RUSTC) --test src/getopt-rs/lib.rs -o build/test/getopt
build/o/libsysexits.rlib: build .PHONY: rustlibs
rustlibs: build/o/libsysexits.rlib build/o/libgetopt.rlib \
build/o/libstrerror.rlib
build/o/libgetopt.rlib: build src/getopt-rs/lib.rs
$(RUSTC) $(RUSTFLAGS) --crate-type=lib --crate-name=getopt \
-o $@ src/getopt-rs/lib.rs
build/o/libstrerror.rlib: build src/strerror.rs
$(RUSTC) $(RUSTFLAGS) --crate-type=lib -o $@ \
src/strerror.rs
build/o/libsysexits.rlib: build $(SYSEXITS)sysexits.h
# bandage solution until bindgen(1) gets stdin support # bandage solution until bindgen(1) gets stdin support
printf '#define EXIT_FAILURE 1\n' | cat - include/sysexits.h \ printf '#define EXIT_FAILURE 1\n' | cat - $(SYSEXITS)sysexits.h \
> build/include/sysexits.h > build/include/sysexits.h
bindgen --default-macro-constant-type signed --use-core --formatter=none \ bindgen --default-macro-constant-type signed --use-core --formatter=none \
"$$(printf '#include <sysexits.h>\n' \ build/include/sysexits.h | $(RUSTC) $(RUSTFLAGS) --crate-type lib -o $@ -
| cpp -M -idirafter "build/include" - \
| sed 's/ /\n/g' | grep sysexits.h)" \
| $(RUSTC) $(RUSTFLAGS) --crate-type lib -o build/o/libsysexits.rlib -
build/o/libgetopt.rlib: src/getopt-rs/lib.rs
$(RUSTC) $(RUSTFLAGS) --crate-type=lib --crate-name=getopt \
-o build/o/libgetopt.rlib src/getopt-rs/lib.rs
.PHONY: dj .PHONY: dj
dj: build/bin/dj dj: build/bin/dj
@@ -69,17 +83,13 @@ build/bin/false: src/false.c build
.PHONY: fop .PHONY: fop
fop: build/bin/fop fop: build/bin/fop
build/bin/fop: src/fop.rs build build/o/libgetopt.rlib build/o/libsysexits.rlib build/bin/fop: src/fop.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) --extern getopt=build/o/libgetopt.rlib \ $(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/fop.rs
--extern sysexits=build/o/libsysexits.rlib \
-o $@ src/fop.rs
.PHONY: hru .PHONY: hru
hru: build/bin/hru hru: build/bin/hru
build/bin/hru: src/hru.rs build build/o/libgetopt.rlib build/o/libsysexits.rlib build/bin/hru: src/hru.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) --extern getopt=build/o/libgetopt.rlib \ $(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/hru.rs
--extern sysexits=build/o/libsysexits.rlib \
-o $@ src/hru.rs
.PHONY: intcmp .PHONY: intcmp
intcmp: build/bin/intcmp intcmp: build/bin/intcmp
@@ -88,10 +98,8 @@ build/bin/intcmp: src/intcmp.c build
.PHONY: rpn .PHONY: rpn
rpn: build/bin/rpn rpn: build/bin/rpn
build/bin/rpn: src/rpn.rs build build/o/libsysexits.rlib build/bin/rpn: src/rpn.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) \ $(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/rpn.rs
--extern sysexits=build/o/libsysexits.rlib \
-o $@ src/rpn.rs
.PHONY: scrut .PHONY: scrut
scrut: build/bin/scrut scrut: build/bin/scrut

View File

@@ -22,10 +22,12 @@ use std::{
process::{ Command, exit, Stdio }, process::{ Command, exit, Stdio },
}; };
extern crate sysexits;
extern crate getopt; extern crate getopt;
extern crate strerror;
extern crate sysexits;
use getopt::{ Opt, Parser }; use getopt::{ Opt, Parser };
use strerror::StrError;
use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE };
fn main() { fn main() {
@@ -55,7 +57,7 @@ fn main() {
}); });
let index = argv[index_arg].parse::<usize>().unwrap_or_else(|e| { let index = argv[index_arg].parse::<usize>().unwrap_or_else(|e| {
eprintln!("{}: {}: {}.", argv[0], argv[1], e); eprintln!("{}: {}: {}", argv[0], argv[1], e);
exit(EX_DATAERR); exit(EX_DATAERR);
}); });
@@ -75,13 +77,13 @@ fn main() {
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn() .spawn()
.unwrap_or_else( |e| { .unwrap_or_else( |e| {
eprintln!("{}: {}: {}.", argv[0], argv[command_arg], e); eprintln!("{}: {}: {}", argv[0], argv[command_arg], e.strerror());
exit(EX_UNAVAILABLE); exit(EX_UNAVAILABLE);
}); });
let field = fields.get(index).unwrap_or_else(|| { let field = fields.get(index).unwrap_or_else(|| {
eprintln!( eprintln!(
"{}: {}: No such index in input.", "{}: {}: No such index in input",
argv[0], argv[0],
index.to_string(), index.to_string(),
); );
@@ -94,7 +96,7 @@ fn main() {
} }
let output = spawned.wait_with_output().unwrap_or_else(|e| { let output = spawned.wait_with_output().unwrap_or_else(|e| {
eprintln!("{}: {}: {}.", argv[0], argv[command_arg], e); eprintln!("{}: {}: {}", argv[0], argv[command_arg], e.strerror());
exit(EX_IOERR); exit(EX_IOERR);
}); });
@@ -103,7 +105,7 @@ fn main() {
if replace.pop() != Some(b'\n') { replace = output.stdout; } if replace.pop() != Some(b'\n') { replace = output.stdout; }
let new_field = String::from_utf8(replace).unwrap_or_else(|e| { let new_field = String::from_utf8(replace).unwrap_or_else(|e| {
eprintln!("{}: {}: {}.", argv[0], argv[command_arg], e); eprintln!("{}: {}: {}", argv[0], argv[command_arg], e);
exit(EX_IOERR); exit(EX_IOERR);
}); });
@@ -111,8 +113,8 @@ fn main() {
stdout().write_all( stdout().write_all(
fields.join(&d.to_string()).as_bytes() fields.join(&d.to_string()).as_bytes()
).unwrap_or_else(|e|{ ).unwrap_or_else(|e| {
eprintln!("{}: {}.", argv[0], e); eprintln!("{}: {}", argv[0], e.strerror());
exit(EX_IOERR); exit(EX_IOERR);
}); });
} }

View File

@@ -23,8 +23,10 @@ use std::{
process::{ ExitCode, exit }, process::{ ExitCode, exit },
}; };
extern crate strerror;
extern crate sysexits; extern crate sysexits;
use strerror::StrError;
use sysexits::{ EX_DATAERR, EX_IOERR, EX_SOFTWARE }; use sysexits::{ EX_DATAERR, EX_IOERR, EX_SOFTWARE };
const LIST: [(u32, &str); 10] = [ const LIST: [(u32, &str); 10] = [
@@ -49,7 +51,7 @@ fn convert(input: u128) -> Result<(f64, (u32, &'static str)), String> {
let c = match 10_u128.checked_pow(n) { let c = match 10_u128.checked_pow(n) {
Some(c) => c, Some(c) => c,
None => { None => {
return Err(format!("10^{}: Integer overflow.", n.to_string())); return Err(format!("10^{}: Integer overflow", n.to_string()));
}, },
}; };
@@ -79,7 +81,7 @@ fn main() -> ExitCode {
f f
}, },
Err(err) => { Err(err) => {
eprintln!("{}: {}.", argv[0], err); eprintln!("{}: {}", argv[0], err);
return ExitCode::from(EX_DATAERR as u8); return ExitCode::from(EX_DATAERR as u8);
}, },
}; };
@@ -87,7 +89,7 @@ fn main() -> ExitCode {
let (number, prefix) = match convert(n) { let (number, prefix) = match convert(n) {
Ok(x) => x, Ok(x) => x,
Err(err) => { Err(err) => {
eprintln!("{}: {}.", argv[0], err); eprintln!("{}: {}", argv[0], err);
return ExitCode::from(EX_SOFTWARE as u8); return ExitCode::from(EX_SOFTWARE as u8);
}, },
}; };
@@ -98,7 +100,7 @@ fn main() -> ExitCode {
stdout().write_all(format!("{} {}\n", out, si_prefix).as_bytes()) stdout().write_all(format!("{} {}\n", out, si_prefix).as_bytes())
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
eprintln!("{}: {}.", argv[0], e); eprintln!("{}: {}", argv[0], e.strerror());
exit(EX_IOERR); exit(EX_IOERR);
}); });
} }

View File

@@ -172,7 +172,7 @@ fn eval(
}; };
} else { } else {
return Err(EvaluationError { return Err(EvaluationError {
message: format!("{}: Unexpected operation.", op), message: format!("{}: Unexpected operation", op),
code: EX_DATAERR, code: EX_DATAERR,
}) })
} }

31
src/strerror.rs Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
* SPDX-License-Identifier: FSFAP
*
* Copying and distribution of this file, with or without modification, are
* permitted in any medium without royalty provided the copyright notice and
* this notice are preserved. This file is offered as-is, without any warranty.
*/
use std::ffi::{ c_int, c_char, CStr };
pub trait StrError { fn strerror(&self) -> String; }
impl StrError for std::io::Error {
/* wrapper function for use in Rust */
fn strerror(&self) -> String {
/* Get the raw OS error. If its None, what the hell is going on‽ */
let errno = self.raw_os_error().unwrap_or(0) as c_int;
/* Get a CStr from the error message so that its referenced and then
* convert it to an owned value. If the string is not valid UTF-8,
* return that error instead. */
match unsafe { CStr::from_ptr(strerror(errno)) }.to_str() {
Ok(s) => s.to_owned(), // yay!! :D
Err(e) => e.to_string(), // awww :(
}
}
}
/* binding to strerror(3p) */
extern "C" { fn strerror(errnum: c_int) -> *mut c_char; }

10
src/test.rs Normal file
View File

@@ -0,0 +1,10 @@
extern crate strerror;
use strerror::raw_message;
fn main() {
stdout.write_all(b"meow\n").unwrap_or_else(|e| {
eprintln!("{}", raw_message(e));
std::process::exit(1);
});
}