Parser for argv that works similarly to getopt

Related tags

Utilities c getopt
Overview

Build Status codecov.io

About

Most command-line programs have to parse options, so there are a lot of different solutions to this problem. Some offer many features, while others are more basic.

One of the simpler solutions for C is the getopt function, and its extension getopt_long. They iterate over the options in argv, returning them one at a time on successive calls.

One nice thing about them is that they are available on most Unix-like operating systems (and usually accompany GCC elsewhere, like Windows). Unfortunately, some implementation details vary between platforms.

A potential question is what license the version you get when you include them is available under. Some are GPL, others LGPL. There are also ports of getopt that use more liberal licenses.

parg is a parser for argv that works similarly to getopt, but does not aim to be a direct replacement. It attempts to make some choices about how to handle the extensions and idiosyncrasies of other getopt implementations, and document them.

It consists of a single source and include file, written in portable ANSI C. It is made available under CC0.

Usage

The include file parg.h contains documentation in the form of doxygen comments. A configuration file is included, so you can simply run doxygen to generate documentation in HTML format.

parg uses CMake to generate build systems. To create one for the tools on your platform, and build parg, use something along the lines of:

mkdir build
cd build
cmake ..
cmake --build .

You can also simply compile the source files and link them into your project. CMake just provides an easy way to build and test across various platforms and toolsets.

Example

Here is an example that parses command-line options using parg_getopt():

#include <stdio.h>
#include <stdlib.h>

#include "parg.h"

int main(int argc, char *argv[])
{
	struct parg_state ps;
	int c;

	parg_init(&ps);

	while ((c = parg_getopt(&ps, argc, argv, "hs:v")) != -1) {
		switch (c) {
		case 1:
			printf("nonoption '%s'\n", ps.optarg);
			break;
		case 'h':
			printf("Usage: testparg [-h] [-v] [-s STRING]\n");
			return EXIT_SUCCESS;
			break;
		case 's':
			printf("option -s with argument '%s'\n", ps.optarg);
			break;
		case 'v':
			printf("testparg 1.0.0\n");
			return EXIT_SUCCESS;
			break;
		case '?':
			if (ps.optopt == 's') {
				printf("option -s requires an argument\n");
			}
			else {
				printf("unknown option -%c\n", ps.optopt);
			}
			return EXIT_FAILURE;
			break;
		default:
			printf("error: unhandled option -%c\n", c);
			return EXIT_FAILURE;
			break;
		}
	}

	for (c = ps.optind; c < argc; ++c) {
		printf("nonoption '%s'\n", argv[c]);
	}

	return EXIT_SUCCESS;
}

Comparison to getopt

Use of global variables

getopt uses global variables to store its state between calls. parg uses a struct parg_state, which you must pass with each call.

Handling of nonoptions

POSIX and BSD getopt return -1 on the first nonoption argument. GNU getopt by default reorders argv (even though it is passed as const), so all options come first.

parg does not change argv, and returns each nonoption as the option argument of an option with value 1 (like GNU getopt, if optstring were prefixed by '-').

If you wish to process all options first, and have the nonoptions ordered at the end of argv, you can use parg_reorder():

	optend = parg_reorder(argc, argv, optstring, NULL);

	while ((c = parg_getopt(&ps, optend, argv, optstring)) != -1) {
		/* ... */
	}

	/* elements of argv[] from optend to argc are nonoptions */

Value of optind on error

When there are multiple short options in one argument, getopt does not increment optind until the last one is processed. This makes it harder to tell which argument an unknown option came from (if a is an unknown option, -a and -ab will return '?' with different values in optind).

parg always increments the optind value in it's state so it points to the next argv element to be processed. So when parg returns '?' (or ':'), the element that contains the error is argv[optind - 1].

Value of optopt on error

With getopt_long, it varies what the values of optopt and longindex are when an error is found with option arguments of long options. Sometimes these values are not documented.

parg sets optopt to val if flag is NULL, and 0 otherwise (which equals the return value on successful match), and longindex is set to the index of the entry in longopts that matched.

Return value on option argument error

When the first character of optstring is ':', it varies what getopt returns on extraneous option arguments.

In this case, parg returns '?' if no option match is found, and ':' if a match is found, but is missing a required argument, or has an extraneous argument.

Alternatives

Some ports of getopt:

Other command-line parsing libraries that support C:

A few C++ command-line parsing libraries:

You might also like...
A markdown parser for tree-sitter

tree-sitter-markdown A markdown parser for tree-sitter Progress: Leaf blocks Thematic breaks ATX headings Setext headings Indented code blocks Fenced

A TreeSitter parser for the Neorg File Format

NFF TreeSitter Parser A TreeSitter grammar for Neorg. Available Commands Command Result yarn installs needed dependencies (only do if you don't have t

BLLIP reranking parser (also known as Charniak-Johnson parser, Charniak parser, Brown reranking parser) See http://pypi.python.org/pypi/bllipparser/ for Python module.

BLLIP Reranking Parser Copyright Mark Johnson, Eugene Charniak, 24th November 2005 --- August 2006 We request acknowledgement in any publications that

BLLIP reranking parser (also known as Charniak-Johnson parser, Charniak parser, Brown reranking parser)
BLLIP reranking parser (also known as Charniak-Johnson parser, Charniak parser, Brown reranking parser)

BLLIP reranking parser (also known as Charniak-Johnson parser, Charniak parser, Brown reranking parser)

Small Header only library to parse argv for flags

Small Header only library to parse argv for flags

C++ getopt wrapper to make it easier to parse command line arguments

Options is a simple C++ wrapper for getopt that makes it easier to handle command line argument parsing in C++. See demo.cc and the Makefile for an e

Fix some extrinsic parameter importing problems. 6-axis IMU works now. Lidar without ring works now.

LVI-SAM-MODIFIED This repository is a modified version of LVI-SAM. Modification Add function to get extrinsic parameters.The original code assumes the

tiny HTTP parser written in C (used in HTTP::Parser::XS et al.)
tiny HTTP parser written in C (used in HTTP::Parser::XS et al.)

PicoHTTPParser Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, Shigeo Mitsunari PicoHTTPParser is a tiny, primitive, fast HTTP r

Fast C/C++ CSS Parser (Cascading Style Sheets Parser)

MyCSS — a pure C CSS parser MyCSS is a fast CSS Parser implemented as a pure C99 library with the ability to build without dependencies. Mailing List:

udmp-parser: A Windows user minidump C++ parser library.
udmp-parser: A Windows user minidump C++ parser library.

udmp-parser: A Windows user minidump C++ parser library. This is a cross-platform (Windows / Linux / OSX / x86 / x64) C++ library that parses Windows

Simple C++ 20 Serialization Library that works out of the box with aggregate types!

BinaryLove3 Simple C++ 20 Serialization Library that works out of the box with aggregate types! Requirements BinaryLove3 is a c++20 only library.

Advanced keylogger written in C++ , works on all windows versions use it at your own risk !
Advanced keylogger written in C++ , works on all windows versions use it at your own risk !

About Keylogger Keyloggers or keystroke loggers are software programs or hardware devices that track the activities (keys pressed) of a keyboard. Key

An extremely hacky VNC server for WebOS - Works by reading directly from the GPU's framebuffer.
An extremely hacky VNC server for WebOS - Works by reading directly from the GPU's framebuffer.

webos-vncserver An extremely hacky VNC server for WebOS - Works by reading directly from the GPU's framebuffer. Requires root privileges.

Add virtual monitors to your windows 10 device! Works with Oculus software, obs, and any desktop sharing software

License MIT and CC0 or Public Domain, whichever is least restrictive -- Use it AS IS - NO IMPLICIT OR EXPLICIT warranty This may break your computer,

RetroWave is a hardware sound board series that uses vintage sound chips and works with modern hardware.
RetroWave is a hardware sound board series that uses vintage sound chips and works with modern hardware.

RetroWave Authentic sounds from vintage sound chips, on modern hardware! Introduction RetroWave is a hardware sound board series that uses vintage sou

Tutorials on how the UEFI works
Tutorials on how the UEFI works

Step by Step Tutorials on how to use the UEFI for OS Development from scratch THIS IS WINDOWS BASED TUTS, BUT CODE SHOULD WORK IN LINUX AND MAC. NOTE

This repository is to explain how the SN74HC595 register works
This repository is to explain how the SN74HC595 register works

Register_SN74HC595 This repository is to explain how the SN74HC595 register works Aujourd’hui on va apprendre à comment augmenter le nombre de sortie

Serialization framework for Unreal Engine Property System that just works!

DataConfig Serialization framework for Unreal Engine Property System that just works! Unreal Engine features a powerful Property System which implemen

Obfuscate calls to imports by patching in stubs. ICO works on both X86 and X64 binaries.
Obfuscate calls to imports by patching in stubs. ICO works on both X86 and X64 binaries.

ICO adds a new section into the image, then begins building stubs for each import that uses a extremely basic routine to decrypt an RVA and places them into the section.

Comments
  • Memory usage of parg_reorder

    Memory usage of parg_reorder

    The current implementation of parg_reorder allocates a temporary array the same size as argv. This could be an issue if parg were used on embedded systems.

    I am currently testing an in-place version.

    opened by jibsen 1
  • Reordering issue when last element is missing option argument

    Reordering issue when last element is missing option argument

    When the last element is an option that requires an option argument, but there is none, then calling parg_reorder may result in that element being moved to a place where another element is wrongly used as option argument for it.

    An example would be passing foo -r as arguments, where -r requires an option argument. parg_reorder will reorder these into -r foo, and parg_getopt will use foo as option argument for -r.

    opened by jibsen 1
  • Choose a better license

    Choose a better license

    Currently, the CC0 license is NOT recommended by the Open Source Initiative due to a clause that could "possibly even weaken patent infringement defenses available to users of software released under CC0." For this reason I highly recommend that a switch to a public domain equivalent license such as the Zero-Clause BSD license be made.

    opened by wmcgonagle 4
Owner
Jørgen Ibsen
Jørgen Ibsen
tiny recursive descent expression parser, compiler, and evaluation engine for math expressions

TinyExpr TinyExpr is a very small recursive descent parser and evaluation engine for math expressions. It's handy when you want to add the ability to

Lewis Van Winkle 1.2k Dec 30, 2022
Simple .INI file parser in C, good for embedded systems

inih (INI Not Invented Here) inih (INI Not Invented Here) is a simple .INI file parser written in C. It's only a couple of pages of code, and it was d

Ben Hoyt 1.9k Jan 2, 2023
ini file parser

Iniparser 4 I - Overview This modules offers parsing of ini files from the C level. See a complete documentation in HTML format, from this directory o

Nicolas D 845 Jan 1, 2023
Small configuration file parser library for C.

libConfuse Introduction Documentation Examples Build & Install Origin & References Introduction libConfuse is a configuration file parser library writ

null 419 Dec 14, 2022
Universal configuration library parser

LIBUCL Table of Contents generated with DocToc Introduction Basic structure Improvements to the json notation General syntax sugar Automatic arrays cr

Vsevolod Stakhov 1.5k Dec 28, 2022
MiniCalculator with a simple parser.

MiniCalculator with a simple parser. This is a homework-expanded project. To learn something about parser and basic theory of programmi

GZTime 8 Oct 9, 2021
Simple and lightweight pathname parser for C. This module helps to parse dirname, basename, filename and file extension .

Path Module For C File name and extension parsing functionality are removed because it's difficult to distinguish between a hidden dir (ex: .git) and

Prajwal Chapagain 3 Feb 25, 2022
Very fast Markdown parser and HTML generator implemented in WebAssembly, based on md4c

Very fast Markdown parser and HTML generator implemented in WebAssembly, based on md4c

Rasmus 1.3k Dec 24, 2022
A simple YAML parser which produces a Node Tree Object representation of YAML Documents

A simple YAML parser which produces a Node Tree Object representation of YAML Documents and includes a find method to locate individual Nodes within the parsed Node Tree.

Timothy Rule 2 Sep 18, 2022
A PE parser written as an exercise to study the PE file structure.

Description A PE parser written as an exercise to study the PE file structure. It parses the following parts of PE32 and PE32+ files: DOS Header Rich

Ahmed Hesham 22 Nov 18, 2022