libutil

C Utility Library
git clone http://git.omkov.net/libutil
Log | Tree | Refs | README | LICENCE | Download

libutil/src/test/test_optget.c (183 lines, 4.9 KiB) -rw-r--r-- blame download

0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
// test_optget.c
// optget unit test for libutil
// Copyright (C) 2020, Jakob Wakeling
// MIT Licence

#include "../optget.h"
#include "unit.h"

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#define SEQ(s1, s2) (strcmp(s1, s2) == 0)

int main(void) {
	struct opt opt;
	
	{
		char *av[] = { "G00", "-a", "-bfoo", "-c", "bar", "--", "baz", NULL };
		
		opt = OPTGET_INIT; opt.str = ":ab:c:";
		ASSERT("G00T00 option",
				optget(&opt, av, 1) == 'a');
		ASSERT("G00T01 option with shared argument",
				optget(&opt, av, 1) == 'b');
		ASSERT("G00T02 optarg shared argument",
				opt.arg == av[2] + 2);
		ASSERT("G00T03 option with seperate argument",
				optget(&opt, av, 1) == 'c');
		ASSERT("G00T04 optarg seperate argument",
				opt.arg == av[4]);
		ASSERT("G00T05 options end",
				optget(&opt, av, 1) == -1);
		ASSERT("G00T06 operand",
				SEQ(av[opt.ind], "baz"));
	}
	
	{
		char *av[] = { "G01", "-abcfoo", "bar", NULL };
		
		opt = OPTGET_INIT; opt.str = ":abc:";
		ASSERT("G01T00 option",
				optget(&opt, av, 1) == 'a');
		ASSERT("G01T01 option",
				optget(&opt, av, 1) == 'b');
		ASSERT("G01T02 option with shared argument",
				optget(&opt, av, 1) == 'c');
		ASSERT("G01T03 optarg shared argument",
				opt.arg == av[1] + 4);
		ASSERT("G01T04 options end",
				optget(&opt, av, 1) == -1);
		ASSERT("G01T05 optind at end",
				opt.ind == 2);
		ASSERT("G01T06 optarg after end",
				opt.arg == av[1] + 4);
		ASSERT("G01T07 options still end",
				optget(&opt, av, 1) == -1);
		ASSERT("G01T08 optind still at end",
				opt.ind == 2);
		ASSERT("G01T09 operand",
				SEQ(av[opt.ind], "bar"));
	}
	
	{
		char *av[] = { "G02", "-aa", "-b", NULL };
		
		opt = OPTGET_INIT; opt.str = ":b:";
		ASSERT("G02T00 invalid option",
				optget(&opt, av, 1) == '?');
		ASSERT("G02T01 optopt",
				opt.opt == 'a');
		ASSERT("G02T00 invalid option again",
				optget(&opt, av, 1) == '?');
		ASSERT("G02T01 optopt",
				opt.opt == 'a');
		ASSERT("G02T02 missing option argument",
				optget(&opt, av, 1) == ':');
		ASSERT("G02T03 optopt",
				opt.opt == 'b');
	}
	
	{
		char *av[] = { "G03", "foo", "-a", "bar", "-b", "baz", NULL };
		int argc = (sizeof (av) / sizeof (*av) - 1);
		
		opt = OPTGET_INIT; opt.str = ":ab:";
		ASSERT("G03T00 option",
				optget(&opt, av, 1) == 'a');
		ASSERT("G03T01 option with seperate argument",
				optget(&opt, av, 1) == 'b');
		ASSERT("G03T02 optarg seperate argument",
				SEQ(opt.arg, "baz"));
		ASSERT("G03T03 options end",
				optget(&opt, av, 1) == -1);
		ASSERT("G03T04 optind at end",
				opt.ind == 4);
		ASSERT("G03T05 options still end",
				optget(&opt, av, 1) == -1);
		ASSERT("G03T06 optind still at end",
				opt.ind == 4);
		ASSERT("G03T07 permuted operand",
				SEQ(av[opt.ind], "foo")); ++opt.ind;
		ASSERT("G03T08 permuted operand",
				SEQ(av[opt.ind], "bar")); ++opt.ind;
		ASSERT("G03T09 permuted operands end",
				opt.ind >= argc);
	}
	
	{
		char *av[] = { "G04", "--foo", "--bar=arg", "--bar", "argument",
			"--baz", NULL };
		
		struct lop lops[] = {
			{ "foo", ARG_NUL, 256 },
			{ "bar", ARG_REQ, 257 },
			{ "baz", ARG_OPT, 258 },
			{ NULL, 0, 0 }
		};
		
		opt = OPTGET_INIT; opt.str = ":"; opt.lops = lops;
		ASSERT("G04T00 long option",
				optget(&opt, av, 1) == 256);
		ASSERT("G04T01 long option with shared argument",
				optget(&opt, av, 1) == 257);
		ASSERT("G04T02 optarg shared argument",
				SEQ(opt.arg, "arg"));
		ASSERT("G04T03 long option with seperate argument",
				optget(&opt, av, 1) == 257);
		ASSERT("G04T04 optarg seperate argument",
				SEQ(opt.arg, "argument"));
		ASSERT("G04T05 long option without argument",
				optget(&opt, av, 1) == 258);
		ASSERT("G04T06 optarg seperate argument",
				opt.arg == NULL);
	}
	
	{
		char *av[] = { "G05", "foo", "--bar", "--", "baz", NULL };
		int argc = (sizeof (av) / sizeof (*av) - 1);
		
		struct lop lops[] = {
			{ "bar", ARG_NUL, 256 },
			{ NULL, 0, 0 }
		};
		
		opt = OPTGET_INIT; opt.str = ":"; opt.lops = lops;
		ASSERT("G05T00 long option",
				optget(&opt, av, 1) == 256);
		ASSERT("G05T01 options end",
				optget(&opt, av, 1) == -1);
		ASSERT("G05T02 permuted operand",
				SEQ(av[opt.ind], "foo")); ++opt.ind;
		ASSERT("G05T03 permuted operand",
				SEQ(av[opt.ind], "baz")); ++opt.ind;
		ASSERT("G05T04 permuted operands end",
				opt.ind >= argc);
		ASSERT("G05T05 options still end",
				optget(&opt, av, 1) == -1);
		ASSERT("G05T06 permutes operands still end",
				opt.ind >= argc);
		
	}
	
	{
		char *av[] = { "G06", "--foo", "bar", "-a", NULL };
		
		opt = OPTGET_INIT; opt.str = ":a";
		ASSERT("G06T00 invalid option with NULL lopts",
				optget(&opt, av, 0) == '?');
		ASSERT("G06T01 options end without permute",
				optget(&opt, av, 0) == -1);
		ASSERT("G06T02 unpermuted operand",
				SEQ(av[opt.ind], "bar"));
		ASSERT("G06T03 still no permute",
				optget(&opt, av, 0) == -1);
		ASSERT("G06T04 still unpermuted operand",
				SEQ(av[opt.ind], "bar"));
	}
	
	printf("%d of %d tests passed\n", testspassed, testsrun);
	return testsfailed;
}