getopts.c

来自「国外网站上的一些精典的C程序」· C语言 代码 · 共 945 行 · 第 1/3 页

C
945
字号
                                    strcat(ptr->buf, (char *)(ptr->Default));
                              else  strcpy(ptr->buf, (char *)(ptr->Default));
                        }
                        else if (NUL == *p)
                        {
                              string_pending    = True_;
                              additive_pending  = ptr->additive;
                              pending_buf       = ptr->buf;
                        }
                        else
                        {
                              if (ptr->additive)
                                    strcat(ptr->buf, p);
                              else  strcpy(ptr->buf, p);
                        }
                        bounds(ptr);
                        searching = False_;
                        break;

                        default:
                              ErrExit("Unrecognized switch \"%s\"", swStr);
                              return PSerror;
            }
      }
      ++count;
      if (!rspfile)
            --xargc;

      return PSok;
}

/*
**  Static function to process arguments
*/

static void argProc(char *argStr)
{
      DOSFileData ff;

      /* If no wildcards or ignoring wildcards, just copy it */

      if (!xargs_on || !has_wild(argStr))
      {
            xargv[argidx] = malloc(strlen(argStr) + 1);
            if (NULL == xargv[argidx])
                  ErrExit("Out of memory");
            strcpy(xargv[argidx], argStr);
            ++xargc;
            ++argidx;
            return;
      }
      else  /* Expand wildcards, if possible                      */
      {
            if (Success_ == FIND_FIRST(argStr, _A_ANY, &ff))
            {
                  char path[FILENAME_MAX];
                  char *p;

                  /* Save the path for re-attachment              */

                  fnSplit(argStr, NULL, path, NULL, NULL, NULL, NULL);

                  --xargc;    /* We add stuff in the loop, so back up   */
                  do
                  {                             
                        xargv[argidx] = malloc(strlen(ff_name(&ff))
                                               + strlen(path) + 2);
                        if (NULL == xargv[argidx])
                              ErrExit("Out of memory");
                        fnMerge(xargv[argidx], NULL, path, NULL, ff_name(&ff),
                                NULL, NULL);
                        ++argidx;
                        ++xargc;

                  } while (Success_ == FIND_NEXT(&ff));
                  FIND_END(&ff);
            }
      }
}

/*
**  Assure new data are within specified ranges, return non-zero if coerced
*/

static Boolean_T bounds(struct Option_Tag *option)
{
      Boolean_T coerced = False_;
      union {
            unsigned char      B;
            int                I;
            short              S;
            unsigned short     W;
            long               L;
            unsigned long      DW;
            float              F;
            double             D;
            char              *P;
      } tmp, val;
      size_t len;

      switch(option->type)
      {
      case Bitfield_Tag:
            tmp.DW = *((unsigned long *)(option->buf));
            if (option->max)
            {
                  sscanf(option->max, "%lx", &val.DW);
                  tmp.DW |= val.DW ;
            }
            if (option->min)
            {
                  sscanf(option->min, "%hx", &val.DW);
                  tmp.DW &= val.DW;
            }
            if (*((unsigned long *)(option->buf)) != tmp.DW)
            {
                  getopts_range_err = True_;
                  *((unsigned long *)(option->buf)) = tmp.DW;
                  coerced = True_;
            }
            break;

      case Byte_Tag:
            tmp.B = *((unsigned char *)(option->buf));
            if (option->max)
            {
                  sscanf(option->max, "%lx", &val.L);
                  val.L &= 0xff;
                  tmp.B = min(tmp.B, (unsigned char)val.L);
            }
            if (option->min)
            {
                  sscanf(option->min, "%lx", &val.L);
                  val.L &= 0xff;
                  tmp.B = max(tmp.B, (unsigned char)val.L);
            }
            if (*((unsigned char *)(option->buf)) != tmp.B)
            {
                  getopts_range_err = True_;
                  *((unsigned char *)(option->buf)) = tmp.B;
                  coerced = True_;
            }
            break;

      case Int_Tag:
            tmp.I = *((int *)(option->buf));
            if (option->max)
            {
                  val.D = dround(getopts_eval(option->max));
                  if (val.D > (double)INT_MAX)
                        val.I = INT_MAX;
                  else  val.I = (int)val.D;
                  tmp.I = min(tmp.I, val.I);
            }
            if (option->min)
            {
                  val.D = dround(getopts_eval(option->min));
                  if (val.D < (double)INT_MIN)
                        val.I = INT_MIN;
                  else  val.I = (int)val.D;
                  tmp.I = max(tmp.I, val.I);
            }
            if (*((int *)(option->buf)) != tmp.I)
            {
                  getopts_range_err = True_;
                  *((int *)(option->buf)) = tmp.I;
                  coerced = True_;
            }
            break;

      case Short_Tag:
            tmp.S = *((short *)(option->buf));
            if (option->max)
            {
                  val.D = dround(getopts_eval(option->max));
                  if (val.D > (double)SHRT_MAX)
                        val.S = SHRT_MAX;
                  else  val.S = (short)val.D;
                  tmp.S = min(tmp.I, val.I);
            }
            if (option->min)
            {
                  val.D = dround(getopts_eval(option->min));
                  if (val.D < (double)SHRT_MIN)
                        val.S = SHRT_MIN;
                  else  val.S = (short)val.D;
                  tmp.S = max(tmp.I, val.I);
            }
            if (*((short *)(option->buf)) != tmp.S)
            {
                  getopts_range_err = True_;
                  *((short *)(option->buf)) = tmp.I;
                  coerced = True_;
            }
            break;

      case Word_Tag:
            tmp.W = *((unsigned short *)(option->buf));
            if (option->max)
            {
                  sscanf(option->max, "%hx", &val.W);
                  tmp.W = min(tmp.W, val.W);
            }
            if (option->min)
            {
                  sscanf(option->min, "%hx", &val.W);
                  tmp.W = max(tmp.W, val.W);
            }
            if (*((unsigned short *)(option->buf)) != tmp.W)
            {
                  getopts_range_err = True_;
                  *((unsigned short *)(option->buf)) = tmp.W;
                  coerced = True_;
            }
            break;

      case Long_Tag:
            tmp.L = *((long *)(option->buf));
            if (option->max)
            {
                  val.D = dround(getopts_eval(option->max));
                  if (val.D > (double)LONG_MAX)
                        val.L = LONG_MAX;
                  else  val.L = (long)val.D;
                  tmp.L = min(tmp.L, val.L);
            }
            if (option->min)
            {
                  val.D = dround(getopts_eval(option->min));
                  if (val.D < (double)LONG_MIN)
                        val.L = LONG_MIN;
                  else  val.L = (int)val.D;
                  tmp.L = max(tmp.L, val.L);
            }
            if (*((long *)(option->buf)) != tmp.L)
            {
                  getopts_range_err = True_;
                  *((long *)(option->buf)) = tmp.L;
                  coerced = True_;
            }
            break;

      case DWord_Tag:
            tmp.DW = *((unsigned long *)(option->buf));
            if (option->max)
            {
                  sscanf(option->max, "%lx", &val.DW);
                  tmp.DW = min(tmp.DW, val.DW);
            }
            if (option->min)
            {
                  sscanf(option->min, "%hx", &val.DW);
                  tmp.DW = max(tmp.DW, val.DW);
            }
            if (*((unsigned long *)(option->buf)) != tmp.DW)
            {
                  getopts_range_err = True_;
                  *((unsigned long *)(option->buf)) = tmp.DW;
                  coerced = True_;
            }
            break;

      case Float_Tag:
            tmp.F = *((float *)(option->buf));
            if (option->max)
            {
                  val.F = (float)getopts_eval(option->max);
                  tmp.F = min(tmp.F, val.F);
            }
            if (option->min)
            {
                  val.F = (float)getopts_eval(option->min);
                  tmp.F = max(tmp.F, val.F);
            }
            if (*((float *)(option->buf)) != tmp.F)
            {
                  getopts_range_err = True_;
                  *((float *)(option->buf)) = tmp.F;
                  coerced = True_;
            }
            break;

      case DFloat_Tag:
            tmp.D = *((double *)(option->buf));
            if (option->max)
            {
                  val.D = getopts_eval(option->max);
                  tmp.D = min(tmp.D, val.D);
            }
            if (option->min)
            {
                  val.D = getopts_eval(option->min);
                  tmp.D = max(tmp.D, val.D);
            }
            if (*((double *)(option->buf)) != tmp.D)
            {
                  getopts_range_err = True_;
                  *((double *)(option->buf)) = tmp.D;
                  coerced = True_;
            }
            break;
      }

      return coerced;
}

/*
**  Simplified evaluate() call - returns double or aborts
*/

double getopts_eval(char *str)
{
      return strtod(str, NULL);
}

⌨️ 快捷键说明

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