forked from bonsai/harakit
		
	Merge branch 'main' into sleep
This commit is contained in:
		
						commit
						81c657ec3e
					
				
							
								
								
									
										79
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,6 +1,7 @@ | ||||
| # Copyright (c) 2023–2024 Emma Tebibyte <emma@tebibyte.media>
 | ||||
| # Copyright (c) 2023–2024 DTB <trinity@trinity.moe>
 | ||||
| # Copyright (c) 2023 Sasha Koshka <sashakoshka@tebibyte.media>
 | ||||
| # Copyright (c) 2024 Aaditya Aryal <aryalaadi123@gmail.com>
 | ||||
| # SPDX-License-Identifier: FSFAP
 | ||||
| #
 | ||||
| # Copying and distribution of this file, with or without modification, are
 | ||||
| @ -8,16 +9,26 @@ | ||||
| # notice are preserved.  This file is offered as-is, without any warranty.
 | ||||
| 
 | ||||
| .POSIX: | ||||
| 
 | ||||
| # if using BSD make(1), remove these pragmas because they break it
 | ||||
| .PRAGMA: posix_202x # future POSIX standard support à la pdpmake(1)
 | ||||
| .PRAGMA: command_comment # breaks without this?
 | ||||
| 
 | ||||
| PREFIX=/usr/local | ||||
| DESTDIR ?= dist | ||||
| PREFIX ?= /usr/local | ||||
| 
 | ||||
| CC=cc | ||||
| RUSTC=rustc | ||||
| SYSEXITS != printf '\043include <sysexits.h>\n' | cpp -M - | sed 's/ /\n/g' \
 | ||||
| 	| 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 | ||||
| all: dj false fop hru intcmp mm rpn scrut str strcmp swab true | ||||
| all: dj false fop hru intcmp mm npc rpn scrut str strcmp swab true | ||||
| 
 | ||||
| build: | ||||
| 	# keep build/include until bindgen(1) has stdin support | ||||
| @ -26,36 +37,40 @@ build: | ||||
| 
 | ||||
| .PHONY: clean | ||||
| clean: | ||||
| 	rm -rf build/ dist/ | ||||
| 	rm -rf build dist | ||||
| 
 | ||||
| dist: all | ||||
| 	mkdir -p dist/bin dist/share/man/man1 | ||||
| 	cp build/bin/* dist/bin/ | ||||
| 	cp docs/*.1 dist/share/man/man1/ | ||||
| 	mkdir -p $(DESTDIR)/$(PREFIX)/bin $(DESTDIR)/$(PREFIX)/share/man/man1 | ||||
| 	cp build/bin/* $(DESTDIR)/$(PREFIX)/bin | ||||
| 	cp docs/*.1 $(DESTDIR)/$(PREFIX)/share/man/man1 | ||||
| 
 | ||||
| .PHONY: install | ||||
| install: dist | ||||
| 	mkdir -p $(PREFIX) | ||||
| 	cp -r dist/* $(PREFIX)/ | ||||
| 	cp -r $(DESTDIR)/* / | ||||
| 
 | ||||
| .PHONY: test | ||||
| test: build | ||||
| 	tests/posix-compat.sh | ||||
| 	$(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 | ||||
| 	printf '#define EXIT_FAILURE 1\n' | cat - include/sysexits.h \
 | ||||
| 	printf '#define EXIT_FAILURE 1\n' | cat - $(SYSEXITS)sysexits.h \
 | ||||
| 		> build/include/sysexits.h  | ||||
| 	bindgen --default-macro-constant-type signed --use-core --formatter=none \
 | ||||
| 		"$$(printf '#include <sysexits.h>\n' \
 | ||||
| 			| 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 | ||||
| 		build/include/sysexits.h | $(RUSTC) $(RUSTFLAGS) --crate-type lib -o $@ - | ||||
| 
 | ||||
| .PHONY: dj | ||||
| dj: build/bin/dj | ||||
| @ -69,17 +84,13 @@ build/bin/false: src/false.c build | ||||
| 
 | ||||
| .PHONY: fop | ||||
| fop: build/bin/fop | ||||
| build/bin/fop: src/fop.rs build build/o/libgetopt.rlib build/o/libsysexits.rlib | ||||
| 	$(RUSTC) $(RUSTFLAGS) --extern getopt=build/o/libgetopt.rlib \
 | ||||
| 		--extern sysexits=build/o/libsysexits.rlib \
 | ||||
| 		-o $@ src/fop.rs | ||||
| build/bin/fop: src/fop.rs build rustlibs | ||||
| 	$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/fop.rs | ||||
| 
 | ||||
| .PHONY: hru | ||||
| hru: build/bin/hru | ||||
| build/bin/hru: src/hru.rs build build/o/libgetopt.rlib build/o/libsysexits.rlib | ||||
| 	$(RUSTC) $(RUSTFLAGS) --extern getopt=build/o/libgetopt.rlib \
 | ||||
| 		--extern sysexits=build/o/libsysexits.rlib \
 | ||||
| 		-o $@ src/hru.rs | ||||
| build/bin/hru: src/hru.rs build rustlibs  | ||||
| 	$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/hru.rs | ||||
| 
 | ||||
| .PHONY: intcmp | ||||
| intcmp: build/bin/intcmp | ||||
| @ -91,12 +102,16 @@ mm: build/bin/mm | ||||
| build/bin/mm: src/mm.c build | ||||
| 	$(CC) $(CFLAGS) -o $@ src/mm.c | ||||
| 
 | ||||
| 
 | ||||
| .PHONY: npc | ||||
| npc: build/bin/npc | ||||
| build/bin/npc: src/npc.c build | ||||
| 	$(CC) $(CFLAGAS) -o $@ src/npc.c | ||||
| 
 | ||||
| .PHONY: rpn | ||||
| rpn: build/bin/rpn | ||||
| build/bin/rpn: src/rpn.rs build build/o/libsysexits.rlib | ||||
| 	$(RUSTC) $(RUSTFLAGS) \
 | ||||
| 		--extern sysexits=build/o/libsysexits.rlib \
 | ||||
| 		-o $@ src/rpn.rs | ||||
| build/bin/rpn: src/rpn.rs build rustlibs | ||||
| 	$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/rpn.rs | ||||
| 
 | ||||
| .PHONY: scrut | ||||
| scrut: build/bin/scrut | ||||
|  | ||||
							
								
								
									
										18
									
								
								src/fop.rs
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/fop.rs
									
									
									
									
									
								
							| @ -22,10 +22,12 @@ use std::{ | ||||
| 	process::{ Command, exit, Stdio }, | ||||
| }; | ||||
| 
 | ||||
| extern crate sysexits; | ||||
| extern crate getopt; | ||||
| extern crate strerror; | ||||
| extern crate sysexits; | ||||
| 
 | ||||
| use getopt::{ Opt, Parser }; | ||||
| use strerror::StrError; | ||||
| use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; | ||||
| 
 | ||||
| fn main() { | ||||
| @ -55,7 +57,7 @@ fn main() { | ||||
| 	}); | ||||
| 
 | ||||
| 	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); | ||||
| 	}); | ||||
| 
 | ||||
| @ -75,13 +77,13 @@ fn main() { | ||||
| 		.stdout(Stdio::piped()) | ||||
| 		.spawn() | ||||
| 		.unwrap_or_else( |e| { | ||||
| 			eprintln!("{}: {}: {}.", argv[0], argv[command_arg], e); | ||||
| 			eprintln!("{}: {}: {}", argv[0], argv[command_arg], e.strerror()); | ||||
| 			exit(EX_UNAVAILABLE); | ||||
| 		}); | ||||
| 
 | ||||
| 	let field = fields.get(index).unwrap_or_else(|| { | ||||
| 		eprintln!( | ||||
| 			"{}: {}: No such index in input.", | ||||
| 			"{}: {}: No such index in input", | ||||
| 			argv[0], | ||||
| 			index.to_string(), | ||||
| 		); | ||||
| @ -94,7 +96,7 @@ fn main() { | ||||
| 	} | ||||
| 
 | ||||
| 	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); | ||||
| 	}); | ||||
| 
 | ||||
| @ -103,7 +105,7 @@ fn main() { | ||||
| 	if replace.pop() != Some(b'\n') { replace = output.stdout; } | ||||
| 
 | ||||
| 	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); | ||||
| 	}); | ||||
| 
 | ||||
| @ -111,8 +113,8 @@ fn main() { | ||||
| 
 | ||||
| 	stdout().write_all( | ||||
| 		fields.join(&d.to_string()).as_bytes() | ||||
| 	).unwrap_or_else(|e|{ | ||||
| 		eprintln!("{}: {}.", argv[0], e); | ||||
| 	).unwrap_or_else(|e| { | ||||
| 		eprintln!("{}: {}", argv[0], e.strerror()); | ||||
| 		exit(EX_IOERR); | ||||
| 	}); | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								src/hru.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/hru.rs
									
									
									
									
									
								
							| @ -23,8 +23,10 @@ use std::{ | ||||
| 	process::{ ExitCode, exit }, | ||||
| }; | ||||
| 
 | ||||
| extern crate strerror; | ||||
| extern crate sysexits; | ||||
| 
 | ||||
| use strerror::StrError; | ||||
| use sysexits::{ EX_DATAERR, EX_IOERR, EX_SOFTWARE }; | ||||
| 
 | ||||
| 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) { | ||||
| 			Some(c) => c, | ||||
| 			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 | ||||
| 			}, | ||||
| 			Err(err) => { | ||||
| 				eprintln!("{}: {}.", argv[0], err); | ||||
| 				eprintln!("{}: {}", argv[0], err); | ||||
| 				return ExitCode::from(EX_DATAERR as u8); | ||||
| 			}, | ||||
| 		}; | ||||
| @ -87,7 +89,7 @@ fn main() -> ExitCode { | ||||
| 		let (number, prefix) = match convert(n) { | ||||
| 			Ok(x) => x, | ||||
| 			Err(err) => { | ||||
| 				eprintln!("{}: {}.", argv[0], err); | ||||
| 				eprintln!("{}: {}", argv[0], err); | ||||
| 				return ExitCode::from(EX_SOFTWARE as u8); | ||||
| 			}, | ||||
| 		}; | ||||
| @ -98,7 +100,7 @@ fn main() -> ExitCode { | ||||
| 
 | ||||
| 		stdout().write_all(format!("{} {}\n", out, si_prefix).as_bytes()) | ||||
| 			.unwrap_or_else(|e| { | ||||
| 				eprintln!("{}: {}.", argv[0], e); | ||||
| 				eprintln!("{}: {}", argv[0], e.strerror()); | ||||
| 				exit(EX_IOERR); | ||||
| 			}); | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										18
									
								
								src/mm.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/mm.c
									
									
									
									
									
								
							| @ -106,6 +106,15 @@ oserr(char *s, char *r){ | ||||
| 	} \ | ||||
| 	return retval | ||||
| 
 | ||||
| /* Prints a usage text, in which s is the program being run (i.e. argv[0]), and
 | ||||
|  * returns an exit status appropriate for a usage error. */ | ||||
| int usage(char *s){ | ||||
| 
 | ||||
| 	fprintf(stderr, "Usage: %s (-aenu) (-i [input])... (-o [output])...\n", s); | ||||
| 
 | ||||
| 	return EX_USAGE; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]){ | ||||
| 	int c; | ||||
| 	struct Files files[2]; /* {read, write} */ | ||||
| @ -178,12 +187,15 @@ int main(int argc, char *argv[]){ | ||||
| 				k = 1; | ||||
| 				break; | ||||
| 			default: | ||||
| 				fprintf(stderr, "Usage: %s (-aenu) (-i [input])..." | ||||
| 					" (-o [output])...\n", argv[0]); | ||||
| 				retval = EX_USAGE; | ||||
| 				retval = usage(argv[0]); | ||||
| 				terminate; | ||||
| 			} | ||||
| 
 | ||||
| 	if(optind != argc){ | ||||
| 		retval = usage(argv[0]); | ||||
| 		terminate; | ||||
| 	} | ||||
| 
 | ||||
| 	files[0].s += files[0].s == 0; | ||||
| 	files[1].s += files[1].s == 0; | ||||
| 	 | ||||
|  | ||||
| @ -172,7 +172,7 @@ fn eval( | ||||
| 					}; | ||||
| 				} else { | ||||
| 					return Err(EvaluationError { | ||||
| 						message: format!("{}: Unexpected operation.", op), | ||||
| 						message: format!("{}: Unexpected operation", op), | ||||
| 						code: EX_DATAERR, | ||||
| 					}) | ||||
| 				} | ||||
|  | ||||
							
								
								
									
										15
									
								
								src/scrut.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/scrut.c
									
									
									
									
									
								
							| @ -1,5 +1,6 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2023 DTB <trinity@trinity.moe> | ||||
|  * Copyright (c) 2023–2024 DTB <trinity@trinity.moe> | ||||
|  * Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media> | ||||
|  * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify it under | ||||
| @ -17,13 +18,15 @@ | ||||
|  */ | ||||
| 
 | ||||
| #include <stdio.h> /* fprintf(3), stderr, NULL */ | ||||
| #include <stdlib.h> /* EXIT_FAILURE */ | ||||
| #include <stdlib.h> /* EXIT_FAILURE, EXIT_SUCCESS */ | ||||
| #include <string.h> /* memset(3), strchr(3) */ | ||||
| #ifndef EX_USAGE | ||||
| #	include <sysexits.h> | ||||
| #endif | ||||
| #include <unistd.h> /* access(3), getopt(3), F_OK, R_OK, W_OK, X_OK */ | ||||
| #include <sys/stat.h> /* lstat(3), stat struct, S_ISBLK, S_ISCHR, S_ISDIR, | ||||
|                        * S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK, | ||||
|                        * S_ISUID, S_ISVTX */ | ||||
| #include <sysexits.h> | ||||
| 
 | ||||
| static char args[] = "bcdefghkprsuwxLS"; | ||||
| static char ops[(sizeof args) / (sizeof *args)]; | ||||
| @ -57,7 +60,7 @@ int main(int argc, char *argv[]){ | ||||
| 
 | ||||
| 	argv += optind; | ||||
| 	do{	if(access(*argv, F_OK) != 0 || lstat(*argv, &buf) == -1) | ||||
| 			return 1; /* doesn't exist or isn't stattable */ | ||||
| 			return EXIT_FAILURE; /* doesn't exist or isn't stattable */ | ||||
| 
 | ||||
| 		for(i = 0; ops[i] != '\0'; ++i) | ||||
| 			if(ops[i] == 'e') | ||||
| @ -97,8 +100,8 @@ usage:				fprintf(stderr, "Usage: %s (-%s) [file...]\n", | ||||
| 						&& !S_ISLNK(buf.st_mode)) | ||||
| 					|| (ops[i] == 'S' | ||||
| 						&& !S_ISSOCK(buf.st_mode))) | ||||
| 				return 1; | ||||
| 				return EXIT_FAILURE; | ||||
| 	}while(*++argv != NULL); | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return EXIT_SUCCESS; | ||||
| } | ||||
|  | ||||
							
								
								
									
										31
									
								
								src/strerror.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/strerror.rs
									
									
									
									
									
										Normal 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 it’s 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 it’s 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
									
								
							
							
						
						
									
										10
									
								
								src/test.rs
									
									
									
									
									
										Normal 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); | ||||
| 	}); | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user