- cross-posted to:
- fli@lemmy.ml
- cross-posted to:
- fli@lemmy.ml
Here is a simple program, that parses and prints 2 options: -n (w/o associated value) and -t (with numeric value) and an argument after options.
C
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int flags, opt; int nsecs, tfnd; nsecs = 0; tfnd = 0; flags = 0; while ((opt = getopt(argc, argv, "nt:")) != -1) { switch (opt) { case 'n': flags = 1; break; case 't': // converting string to integer nsecs = atoi(optarg); tfnd = 1; break; default: /* '?' */ exit(EXIT_FAILURE); } } printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\n", flags, tfnd, nsecs, optind); if (optind >= argc) { fprintf(stderr, "Expected argument after options\n"); exit(EXIT_FAILURE); } printf("name argument = %s\n", argv[optind]); exit(EXIT_SUCCESS); }and the same program in no_std rust
Rust
#![no_std] #![no_main] //use libc; // 0.2.186 #[cfg(not(test))] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { unsafe { libc::abort() } } unsafe extern "C" { static mut optarg: *mut libc::c_char; static mut optind: i32; } #[unsafe(no_mangle)] extern "C" fn main(argc: i32, argv: *const *mut libc::c_char) { let (mut nsecs, mut tfnd, mut flags) = (0, 0, 0); loop { let opt = unsafe { libc::getopt(argc, argv, c"nt:".as_ptr()) }; if opt == -1 { break; } match opt as u8 { b'n' => { flags = 1; } b't' => { nsecs = unsafe { libc::atoi(optarg) }; tfnd = 1; } _ => unsafe { libc::exit(libc::EXIT_FAILURE) }, } } unsafe { libc::printf( c"flags=%d; tfnd=%d; nsecs=%d; optind=%d\n".as_ptr(), flags, tfnd, nsecs, optind, ); } unsafe { if optind >= argc { libc::printf(c"Expected argument after options\n".as_ptr()); libc::exit(libc::EXIT_FAILURE) } libc::printf(c"name argument = %s\n".as_ptr(), *argv.add(optind as usize)); } unsafe { libc::exit(libc::EXIT_SUCCESS) } }Important notice: it is not some dismiss of rust, it is just a factual state. MacOS for example pushes you to use libc, since their syscalls ABI is not stable. So there is no way to avoid it
You must log in or register to comment.
getopt is not a syscall and you don’t need it to parse command line arguments.
So you wrote some awful, unmaintainable code. Then what ?

