[BACK]Return to compat_getsubopt.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

File: [cvsweb.bsd.lv] / mandoc / compat_getsubopt.c (download)

Revision 1.5, Sun Aug 17 20:53:50 2014 UTC (6 years, 3 months ago) by schwarze
Branch: MAIN
CVS Tags: VERSION_1_14_5, VERSION_1_14_4, VERSION_1_14_3, VERSION_1_14_2, VERSION_1_14_1, VERSION_1_13_4, VERSION_1_13_3, VERSION_1_13_2, VERSION_1_13
Changes since 1.4: +2 -8 lines

Do not require getsubopt() to provide extern char *suboptarg.
We don't use it anyway in mandoc.  Like this, fewer systems need
the compat implementation.  In particular, we can now use the stock
getsubopt() on glibc and musl.

Besides, the comment in the BSD getsubopt.c that error messages are
tricky without *suboptarg is massively overblown.  If you simply
save a copy of the pointer you pass into getsubopt(), that's quite
usable for an error message.

People start campaigning for the addition of *suboptarg to C libraries
on the grounds that mandoc wants it, but actually, i consider library
functions manipulating global data quite ugly, so stop pushing people
into that questionable direction.

While here, add an explicit Copyright header to the test file.
While it's obviously to me what Kristaps intended, others might
consider this file copyrightable and wonder what's up.

#include "config.h"

#if HAVE_GETSUBOPT

int dummy;

#else

/*	$Id: compat_getsubopt.c,v 1.5 2014/08/17 20:53:50 schwarze Exp $	*/
/*	$OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie Exp $	*/

/*-
 * Copyright (c) 1990, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int
getsubopt(char **optionp, char * const *tokens, char **valuep)
{
	int cnt;
	char *suboptarg;
	char *p;

	suboptarg = *valuep = NULL;

	if (!optionp || !*optionp)
		return(-1);

	/* skip leading white-space, commas */
	for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);

	if (!*p) {
		*optionp = p;
		return(-1);
	}

	/* save the start of the token, and skip the rest of the token. */
	for (suboptarg = p;
	    *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);

	if (*p) {
		/*
		 * If there's an equals sign, set the value pointer, and
		 * skip over the value part of the token.  Terminate the
		 * token.
		 */
		if (*p == '=') {
			*p = '\0';
			for (*valuep = ++p;
			    *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
			if (*p) 
				*p++ = '\0';
		} else
			*p++ = '\0';
		/* Skip any whitespace or commas after this token. */
		for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
	}

	/* set optionp for next round. */
	*optionp = p;

	for (cnt = 0; *tokens; ++tokens, ++cnt)
		if (!strcmp(suboptarg, *tokens))
			return(cnt);
	return(-1);
}

#endif