Skip to main content

Crate getopt_iter

Crate getopt_iter 

Source
Expand description

A POSIX-compliant command-line option parser with GNU extensions.

This library provides an iterator-based interface for parsing command-line options in both std and no_std environments.

§Examples

§Basic Usage with std

use getopt_iter::Getopt;

let args = vec!["myapp", "-a", "-b", "value", "file.txt"];
let mut getopt = Getopt::new(args.iter().copied(), "ab:");

while let Some(opt) = getopt.next() {
    match opt.val() {
        'a' => println!("Option a"),
        'b' => println!("Option b with arg: {}", opt.arg().unwrap()),
        '?' => eprintln!("Unknown option: {:?}", opt.erropt()),
        _ => {}
    }
}

// Process remaining positional arguments
for arg in getopt.remaining() {
    println!("File: {}", arg);
}

§no_std Usage with C FFI (argc/argv)

For bare-metal or embedded environments where you receive C-style argc and argv parameters, you can wrap them in an iterator that yields &core::ffi::CStr:

#![no_std]
#![no_main]

extern crate alloc;
use core::ffi::CStr;
use core::slice;
use getopt_iter::Getopt;

/// Iterator that wraps raw C argc/argv pointers
struct ArgvIter {
    argv: *const *const i8,
    current: isize,
    end: isize,
}

impl ArgvIter {
    unsafe fn new(argc: i32, argv: *const *const i8) -> Self {
        Self {
            argv,
            current: 0,
            end: argc as isize,
        }
    }
}

impl Iterator for ArgvIter {
    type Item = &'static CStr;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current >= self.end {
            return None;
        }
         
        unsafe {
            let arg_ptr = *self.argv.offset(self.current);
            self.current += 1;
             
            if arg_ptr.is_null() {
                None
            } else {
                Some(CStr::from_ptr(arg_ptr))
            }
        }
    }
}

#[unsafe(no_mangle)]
pub extern "C" fn main(argc: i32, argv: *const *const i8) -> i32 {
    // Wrap the raw pointers in our iterator
    let args = unsafe { ArgvIter::new(argc, argv) };
     
    // Parse options using getopt
    let mut getopt = Getopt::new(args, "hvf:");
    getopt.set_opterr(false); // Suppress error messages in no_std environment
     
    let mut verbose = false;
    let mut filename = None;
     
    while let Some(opt) = getopt.next() {
        match opt.val() {
            'h' => {
                // Print help
                return 0;
            }
            'v' => verbose = true,
            'f' => filename = opt.into_arg(),
            '?' => return 1, // Unknown option
            ':' => return 1, // Missing argument
            _ => {}
        }
    }
     
    // Process remaining arguments
    for arg in getopt.remaining() {
        // Process positional argument (arg is &CStr)
        // Note: In no_std, you cannot print to stdout/stderr
        // without custom panic/print handlers
    }
     
    0
}

The ArgvIter adapter safely wraps the raw C pointers and yields &CStr references, which are automatically converted to String by the ArgV trait implementation. This allows seamless integration with C environments while maintaining memory safety within the iterator abstraction.

Structs§

Getopt
State management for getopt parsing
Opt
Represents the result of parsing a single command-line option.

Traits§

ArgV
Trait for types that can be converted into strings for use as command-line arguments.