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 + -
显示快捷键?