/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1992-1996,2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* * This file contains getoptstr(), which is getopt() for strings of arguments * (not arrays of strings). It is used by the bootloader ({*fs,inet}boot) and * the kernel to process argument strings. */ #include "getoptstr.h" #include /* * This routine needs to be supplied by whatever uses this file. */ char *strchr(const char *s, int c); #define ISNTWORDCH(c) ((c) == '\0' || ISSPACE(c)) /* * Prepare a gos_params structure for use by getoptstr(). */ void getoptstr_init(struct gos_params *params) { params->gos_pos = 1; } /* * Modeled after lib/libc/port/gen/getopt.c. * * With params->gos_opts set to a string of options and params->gos_strp set to * an argument string, getoptstr returns * * the next option letter, where the options are given by the * params->gos_opts string. If the option is followed by a ':' in gos_opts, * then params->gos_optargp will point to the beginning of the argument in * the string, and params->gos_optarglen will contain its length. * * -1 if "--" or a non-option argument is encountered. In the former * case, params->gos_strp is advanced to the next argument. * * '?' if an illegal option is encountered or if an argument is not * supplied for an option which requires one and ':' is not the first * character of opts. In both cases, the option letter is available in * params->gos_last_opt, and in the former case, params->gos_errp will * point to the offending character. * * ':' if an argument is not supplied for an option which requires one and * ':' is the first character of params->gos_opts. */ int getoptstr(struct gos_params *params) { char c; char *cp; /* * const because we should update params. Just make sure you don't * use this after you update params->gos_strp. */ const char * const strp = params->gos_strp; if (params->gos_opts == NULL || strp == NULL) return (-1); if (params->gos_pos == 1) { /* At beginning of new word. */ if (strp[0] == '\0' || strp[0] != '-') return (-1); if (ISNTWORDCH(strp[1])) { /* Lone dash. */ return (-1); } /* Check for "--" */ if (strp[1] == '-' && ISNTWORDCH(strp[2])) { params->gos_strp = &strp[2]; SKIP_SPC(params->gos_strp); return (-1); } } params->gos_last_opt = c = strp[params->gos_pos]; if (c == ':' || (cp = strchr(params->gos_opts, c)) == NULL) { /* Unrecognized option error. */ params->gos_errp = &strp[params->gos_pos]; ++params->gos_pos; if (ISNTWORDCH(strp[params->gos_pos])) { params->gos_strp = &strp[params->gos_pos]; SKIP_SPC(params->gos_strp); params->gos_pos = 1; } return ('?'); } if (cp[1] == ':') { /* This option expects an argument. */ params->gos_strp = &strp[params->gos_pos + 1]; if (ISNTWORDCH(*params->gos_strp)) { /* The argument is in the next word. */ SKIP_SPC(params->gos_strp); if (*params->gos_strp == '\0') { /* Not. Missing argument. */ params->gos_pos = 1; params->gos_optargp = NULL; return (params->gos_opts[0] == ':' ? ':' : '?'); } } params->gos_optargp = params->gos_strp; /* Advance to the next word. */ SKIP_WORD(params->gos_strp); params->gos_optarglen = params->gos_strp - params->gos_optargp; SKIP_SPC(params->gos_strp); params->gos_pos = 1; } else { ++params->gos_pos; if (ISNTWORDCH(strp[params->gos_pos])) { params->gos_strp = &strp[params->gos_pos]; SKIP_SPC(params->gos_strp); params->gos_pos = 1; } params->gos_optargp = NULL; } return (c); }