📄 getargs.c
字号:
* used for CPP type flags we allow to * match -Dabc=xyz on 'D&'. Note that * Dabc=xyz will not match 'D&'. */ if ((!hasdash && argp != sargp) || *fmt != '&') goto nextarg; } /* * *arpp == '\0' || !haseql * We come here if 'argp' starts with * the same sequence as a valid flag. * This will match on the following args: * -farg match on 'f*' * -f12 match on 'f#' * +12 match on '+#' * -12 match on '#' * and all args that are separated from * their flags. * In the switch statement below, we check * if the text after 'argp' (if *argp != 0) or * the next arg is a valid arg for this flag. */ break; } else if (*fmt == *argp) { if (argp[1] == '\0' && (fmt[1] == '\0' || fmt[1] == ',')) { if (setargs) *((int *)curarg) = TRUE; return (checkfmt(fmt));/* XXX */ } } else { /* * skip over to next format identifier * & reset arg pointer */ nextarg: while (*fmt != ',' && *fmt != '\0') { /* function has extra arg on stack */ if (*fmt == '&' && setargs) curarg = va_arg(args, void *); fmt++; } argp = sargp; break; } } switch(*fmt) { case '\0': /* * Boolean type has been tested before. */ if (singlecharflag && !doubledash && (val = dosflags(sargp, sfmt, setargs, oargs)) != BADFLAG) return (val); return (BADFLAG); case ',': fmt++; if (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0') singlecharflag++; if (setargs) curarg = va_arg(args, void *); continue; case '*': if (*argp == '\0') { if (*pac > 1) { (*pac)--; (*pav)++; argp = **pav; } else { return (BADFLAG); } } if (setargs) *((const char **)curarg) = argp; return (checkfmt(fmt)); case '?': /* * If more than one char arg, it * cannot be a character argument. */ if (argp[1] != '\0') goto nextchance; if (setargs) *((char *)curarg) = *argp; return (checkfmt(fmt)); case '+': /* * inc type is similar to boolean, * there is no arg in argp to convert. */ if (*argp != '\0') goto nextchance; /* * If *fmt is '+' and we are on the beginning * of the format desciptor that is currently * checked, this cannot be an inc type flag. */ if (fmt == sfmt || fmt[-1] == ',') goto nextchance; if (fmt[1] == 'l' || fmt[1] == 'L') { if (setargs) *((long *)curarg) += 1; fmt++; } else if (fmt[1] == 's' || fmt[1] == 'S') { if (setargs) *((short *)curarg) += 1; fmt++; } else { if (fmt[1] == 'i' || fmt[1] == 'I') fmt++; if (setargs) *((int *)curarg) += 1; } return (checkfmt(fmt)); case '#': if (*argp == '\0') { if (*pac > 1) { (*pac)--; (*pav)++; argp = **pav; } else { return (BADFLAG); } } if (*astol(argp, &val) != '\0') { /* * arg is not a valid number! * go to next format in the format string * and check if arg matches any other type * in the format specs. */ nextchance: while(*fmt != ',' && *fmt != '\0') { if (*fmt == '&' && setargs) curarg = va_arg(args, void *); fmt++; } argp = sargp; *pac = spac; *pav = spav; continue; } if (fmt[1] == 'l' || fmt[1] == 'L') { if (setargs) *((long *)curarg) = val; fmt++; } else if (fmt[1] == 's' || fmt[1] == 'S') { if (setargs) *((short *)curarg) = val; fmt++; } else { if (fmt[1] == 'i' || fmt[1] == 'I') fmt++; if (setargs) *((int *)curarg) = val; } return (checkfmt(fmt)); case '&': if (*argp == '\0') { if (*pac > 1) { (*pac)--; (*pav)++; argp = **pav; } else { return (BADFLAG); } } if ((val = checkfmt(fmt)) != NOTAFLAG) return (val); if (setargs) { int ret; void *funarg = va_arg(args, void *); ret = ((*(getargfun)curarg) (argp, funarg)); if (ret != NOTAFILE) return (ret); fmt++; } else { return (val); } /* * Called function returns NOTAFILE: try next format. */ } }}/*---------------------------------------------------------------------------|| parse args for combined single char flags|+---------------------------------------------------------------------------*/typedef struct { void *curarg; short count; char c; char type;} sflags;LOCAL int dosflags(argp, fmt, setargs, oargs) register const char *argp; register const char *fmt; BOOL setargs; va_list oargs;{#define MAXSF 32 sflags sf[MAXSF]; va_list args; register sflags *rsf = sf; register int nsf = 0; register const char *p = argp; register int i; register void *curarg = (void *)0; /* * Initialize 'args' to the start of the argument list. * I don't know any portable way to copy an arbitrary * C object so I use a system-specific routine * (probably a macro) from stdarg.h. (Remember that * if va_list is an array, 'args' will be a pointer * and '&args' won't be what I would need for memcpy.) * It is a system requirement for SVr4 compatibility * to be able to do this assgignement. If your system * defines va_list to be an array but does not define * va_copy() you are lost. * This is needed to make sure, that 'oargs' will not * be clobbered. */ va_copy(args, oargs); if (setargs) curarg = va_arg(args, void *); while (*p) { for (i=0; i < nsf; i++) { if (rsf[i].c == *p) break; } if (i >= MAXSF) return (BADFLAG); if (i == nsf) { rsf[i].curarg = (void *)0; rsf[i].count = 0; rsf[i].c = *p; rsf[i].type = (char)-1; nsf++; } rsf[i].count++; p++; } while (*fmt) { if (!isfmtspec(*fmt) && (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0') && strchr(argp, *fmt)) { for (i=0; i < nsf; i++) { if (rsf[i].c == *fmt) { if (fmt[1] == '+') { fmt++; if (fmt[1] == ',' || fmt[1] == '\0') { rsf[i].type = 'i'; } else { rsf[i].type = fmt[1]; } } else { rsf[i].type = fmt[1]; } rsf[i].curarg = curarg; break; } } } while (*fmt != ',' && *fmt != '\0') { /* function has extra arg on stack */ if (*fmt == '&' && setargs) curarg = va_arg(args, void *); fmt++; } if (*fmt != '\0') fmt++; if (setargs) curarg = va_arg(args, void *); } for (i=0; i < nsf; i++) { if (rsf[i].type == (char)-1) return (BADFLAG); if (rsf[i].curarg) { if (rsf[i].type == ',' || rsf[i].type == '\0') { *((int *)rsf[i].curarg) = TRUE; } else if (rsf[i].type == 'i' || rsf[i].type == 'I') { *((int *)rsf[i].curarg) += rsf[i].count; } else if (rsf[i].type == 'l' || rsf[i].type == 'L') { *((long *)rsf[i].curarg) += rsf[i].count; } else if (rsf[i].type == 's' || rsf[i].type == 'S') { *((short *)rsf[i].curarg) += rsf[i].count; } else { return (BADFLAG); } } } return (NOTAFLAG);}/*---------------------------------------------------------------------------|| If the next format character is a comma or the string delimiter,| there are no invalid format specifiers. Return success.| Otherwise raise the getarg_bad_format condition.|+---------------------------------------------------------------------------*/LOCAL int checkfmt(fmt) const char *fmt;{ char c; c = *(++fmt); /* non constant expression */ if (c == ',' || c == '\0') { return (NOTAFLAG); } else { raisecond("getarg_bad_format", (long)fmt); return (BADFMT); }}/*---------------------------------------------------------------------------|| Parse the string as long as valid characters can be found.| Valid flag identifiers are chosen from the set of| alphanumeric characters, '-' and '_'.| If the next character is an equal sign the string| contains a valid flag identifier.|+---------------------------------------------------------------------------*/static int checkeql(str) register const char *str;{ register unsigned char c; for (c = (unsigned char)*str; isalnum(c) || c == '_' || c == '-'; c = *str++) ; return (c == '=');}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -