⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 option.c

📁 Sun公司Dream项目
💻 C
字号:
/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the "License").  You may not use this file except
 * in compliance with the License.
 *
 * You can obtain a copy of the license at
 * http://www.opensource.org/licenses/cddl1.php
 * 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
 * http://www.opensource.org/licenses/cddl1.php.  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]
 */ 

/*
 * $(@)Option.c $Revision: 1.2 $ $Date: 2006/07/15 00:02:34 $
 * 
 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
 */
/*
 * Copyright (c) 1998 by Sun Microsystems, Inc.
 */

/*
 * Option.c -- Description.
 */

#pragma ident "@(#)Option.c 1.4	99/08/27 SMI"

#if	!defined(OPTION_HEADER)
#define	OPTION_BODY
#define	OPTION_INLINE		extern
#include "cobjs/Option.h"
#endif					   /* !defined(OPTION_HEADER) */

#include <stdlib.h>
#include <ctype.h>
#include <libintl.h>

#include "cobjs/Log.h"
#include "cobjs/Macros.h"
#include "cobjs/Types.h"

/*************************************************************************
 * Defines
 *************************************************************************/

/*************************************************************************
 * Instance Variables
 *************************************************************************/

struct _Option {
    int			argc;
    const char * const	*argv;
    OptionEntry		*table;
    OptionEntry		*entryp;
    int			flag;		   /* option character that failed */
    int			arg;		   /* next option to parse */
    const char		*argp;		   /* position in arg */
    const char		*argval;
};

/*************************************************************************
 * Private types and prototypes referenced from inlines
 *************************************************************************/

/*
 * Use INLINE_PRIVATE if non-inline-able, define in Non-inlinable section
 * Use static if inline-able, define in Private Inline-able section
 *
 * INLINE_PRIVATE void optionInlinePrivate(void);
 */

/*************************************************************************
 * Private class data referenced from inlines
 *************************************************************************/

/*************************************************************************
 * Inline Methods
 *************************************************************************/

OPTION_INLINE int
optionFlag(Option option)
{
    return option->flag;
}

OPTION_INLINE int
optionArg(Option option)
{
    return option->arg;
}

OPTION_INLINE char *
optionValue(Option option)
{
    return (char *)option->argval;
}

OPTION_INLINE OptionEntry *
optionEntry(Option option)
{
    return option->entryp;
}

/*************************************************************************
 * Private Inlineable Methods and Functions Called From Inlines
 *************************************************************************/

#if	!defined(OPTION_HEADER)

/*************************************************************************
 * Private types
 *************************************************************************/

/*************************************************************************
 * Private method prototypes
 *************************************************************************/

/*************************************************************************
 * Private function prototypes
 *************************************************************************/

/*************************************************************************
 * Private class data
 *************************************************************************/

/*************************************************************************
 * Class Methods
 *************************************************************************/

/*
 * lint won't let you pass a "char **argv" to "const char * const *argv"
 * So, we give up and declare this char ** and then cast on the
 * instance var assignment.
 */
Option
optionNew(int argc, char **argv, OptionEntry table[])
{
    Option option = NEW_ZEROED(struct _Option, 1);

    option->argc = argc;
    option->argv = (const char * const *)argv;
    option->table = table;
    option->entryp = NULL;
    option->flag = 'a';
    option->arg = 1;
    option->argp = "";
    option->argval = NULL;
    return option;
}

/*************************************************************************
 * Instance Methods
 *************************************************************************/

Boolean
optionScan(Option option, const char *progName, const char *extraArgs)
{
    char flag = '\0';	/* lint */
    Boolean isSuccess = TRUE;

    while (isSuccess && (flag = optionNext(option)) != '\0') {
	switch (flag) {
	case '#':
	    switch (optionEntry(option)->type) {
	    case OPTION_TYPE_INT:
		logLibPrint(cobjs_TEXT_DOMAIN,
		    "FATAL: %s not legal integer value for flag %c\n",
		    optionValue(option), optionFlag(option));
		break;
	    case OPTION_TYPE_DBL:
		logLibPrint(cobjs_TEXT_DOMAIN,
		    "FATAL: %s not legal floating point value for flag %c\n",
		    optionValue(option), optionFlag(option));
		break;
	    default:
		logLibPrint(cobjs_TEXT_DOMAIN,
		    "FATAL: %s not legal value for flag %c\n",
		    optionValue(option), optionFlag(option));
		break;
	    }
	    optionUsage(option, progName, extraArgs);
	    isSuccess = FALSE;
	    break;
	case '?':
	    logLibPrint(cobjs_TEXT_DOMAIN,
		    "FATAL: flag %c not legal\n", optionFlag(option));
	    optionUsage(option, progName, extraArgs);
	    isSuccess = FALSE;
	    break;
	case '!':
	    switch (optionEntry(option)->type) {
	    case OPTION_TYPE_INT:
		logLibPrint(cobjs_TEXT_DOMAIN,
		    "FATAL: flag %c requires integer value\n",
		    optionFlag(option));
		break;
	    case OPTION_TYPE_DBL:
		logLibPrint(cobjs_TEXT_DOMAIN,
		    "FATAL: flag %c requires floating point value\n",
		    optionFlag(option));
		break;
	    default:
		logLibPrint(cobjs_TEXT_DOMAIN,
		    "FATAL: flag %c requires value\n",
		    optionFlag(option));
		break;
	    }
	    optionUsage(option, progName, extraArgs);
	    isSuccess = FALSE;
	    break;
	case '@':
	    optionUsage(option, progName, extraArgs);
	    isSuccess = FALSE;
	    break;
	}
    }
    return isSuccess;
}

char
optionNext(Option option)
{
    OptionEntry *entryp;
    double dval;
    int ival;
    char *cp;

    option->argval = NULL;
    option->entryp = NULL;

    ABORT_IF_FALSE(option->flag != '\0');
    if ((option->flag = *(const u8 *)option->argp++) == '\0') {
	if (option->arg >= option->argc
		|| option->argv[option->arg] == NULL
		|| option->argv[option->arg][0] != '-') {
	    return '\0';
	}
	option->argp = &option->argv[option->arg++][1];
	if ((option->flag = *(const u8 *)option->argp++) == '\0') {
	    return '\0';
	}
	if (option->flag == '-' && *((const u8 *)option->argp) == '\0') {
	    option->flag = '\0';
	    option->arg += 1;
	    return '\0';
	}
    }

    for (entryp = option->table; entryp->flag != '\0'; entryp++) {
	if (entryp->flag == option->flag
	    || (entryp->type == OPTION_TYPE_BOOLEAN
		&& entryp->flag == tolower(option->flag))) {
	    break;
	}
    }
    if (entryp->flag == '\0') {
	return '?';
    }
    option->entryp = entryp;
    switch (entryp->type) {
    case OPTION_TYPE_FLAG:
	*(Boolean *) entryp->ptr = TRUE;
	break;
    case OPTION_TYPE_BOOLEAN:
	*(Boolean *) entryp->ptr = (Boolean)islower(option->flag);
	break;
    case OPTION_TYPE_STRING:
    case OPTION_TYPE_INT:
    case OPTION_TYPE_DBL:
	if (option->arg >= option->argc) {
	    return '!';
	}
	option->argval = option->argv[option->arg++];
	switch (entryp->type) {
	case OPTION_TYPE_STRING:
	    *(char **) entryp->ptr = (char *)option->argval;
	    break;
	case OPTION_TYPE_INT:
	    ival = strtol(option->argval, &cp, 0);
	    if (*cp != '\0') {
		return '#';
	    }
	    *(int *) entryp->ptr = ival;
	    break;
	case OPTION_TYPE_DBL:
	    dval = strtod(option->argval, &cp);
	    if (*cp != '\0') {
		return '#';
	    }
	    *(double *) entryp->ptr = dval;
	    break;
	}
	break;
    case OPTION_TYPE_USAGE:
	return '@';
    default:
	ABORT("illegal OptionTable type");
    }
    return option->flag;
}

void
optionUsage(Option option, const char *progname, const char *cmdargs)
{
    OptionEntry *entryp;

    if (progname == NULL || progname[0] == '\0') {
	if (option->argv[0] == NULL) {
	    progname = "<Unknown>";
	} else {
	    progname = strrchr(option->argv[0], '/');
	    if (progname == NULL) {
		progname = option->argv[0];
	    } else {
		progname += 1;
	    }
	}
    }
    logLibPrint(cobjs_TEXT_DOMAIN, "Usage: %s [<flags>] %s", progname,
	    gettext(cmdargs));
    logLibPrint(cobjs_TEXT_DOMAIN, "   Flags are:");
    for (entryp = option->table; entryp->flag != '\0'; entryp++) {
	switch (entryp->type) {
	case OPTION_TYPE_FLAG:
	    logLibPrint(cobjs_TEXT_DOMAIN,
		NO_LOCALE("       [-%c]  {%s}"),
		entryp->flag, gettext(entryp->desc));
	    break;
	case OPTION_TYPE_USAGE:
	    logLibPrint(cobjs_TEXT_DOMAIN,
		NO_LOCALE("       [-%c]  {%s}"),
		entryp->flag, gettext(entryp->desc));
	    break;
	case OPTION_TYPE_BOOLEAN:
	    logLibPrint(cobjs_TEXT_DOMAIN,
		NO_LOCALE("       [-%c%c] {%s: %c}"),
		entryp->flag, toupper(entryp->flag), gettext(entryp->desc),
		*(Boolean *)entryp->ptr ? entryp->flag : toupper(entryp->flag));
	    break;
	case OPTION_TYPE_STRING:
	    logLibPrint(cobjs_TEXT_DOMAIN,
		NO_LOCALE("       [-%c]  {%s: \"%s\"}"),
		entryp->flag, gettext(entryp->desc),
		*(char **)entryp->ptr != NULL ? *(char **) entryp->ptr
		    : dgettext(cobjs_TEXT_DOMAIN, "<NULL>"));
	    break;
	case OPTION_TYPE_INT:
	    logLibPrint(cobjs_TEXT_DOMAIN,
		NO_LOCALE("       [-%c]  {%s: %d}"),
		entryp->flag, gettext(entryp->desc), *(int *) entryp->ptr);
	    break;
	case OPTION_TYPE_DBL:
	    logLibPrint(cobjs_TEXT_DOMAIN,
		NO_LOCALE("       [-%c]  {%s: %.3f}"),
		entryp->flag, gettext(entryp->desc), *(double *) entryp->ptr);
	    break;
	default:
	    ABORT("illegal OptionTable type");
	}
    }
}

void
optionFree(Option option)
{
    free(option);
}

/*************************************************************************
 * Private Methods
 *************************************************************************/

/*
 * Non-inlinable called from inline
 *
 * INLINE_PRIVATE void
 * optionInlinePrivate(void)
 * {
 * }
 *
 * static void
 * optionPrivate(void)
 * {
 * }
 */

/*************************************************************************
 * Private Functions
 *************************************************************************/

/* 
 * static void
 * optionFunc()
 * {
 * }
 */

#endif					   /* !defined(OPTION_HEADER) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -