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

📄 getopts.c

📁 C语言库函数的源代码,是C语言学习参考的好文档。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* +++Date last modified: 05-Jul-1997 */

/************************************************************************/
/*                                                                      */
/*  GETOPTS.C - Universal command line options parser                   */
/*                                                                      */
/*  Original Copyright 1990-96 by Robert B. Stout as part of            */
/*  the MicroFirm Function Library (MFL)                                */
/*                                                                      */
/*  The user is granted a free limited license to use this source file  */
/*  to create royalty-free programs, subject to the terms of the        */
/*  license restrictions specified in the LICENSE.MFL file.             */
/*                                                                      */
/************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include "sniptype.h"
#include "filnames.h"
#include "errors.h"
#include "dirport.h"
#include "snipmath.h"
#include "minmax.h"
#include "getopts.h"
#include "numcnvrt.h"

#define MAX_XARGS 512

int         xargc = 0;
char       *xargv[MAX_XARGS]        = {NULL};
Boolean_T   getopts_range_err       = False_;
Boolean_T   xargs_on                = True_;

static FILE *rspfile = NULL;
static int   count = 0, argidx = 0;

enum proc_stat { PSerror = -1, PSok, PSliteral};

static Boolean_T      PASCAL bounds(struct Option_Tag *);
static enum proc_stat PASCAL swProc(char *swStr);
static void           PASCAL argProc(char *argStr);

/*
**  getopts()
**
**  Parameters: 1 - argc from main()
**              2 - argv from main()
**              3 - your program's options[] array
**
**  Returns: Number of options specified or Error_
**
**  Notes: 1. Your program should declare the global options[] array which
**            specifies all options recognized by getopts().
**
**         2. Out of range data are coerced into range and getopts_range_err
**            is set True_.
*/

int getopts(int argc, char *argv[])
{
      int i;
      Boolean_T scanning = True_;
      struct Option_Tag *ptr;
      char rspfname[FILENAME_MAX];
      char newarg[256];
      enum proc_stat ps;

      xargc = argc;
      xargv[argidx++] = argv[0];
      for (i = 1, count = 0; i < argc; )
      {
            /*
            ** If necessary, open a response file
            */

            if (scanning && !rspfile && '@' == argv[i][0])
            {
                  rspfile = cant(&argv[i][1], "r");
                  --xargc;
                  continue;
            }

            /*
            ** Get the next argument
            */

            if (rspfile)
            {
                  if (NULL == fgets(newarg, 256, rspfile))
                  {
                        rspfile = NULL;
                        ++i;
                        continue;
                  }
                  else
                  {
                        if ('\n' == LAST_CHAR(newarg))
                              LAST_CHAR(newarg) = NUL;
                  }
            }
            else
            {
                  strcpy(newarg, argv[i++]);
            }

            /*
            ** Per Unix tradition, back-to-back switch characters signify
            ** the end of the switches
            */

            if ((2 == strlen(newarg)) && strchr("-/", newarg[0]) &&
                  strchr("-/", newarg[1]))
            {
                  scanning = False_;
                  if (!rspfile)
                        --xargc;
                  continue;
            }

            if (scanning && (strchr("-/", newarg[0])))
            {
                  ps = swProc(newarg);

                  if (PSerror == ps)
                        return Error_;

                  if (PSok == ps)
                        continue;
            }

            /*
            ** If we got here, newarg must be an argument or filename
            */

            argProc(newarg);
      }
      return count;
}

/*
**  Static function to process switch statements
**
**  Parameters: 1 - argv[i] containing the switch
**
**  Returns: PSok      if switch successful
**           PSerror   if invalid
**           PSliteral if literal (non-switch) argument
*/

static enum proc_stat PASCAL swProc(char *swStr)
{
      struct Option_Tag *ptr;
      Boolean_T searching;
      unsigned short byte_var;
      char *arg_ptr;

      /*
      ** Found a switch - If the 2nd character is also a switch
      ** character. If so, then it's a literal and is skipped
      */

      if (strchr("-/@", swStr[1]))
            return PSliteral;

      for (ptr = options, searching = True_; searching; ++ptr)
      {
            if (!ptr->case_sense)
            {
                  ptr->letter = toupper(ptr->letter);
                  swStr[1]    = toupper(swStr[1]);
            }
            if ((int)swStr[1] == ptr->letter) switch (ptr->type)
            {
            case Boolean_Tag:
                  if ('-' == swStr[2])
                        *((Boolean_T *)(ptr->buf)) = False_;
                  else  *((Boolean_T *)(ptr->buf)) = True_;
                  searching = False_;
                  break;

            case Byte_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;
                  }
                  else  arg_ptr = &swStr[2];

                  sscanf(arg_ptr, "%hx", &byte_var);
                  *((char *)(ptr->buf)) = (unsigned char)(byte_var & 0xff);
                  bounds(ptr);
                  searching = False_;
                  break;

            case Int_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;
                  }
                  else  arg_ptr = &swStr[2];

                  *((int *)(ptr->buf)) = (int)(dround(getopts_eval(arg_ptr)));
                  bounds(ptr);
                  searching = False_;
                  break;

            case Short_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;
                  }
                  else  arg_ptr = &swStr[2];

                  *((short *)(ptr->buf)) =
                        (short)(dround(getopts_eval(arg_ptr)));
                  bounds(ptr);
                  searching = False_;
                  break;

            case Word_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;
                  }
                  else  arg_ptr = &swStr[2];

                  sscanf(arg_ptr, "%hx", (unsigned short *)(ptr->buf));
                  bounds(ptr);
                  searching = False_;
                  break;

            case Long_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;
                  }
                  else  arg_ptr = &swStr[2];

                  *((long *)(ptr->buf)) =
                        (long)(dround(getopts_eval(arg_ptr)));
                  bounds(ptr);
                  searching = False_;
                  break;

            case DWord_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;
                  }
                  else  arg_ptr = &swStr[2];

                  sscanf(arg_ptr, "%lx", (unsigned long *)(ptr->buf));
                  bounds(ptr);
                  searching = False_;
                  break;

            case Float_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;
                  }
                  else  arg_ptr = &swStr[2];

                  *((double *)(ptr->buf)) = (double)getopts_eval(arg_ptr);
                  bounds(ptr);
                  searching = False_;
                  break;

            case DFloat_Tag:
                  if (!swStr[2])
                  {
                        if (ptr->Default)
                              arg_ptr = ptr->Default;
                        else  return PSerror;

⌨️ 快捷键说明

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