ReactOS 0.4.15-dev-7788-g1ad9096
getargs.c File Reference
#include <schily/mconfig.h>
#include <schily/standard.h>
#include <schily/utypes.h>
#include <schily/getargs.h>
#include <schily/varargs.h>
#include <schily/string.h>
#include <schily/schily.h>
#include <schily/ctype.h>
Include dependency graph for getargs.c:

Go to the source code of this file.

Classes

struct  sflags
 

Macros

#define NEW
 
#define RETMAX   2 /* Max. value for getargerror() */
 
#define FLAGDELIM   2 /* "--" stopped flag processing */
 
#define NOTAFLAG   1 /* Not a flag type argument */
 
#define NOARGS   0 /* No more args */
 
#define BADFLAG   (-1) /* Not a valid flag argument */
 
#define BADFMT   (-2) /* Error in format string */
 
#define NOTAFILE   (-3) /* Seems to be a flag type arg */
 
#define RETMIN   (-3) /* Min. value for getargerror() */
 
#define RNAME(a)   (retnames[(a)-RETMIN])
 
#define SCANONLY   0 /* Do not try to set argument values */
 
#define SETARGS   1 /* Set argument values from cmdline */
 
#define ARGVECTOR   2 /* Use vector instead of list interface */
 
#define NOEQUAL   4 /* -opt=val not allowed for -opt val */
 
#define isfmtspec(c)   (strchr(fmtspecs, c) != NULL)
 
#define MAXSF   64
 

Functions

LOCAL struct ga_props *_getprops __PR ((struct ga_props *))
 
int _getargs __PR ((int *, char *const **, void *, int, struct ga_props *, va_list))
 
LOCAL int dofile __PR ((int *, char *const **, const char **, struct ga_props *))
 
LOCAL int doflag __PR ((int *, char *const **, const char *, void *, int, va_list))
 
LOCAL int dosflags __PR ((const char *, void *, int *, char *const **, int, va_list))
 
LOCAL int checkfmt __PR ((const char *))
 
EXPORT int _getarginit (struct ga_props *props, size_t size, UInt32_t flags)
 
LOCAL struct ga_props_getprops (struct ga_props *props)
 
EXPORT int getargs (int *pac, pav, char *fmt, va_alist)
 
EXPORT int getlargs (int *pac, pav, struct ga_props *props, char *fmt, va_alist)
 
EXPORT int getvargs (int *pac, pav, struct ga_props *props, struct ga_flags *vfmt)
 
EXPORT int getallargs (int *pac, pav, char *fmt, va_alist)
 
EXPORT int getlallargs (int *pac, pav, struct ga_props *props, char *fmt, va_alist)
 
EXPORT int getvallargs (int *pac, pav, struct ga_props *props, struct ga_flags *vfmt)
 
EXPORT int getfiles (int *pac, pav, const char *fmt)
 
EXPORT int getlfiles (int *pac, pav, struct ga_props *props, const char *fmt)
 
EXPORT int getvfiles (int *pac, pav, struct ga_props *props, struct ga_flags *vfmt)
 
EXPORT int _getargs (int *pac, char *const **pav, void *vfmt, int flags, struct ga_props *props, va_list args)
 
LOCAL int dofile (int *pac, char *const **pav, const char **pargp, struct ga_props *props)
 
LOCAL int doflag (int *pac, char *const **pav, const char *argp, void *vfmt, int flags, va_list oargs)
 
LOCAL int dosflags (const char *argp, void *vfmt, int *pac, char *const **pav, int flags, va_list oargs)
 
LOCAL int checkfmt (char *fmt) const
 
LOCAL int checkeql (const char *str)
 
EXPORT chargetargerror (int err)
 

Variables

static UConst char sccsid []
 
LOCAL charretnames []
 
LOCAL va_list va_dummy
 
LOCAL char fmtspecs [] = "#?*&~+%"
 
LOCAL struct ga_props props_default = { 0, 0, sizeof (struct ga_props) }
 
LOCAL struct ga_props props_posix = { GAF_POSIX_DEFAULT, 0, sizeof (struct ga_props) }
 

Macro Definition Documentation

◆ ARGVECTOR

#define ARGVECTOR   2 /* Use vector instead of list interface */

Definition at line 92 of file getargs.c.

◆ BADFLAG

#define BADFLAG   (-1) /* Not a valid flag argument */

Definition at line 75 of file getargs.c.

◆ BADFMT

#define BADFMT   (-2) /* Error in format string */

Definition at line 76 of file getargs.c.

◆ FLAGDELIM

#define FLAGDELIM   2 /* "--" stopped flag processing */

Definition at line 72 of file getargs.c.

◆ isfmtspec

#define isfmtspec (   c)    (strchr(fmtspecs, c) != NULL)

Definition at line 115 of file getargs.c.

◆ MAXSF

#define MAXSF   64

◆ NEW

#define NEW

Definition at line 7 of file getargs.c.

◆ NOARGS

#define NOARGS   0 /* No more args */

Definition at line 74 of file getargs.c.

◆ NOEQUAL

#define NOEQUAL   4 /* -opt=val not allowed for -opt val */

Definition at line 93 of file getargs.c.

◆ NOTAFILE

#define NOTAFILE   (-3) /* Seems to be a flag type arg */

Definition at line 77 of file getargs.c.

◆ NOTAFLAG

#define NOTAFLAG   1 /* Not a flag type argument */

Definition at line 73 of file getargs.c.

◆ RETMAX

#define RETMAX   2 /* Max. value for getargerror() */

Definition at line 71 of file getargs.c.

◆ RETMIN

#define RETMIN   (-3) /* Min. value for getargerror() */

Definition at line 78 of file getargs.c.

◆ RNAME

#define RNAME (   a)    (retnames[(a)-RETMIN])

Definition at line 88 of file getargs.c.

◆ SCANONLY

#define SCANONLY   0 /* Do not try to set argument values */

Definition at line 90 of file getargs.c.

◆ SETARGS

#define SETARGS   1 /* Set argument values from cmdline */

Definition at line 91 of file getargs.c.

Function Documentation

◆ __PR() [1/6]

LOCAL int checkfmt __PR ( (const char *)  )

◆ __PR() [2/6]

LOCAL int dosflags __PR ( (const char *, void *, int *, char *const **, int, va_list )

◆ __PR() [3/6]

LOCAL int dofile __PR ( (int *, char *const **, const char **, struct ga_props *)  )

◆ __PR() [4/6]

LOCAL int doflag __PR ( (int *, char *const **, const char *, void *, int, va_list )

◆ __PR() [5/6]

int _getargs __PR ( (int *, char *const **, void *, int, struct ga_props *, va_list )

◆ __PR() [6/6]

◆ _getarginit()

EXPORT int _getarginit ( struct ga_props props,
size_t  size,
UInt32_t  flags 
)

Definition at line 121 of file getargs.c.

125{
126 if (size > sizeof (struct ga_props))
127 return (-1);
128
129 /*
130 * GAF_POSIX may be used as an alias for the flags that currently
131 * define POSIX behavior.
132 */
133 if (flags == GAF_POSIX)
135
136 props->ga_flags = flags;
137 props->ga_oflags = 0;
138 props->ga_size = size;
139 return (0);
140}
#define GAF_POSIX
Definition: getargs.h:117
#define GAF_POSIX_DEFAULT
Definition: getargs.h:132
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
static const WCHAR props[]
Definition: wbemdisp.c:288

◆ _getargs()

EXPORT int _getargs ( int pac,
char *const **  pav,
void vfmt,
int  flags,
struct ga_props props,
va_list  args 
)

Definition at line 395 of file getargs.c.

402{
403 const char *argp;
404 int ret;
405
406
408
409 if (props->ga_flags & GAF_NO_EQUAL)
410 flags |= NOEQUAL;
411
412 for (; *pac > 0; (*pac)--, (*pav)++) {
413 argp = **pav;
414
415 ret = dofile(pac, pav, &argp, props);
416
417 if (ret != NOTAFILE)
418 return (ret);
419
420 ret = doflag(pac, pav, argp, vfmt, flags, args);
421
422 if (ret != NOTAFLAG)
423 return (ret);
424 }
425 return (NOARGS);
426}
#define GAF_NO_EQUAL
Definition: getargs.h:113
Definition: match.c:390
LOCAL int doflag(int *pac, char *const **pav, const char *argp, void *vfmt, int flags, va_list oargs)
Definition: getargs.c:502
LOCAL int dofile(int *pac, char *const **pav, const char **pargp, struct ga_props *props)
Definition: getargs.c:433
#define NOTAFILE
Definition: getargs.c:77
#define NOEQUAL
Definition: getargs.c:93
#define NOTAFLAG
Definition: getargs.c:73
#define NOARGS
Definition: getargs.c:74
LOCAL struct ga_props * _getprops(struct ga_props *props)
Definition: getargs.c:143
int ret

Referenced by getallargs(), getargs(), getfiles(), getlallargs(), getlargs(), getlfiles(), getvallargs(), getvargs(), and getvfiles().

◆ _getprops()

LOCAL struct ga_props * _getprops ( struct ga_props props)

Definition at line 143 of file getargs.c.

145{
146 if (props == GA_NO_PROPS)
148 else if (props == GA_POSIX_PROPS)
150 props->ga_oflags = 0;
151 /*
152 * GAF_POSIX may be used as an alias for the flags that currently
153 * define POSIX behavior.
154 */
155 if (props->ga_flags == GAF_POSIX)
156 props->ga_flags = GAF_POSIX_DEFAULT;
157
158 return (props);
159}
#define GA_POSIX_PROPS
Definition: getargs.h:106
#define GA_NO_PROPS
Definition: getargs.h:105
LOCAL struct ga_props props_default
Definition: getargs.c:117
LOCAL struct ga_props props_posix
Definition: getargs.c:118

Referenced by _getargs(), getlallargs(), and getvallargs().

◆ checkeql()

LOCAL int checkeql ( const char str)

Definition at line 1321 of file getargs.c.

1323{
1324 register unsigned char c;
1325
1326 for (c = (unsigned char)*str;
1327 isalnum(c) || c == '_' || c == '-' || c == '+';
1328 c = *++str)
1329 /* LINTED */
1330 ;
1331 return (c == '=');
1332}
const GLubyte * c
Definition: glext.h:8905
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define c
Definition: ke_i.h:80
const WCHAR * str

Referenced by dofile(), and doflag().

◆ checkfmt()

LOCAL int checkfmt ( char fmt) const

Definition at line 1297 of file getargs.c.

1299{
1300 char c;
1301
1302 c = *(++fmt); /* non constant expression */
1303
1304
1305 if (c == ',' || c == '\0') {
1306 return (NOTAFLAG);
1307 } else {
1308 raisecond("getarg_bad_format", (long)fmt);
1309 return (BADFMT);
1310 }
1311}
EXPORT void raisecond(char *signame, long arg2) const
Definition: raisecond.c:100
Definition: dsound.c:943
#define BADFMT
Definition: getargs.c:76

Referenced by doflag(), and for().

◆ dofile()

LOCAL int dofile ( int pac,
char *const **  pav,
const char **  pargp,
struct ga_props props 
)

Definition at line 433 of file getargs.c.

438{
439 register const char *argp = *pargp;
440
441
442 if (argp[0] == '-') {
443 /*
444 * "-" is a special non flag type argument
445 * that usually means take stdin instead of a named file
446 */
447 if (argp[1] == '\0')
448 return (NOTAFLAG);
449 /*
450 * "--" is a prefix to take the next argument
451 * as non flag type argument
452 * NOTE: POSIX requires "--" to indicate the end of the
453 * flags on the command line. Programs that like to be
454 * 100% POSIX compliant call only get[lv]args() once
455 * and then process the list of files from cav[0].
456 */
457 if (argp[1] == '-' && argp[2] == '\0') {
458 if (--(*pac) > 0) {
459 (*pav)++;
460 return (FLAGDELIM);
461 } else {
462 return (NOARGS);
463 }
464 }
465 }
466
467 /*
468 * Now check if it may be flag type argument at all.
469 * Flag type arguments begin with a '-', a '+' or contain a '='
470 * i.e. -flag +flag or flag=
471 * The behavior here may be controlled by props->ga_flags to
472 * allow getargs() to e.g. behave fully POSIX compliant.
473 */
474 if (argp[0] != '-') {
475 if (argp[0] == '+' && (props->ga_flags & GAF_NO_PLUS) == 0)
476 return (NOTAFILE); /* This is a flag type arg */
477
478 /*
479 * If 'flag=value' is not allowed at all, speed things up
480 * and do not call checkeql() to check for '='.
481 */
482 if (props->ga_flags & GAF_NO_EQUAL)
483 return (NOTAFLAG);
484 if (checkeql(argp) && (props->ga_flags & GAF_NEED_DASH) == 0)
485 return (NOTAFILE); /* This is a flag type arg */
486 return (NOTAFLAG);
487 }
488 return (NOTAFILE); /* This is a flag type arg */
489}
#define GAF_NEED_DASH
Definition: getargs.h:114
#define GAF_NO_PLUS
Definition: getargs.h:112
LOCAL int checkeql(const char *str)
Definition: getargs.c:1321
#define FLAGDELIM
Definition: getargs.c:72

Referenced by _getargs().

◆ doflag()

LOCAL int doflag ( int pac,
char *const **  pav,
const char argp,
void vfmt,
int  flags,
va_list  oargs 
)

Definition at line 502 of file getargs.c.

509{
510 register const char *fmt = (const char *)vfmt;
511 struct ga_flags *flagp = vfmt;
512 const char *fmtp;
513 long val;
514 Llong llval;
515 int singlecharflag = 0;
516 BOOL isspec;
517 BOOL hasdash = FALSE;
518 BOOL doubledash = FALSE;
519 BOOL haseql = checkeql(argp);
520 const char *sargp;
521 const char *sfmt;
523 char *const *spav = *pav;
524 int spac = *pac;
525 void *curarg = (void *)0;
526
527 sfmt = fmt;
528 /*
529 * flags beginning with '-' don't have to include the '-' in
530 * the format string.
531 * flags beginning with '+' have to include it in the format string.
532 */
533 if (argp[0] == '-') {
534 argp++;
535 hasdash = TRUE;
536 /*
537 * Implement legacy support for --longopt
538 * If we find a double dash, we do not look for combinations
539 * of boolean single char flags.
540 */
541 if (argp[0] == '-') {
542 argp++;
543 doubledash = TRUE;
544 /*
545 * Allow -- only for long options.
546 */
547 if (argp[1] == '\0') {
548 return (BADFLAG);
549 }
550 }
551 }
552 sargp = argp;
553
554 /*
555 * Initialize 'args' to the start of the argument list.
556 * I don't know any portable way to copy an arbitrary
557 * C object so I use a system-specific routine
558 * (probably a macro) from stdarg.h. (Remember that
559 * if va_list is an array, 'args' will be a pointer
560 * and '&args' won't be what I would need for memcpy.)
561 * It is a system requirement for SVr4 compatibility
562 * to be able to do this assgignement. If your system
563 * defines va_list to be an array but does not define
564 * va_copy() you are lost.
565 * This is needed to make sure, that 'oargs' will not
566 * be clobbered.
567 */
569
570 if (flags & ARGVECTOR) {
571 sfmt = fmt = flagp->ga_format;
572 if (fmt == NULL)
573 sfmt = fmt = "";
574 if (flags & SETARGS)
575 curarg = flagp->ga_arg;
576 } else if (flags & SETARGS) {
577 curarg = va_arg(args, void *);
578 }
579 /*
580 * check if the first flag in format string is a singlechar flag
581 */
582again:
583 if (fmt[0] != '\0' &&
584 (fmt[1] == ',' || fmt[1] == '+' ||
585 fmt[1] == '~' || fmt[1] == '%' || fmt[1] == '\0'))
586 singlecharflag++;
587 /*
588 * check the whole format string for a match
589 */
590 for (;;) {
591 for (; *fmt; fmt++, argp++) {
592 if (*fmt == '\\') {
593 /*
594 * Allow "#?*&+" to appear inside a flag.
595 * NOTE: they must be escaped by '\\' only
596 * inside the the format string.
597 */
598 fmt++;
599 isspec = FALSE;
600 } else {
601 isspec = isfmtspec(*fmt);
602 }
603 /*
604 * If isspec is TRUE, the arg beeing checked starts
605 * like a valid flag. Argp now points to the rest.
606 */
607 if (isspec) {
608 /*
609 * If *argp is '+' and we are on the
610 * beginning of the arg that is currently
611 * checked, this cannot be an inc type flag.
612 */
613 if (*argp == '+' && argp == sargp)
614 continue;
615 /*
616 * skip over to arg of flag
617 */
618 if (*argp == '=') {
619 if (flags & NOEQUAL)
620 return (BADFLAG);
621 argp++;
622 } else if (*argp != '\0' && haseql) {
623 /*
624 * Flag and arg are not separated by a
625 * space.
626 * Check here for:
627 * xxxxx=yyyyy match on '&'
628 * Checked before:
629 * abc=yyyyy match on 'abc&'
630 * or 'abc*'
631 * or 'abc#'
632 * We come here if 'argp' starts with
633 * the same sequence as a valid flag
634 * and contains an equal sign.
635 * We have tested before if the text
636 * before 'argp' matches exactly.
637 * At this point we have no exact match
638 * and we only allow to match
639 * the special pattern '&'.
640 * We need this e.g. for 'make'.
641 * We allow any flag type argument to
642 * match the format string "&" to set
643 * up a function that handles all odd
644 * stuff that getargs will not grok.
645 * In addition, to allow getargs to be
646 * used for CPP type flags we allow to
647 * match -Dabc=xyz on 'D&'. Note that
648 * Dabc=xyz will not match 'D&'.
649 */
650 if ((!hasdash && argp != sargp) || *fmt != '&')
651 goto nextarg;
652 }
653
654 /*
655 * The format string 'f* ' may be used
656 * to disallow -ffoo for f*
657 *
658 * The same behavior is implemented for
659 * 'f# '. 'f? ' and 'f& '.
660 */
661 if (!haseql && *argp != '\0' &&
662 (fmt[0] == '*' || fmt[0] == '#' ||
663 fmt[0] == '?' || fmt[0] == '&') &&
664 fmt[1] == ' ') {
665 goto nextarg;
666 }
667
668 /*
669 * *arpp == '\0' || !haseql
670 * We come here if 'argp' starts with
671 * the same sequence as a valid flag.
672 * This will match on the following args:
673 * -farg match on 'f*'
674 * -f12 match on 'f#'
675 * +12 match on '+#'
676 * -12 match on '#'
677 * and all args that are separated from
678 * their flags.
679 * In the switch statement below, we check
680 * if the text after 'argp' (if *argp != 0) or
681 * the next arg is a valid arg for this flag.
682 */
683 break;
684 } else if (*fmt == *argp) {
685 if (argp[1] == '\0' &&
686 (fmt[1] == '\0' || fmt[1] == ',')) {
687
688 if (flags & SETARGS)
689 *((int *)curarg) = TRUE;
690
691
692 return (checkfmt(fmt)); /* XXX */
693 }
694 } else {
695 /*
696 * skip over to next format identifier
697 * & reset arg pointer
698 */
699 nextarg:
700 while (*fmt != ',' && *fmt != '\0') {
701 /* function has extra arg on stack */
702 if ((*fmt == '&' || *fmt == '~') &&
703 (flags & (SETARGS|ARGVECTOR)) == SETARGS) {
704 curarg = va_arg(args, void *);
705 }
706 fmt++;
707 }
708 argp = sargp;
709 break;
710 }
711 }
712 switch (*fmt) {
713
714 case '\0':
715 /*
716 * Boolean type has been tested before.
717 */
718 if (flags & ARGVECTOR) {
719 if (flagp[1].ga_format != NULL) {
720 flagp++;
721 sfmt = fmt = flagp->ga_format;
722 if (flags & SETARGS)
723 curarg = flagp->ga_arg;
724 argp = sargp;
725 goto again;
726 }
727 }
728 if (singlecharflag && !doubledash &&
729 (val = dosflags(sargp, vfmt, pac, pav,
730 flags & ~SETARGS,
731 va_dummy)) == BADFLAG) {
732 return (val);
733 }
734 if (singlecharflag && !doubledash &&
735 (val = dosflags(sargp, vfmt, pac, pav,
736 flags,
737 oargs)) != BADFLAG) {
738 return (val);
739 }
740 return (BADFLAG);
741
742 case ',':
743 fmt++;
744 if (fmt[0] == '\0') /* Should we allow "a,b,c,"? */
745 return (BADFMT);
746 if (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0')
747 singlecharflag++;
748 if ((flags & (SETARGS|ARGVECTOR)) == SETARGS)
749 curarg = va_arg(args, void *);
750 continue;
751
752 case '*':
753 if (*argp == '\0' && fmt[1] != '_') {
754 if (*pac > 1) {
755 (*pac)--;
756 (*pav)++;
757 argp = **pav;
758 } else {
759 return (BADFLAG);
760 }
761 }
762 if (fmt[1] == '_') /* To disallow -f foo for f* */
763 fmt++;
764 else if (fmt[1] == ' ') /* To disallow -ffoo for f* */
765 fmt++;
766
767 if (flags & SETARGS)
768 *((const char **)curarg) = argp;
769
770
771 return (checkfmt(fmt));
772
773 case '?':
774 if (*argp == '\0' && fmt[1] != '_') {
775 if (*pac > 1) {
776 (*pac)--;
777 (*pav)++;
778 argp = **pav;
779 } else {
780 return (BADFLAG);
781 }
782 }
783 if (fmt[1] == '_') /* To disallow -f c for f? */
784 fmt++;
785 else if (fmt[1] == ' ') /* To disallow -fc for f? */
786 fmt++;
787
788 /*
789 * Allow -f '' to specify a nul character.
790 * If more than one char arg, it
791 * cannot be a character argument.
792 */
793 if (argp[0] != '\0' && argp[1] != '\0')
794 goto nextchance;
795
796 if (flags & SETARGS)
797 *((char *)curarg) = *argp;
798
799
800 return (checkfmt(fmt));
801
802 case '+':
803 /*
804 * inc type is similar to boolean,
805 * there is no arg in argp to convert.
806 */
807 if (*argp != '\0')
808 goto nextchance;
809 /*
810 * If *fmt is '+' and we are on the beginning
811 * of the format desciptor that is currently
812 * checked, this cannot be an inc type flag.
813 */
814 if (fmt == sfmt || fmt[-1] == ',')
815 goto nextchance;
816
817 fmtp = fmt;
818 if (fmt[1] == 'l' || fmt[1] == 'L') {
819 if (fmt[2] == 'l' || fmt[2] == 'L') {
820 if (flags & SETARGS)
821 *((Llong *)curarg) += 1;
822 fmt += 2;
823 } else {
824 if (flags & SETARGS)
825 *((long *)curarg) += 1;
826 fmt++;
827 }
828 } else if (fmt[1] == 's' || fmt[1] == 'S') {
829 if (flags & SETARGS)
830 *((short *)curarg) += 1;
831 fmt++;
832 } else if (fmt[1] == 'c' || fmt[1] == 'C') {
833 if (flags & SETARGS)
834 *((char *)curarg) += 1;
835 fmt++;
836 } else {
837 if (fmt[1] == 'i' || fmt[1] == 'I')
838 fmt++;
839 if (flags & SETARGS)
840 *((int *)curarg) += 1;
841 }
842
843
844 return (checkfmt(fmt));
845
846 case '%':
847 /*
848 * inc type is similar to boolean,
849 * there is no arg in argp to convert.
850 */
851 if (*argp != '\0')
852 goto nextchance;
853
854 fmt++;
855 if (*fmt == '1')
856 val = TRUE;
857 else if (*fmt == '0')
858 val = FALSE;
859 else
860 goto nextchance;
861
862 fmtp = fmt;
863 llval = (Llong)val;
864 if (fmt[1] == 'l' || fmt[1] == 'L') {
865 if (fmt[2] == 'l' || fmt[2] == 'L') {
866 if (flags & SETARGS)
867 *((Llong *)curarg) = llval;
868 fmt += 2;
869 } else {
870 if (flags & SETARGS)
871 *((long *)curarg) = val;
872 fmt++;
873 }
874 } else if (fmt[1] == 's' || fmt[1] == 'S') {
875 if (flags & SETARGS)
876 *((short *)curarg) = val;
877 fmt++;
878 } else if (fmt[1] == 'c' || fmt[1] == 'C') {
879 if (flags & SETARGS)
880 *((char *)curarg) = val;
881 fmt++;
882 } else {
883 if (fmt[1] == 'i' || fmt[1] == 'I')
884 fmt++;
885 if (flags & SETARGS)
886 *((int *)curarg) = val;
887 }
888
889
890 return (checkfmt(fmt));
891
892 case '#':
893 if (*argp == '\0' && fmt[1] != '_') {
894 if (*pac > 1) {
895 (*pac)--;
896 (*pav)++;
897 argp = **pav;
898 } else {
899 return (BADFLAG);
900 }
901 }
902 if (fmt[1] == '_') /* To disallow -f 123 for f# */
903 fmt++;
904 else if (fmt[1] == ' ') /* To disallow -f123 for f# */
905 fmt++;
906
907 if (*astoll(argp, &llval) != '\0') {
908 /*
909 * arg is not a valid number!
910 * go to next format in the format string
911 * and check if arg matches any other type
912 * in the format specs.
913 */
914 nextchance:
915 while (*fmt != ',' && *fmt != '\0') {
916 if ((*fmt == '&' || *fmt == '~') &&
917 (flags & (SETARGS|ARGVECTOR)) == SETARGS) {
918 curarg = va_arg(args, void *);
919 }
920 fmt++;
921 }
922 argp = sargp;
923 *pac = spac;
924 *pav = spav;
925 continue;
926 }
927 fmtp = fmt;
928 val = (long)llval;
929 if (fmt[1] == 'l' || fmt[1] == 'L') {
930 if (fmt[2] == 'l' || fmt[2] == 'L') {
931 if (flags & SETARGS)
932 *((Llong *)curarg) = llval;
933 fmt += 2;
934 } else {
935 if (flags & SETARGS)
936 *((long *)curarg) = val;
937 fmt++;
938 }
939 } else if (fmt[1] == 's' || fmt[1] == 'S') {
940 if (flags & SETARGS)
941 *((short *)curarg) = (short)val;
942 fmt++;
943 } else if (fmt[1] == 'c' || fmt[1] == 'C') {
944 if (flags & SETARGS)
945 *((char *)curarg) = (char)val;
946 fmt++;
947 } else {
948 if (fmt[1] == 'i' || fmt[1] == 'I')
949 fmt++;
950 if (flags & SETARGS)
951 *((int *)curarg) = (int)val;
952 }
953
954 return (checkfmt(fmt));
955
956 case '~':
957 if (*argp != '\0')
958 goto nextchance;
959 if (haseql) {
960 return (BADFLAG);
961 }
962 goto callfunc;
963
964 case '&':
965 if (*argp == '\0' && fmt[1] != '_') {
966 if (*pac > 1) {
967 (*pac)--;
968 (*pav)++;
969 argp = **pav;
970 } else {
971 return (BADFLAG);
972 }
973 }
974 callfunc:
975
976 if (*fmt == '&' && fmt[1] == '_') /* To disallow -f foo for f& */
977 fmt++;
978 else if (fmt[1] == ' ') /* To disallow -ffoo for f& */
979 fmt++;
980 if ((val = checkfmt(fmt)) != NOTAFLAG)
981 return (val);
982
983 fmtp = sargp;
984 if (hasdash)
985 fmtp--;
986 if (doubledash)
987 fmtp--;
988 if ((flags & (SETARGS|ARGVECTOR)) == (SETARGS|ARGVECTOR)) {
989 int ret;
990
991 if (flagp->ga_funcp == NULL)
992 return (BADFMT);
993
994 ret = ((*flagp->ga_funcp) (argp, flagp->ga_arg,
995 pac, pav, fmtp));
996 if (ret != NOTAFILE)
997 return (ret);
998 fmt++;
999 } else
1000 if (flags & SETARGS) {
1001 int ret;
1002 void *funarg = va_arg(args, void *);
1003
1004 if (curarg == NULL)
1005 return (BADFMT);
1006 ret = ((*(getpargfun)curarg) (argp, funarg,
1007 pac, pav, fmtp));
1008 if (ret != NOTAFILE)
1009 return (ret);
1010 fmt++;
1011 } else {
1012 return (val);
1013 }
1014 /*
1015 * Called function returns NOTAFILE: try next format.
1016 */
1017 }
1018 }
1019}
char * va_list
Definition: acmsvcex.h:78
#define va_arg(ap, T)
Definition: acmsvcex.h:89
char * astoll(const char *s, Llong *l)
Definition: astoll.c:56
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLfloat * val
Definition: glext.h:7180
#define long
Definition: qsort.c:33
Llong llval
Definition: format.c:276
const char * sfmt
Definition: format.c:263
#define args
Definition: format.c:66
va_list oargs
Definition: format.c:255
void * ga_arg
Definition: getargs.h:92
getpargfun ga_funcp
Definition: getargs.h:93
const char * ga_format
Definition: getargs.h:91
long Llong
Definition: stdint.h:152
#define BADFLAG
Definition: getargs.c:75
#define SETARGS
Definition: getargs.c:91
LOCAL va_list va_dummy
Definition: getargs.c:111
#define isfmtspec(c)
Definition: getargs.c:115
LOCAL int checkfmt(char *fmt) const
Definition: getargs.c:1297
#define ARGVECTOR
Definition: getargs.c:92
LOCAL int dosflags(const char *argp, void *vfmt, int *pac, char *const **pav, int flags, va_list oargs)
Definition: getargs.c:1035
#define va_copy(d, s)
Definition: vadefs.h:89

Referenced by _getargs().

◆ dosflags()

LOCAL int dosflags ( const char argp,
void vfmt,
int pac,
char *const **  pav,
int  flags,
va_list  oargs 
)

Definition at line 1035 of file getargs.c.

1042{
1043 register const char *fmt = (const char *)vfmt;
1044 struct ga_flags *flagp = vfmt;
1045#define MAXSF 64
1046 sflags sf[MAXSF];
1047 char fl[256];
1048 va_list args;
1049 register sflags *rsf = sf;
1050 register int nsf = 0;
1051 register const char *p = argp;
1052 register int i;
1053 register void *curarg = (void *)0;
1054 getpargfun curfun = 0;
1055 char type;
1056
1057 /*
1058 * Initialize 'args' to the start of the argument list.
1059 * I don't know any portable way to copy an arbitrary
1060 * C object so I use a system-specific routine
1061 * (probably a macro) from stdarg.h. (Remember that
1062 * if va_list is an array, 'args' will be a pointer
1063 * and '&args' won't be what I would need for memcpy.)
1064 * It is a system requirement for SVr4 compatibility
1065 * to be able to do this assgignement. If your system
1066 * defines va_list to be an array but does not define
1067 * va_copy() you are lost.
1068 * This is needed to make sure, that 'oargs' will not
1069 * be clobbered.
1070 */
1071 va_copy(args, oargs);
1072
1073 if (flags & ARGVECTOR) {
1074 fmt = flagp->ga_format;
1075 if (fmt == NULL)
1076 fmt = "";
1077 if (flags & SETARGS) {
1078 curarg = flagp->ga_arg;
1079 curfun = flagp->ga_funcp;
1080 }
1081 } else if (flags & SETARGS) {
1082 /*
1083 * We set curfun to curarg. We later get the real
1084 * curarg in case that we see a function callback
1085 * but we need curfun first in this case.
1086 */
1087 curarg = va_arg(args, void *);
1088 curfun = (getpargfun)curarg;
1089 }
1090
1091 for (i = 0; i < sizeof (fl); i++) {
1092 fl[i] = 0;
1093 }
1094 while (*p) {
1095 for (i = 0; i < nsf; i++) {
1096 if (rsf[i].c == *p)
1097 break;
1098 }
1099 if (i >= MAXSF) {
1100 va_end(args);
1101 return (BADFLAG);
1102 }
1103 if (i == nsf) {
1104 rsf[i].curarg = (void *)0;
1105 rsf[i].curfun = (void *)0;
1106 rsf[i].c = *p;
1107 rsf[i].type = (char)-1;
1108 rsf[i].fmt = '\0';
1109 rsf[i].val = (char)TRUE;
1110 nsf++;
1111 }
1112 fl[*p & 0xFF] = i;
1113 p++;
1114 }
1115
1116again:
1117 while (*fmt) {
1118 if (!isfmtspec(*fmt) &&
1119 (fmt[1] == ',' || fmt[1] == '+' ||
1120 fmt[1] == '~' || fmt[1] == '%' || fmt[1] == '\0') &&
1121 strchr(argp, *fmt)) {
1122 for (i = 0; i < nsf; i++) {
1123 if (rsf[i].c == *fmt) {
1124 if (fmt[1] == '+') {
1125 rsf[i].fmt = '+';
1126 fmt++;
1127 if (fmt[1] == ',' ||
1128 fmt[1] == '\0') {
1129 rsf[i].type = 'i';
1130 } else if ((fmt[1] == 'l' ||
1131 fmt[1] == 'L') &&
1132 (fmt[2] == 'l' ||
1133 fmt[2] == 'L')) {
1134 /*
1135 * Type 'Q'uad (ll)
1136 */
1137 rsf[i].type = 'Q';
1138 fmt++;
1139 } else {
1140 /*
1141 * Type 'l','i','s','c'
1142 */
1143 rsf[i].type = fmt[1];
1144 }
1145 } else if (fmt[1] == '%') {
1146 fmt++;
1147 rsf[i].fmt = '%';
1148 if (fmt[1] == '0')
1149 rsf[i].val = (char)FALSE;
1150 else if (fmt[1] == '1')
1151 rsf[i].val = (char)TRUE;
1152 fmt++;
1153 if (fmt[1] == ',' ||
1154 fmt[1] == '\0') {
1155 rsf[i].type = 'i';
1156 } else if ((fmt[1] == 'l' ||
1157 fmt[1] == 'L') &&
1158 (fmt[2] == 'l' ||
1159 fmt[2] == 'L')) {
1160 /*
1161 * Type 'Q'uad (ll)
1162 */
1163 rsf[i].type = 'Q';
1164 fmt++;
1165 } else {
1166 /*
1167 * Type 'l','i','s','c'
1168 */
1169 rsf[i].type = fmt[1];
1170 }
1171 } else if (fmt[1] == '~') {
1172 /*
1173 * Let fmt point to ',' to
1174 * prevent to fetch the
1175 * func arg twice.
1176 */
1177 fmt += 2;
1178 rsf[i].fmt = '~';
1179 rsf[i].type = '~';
1180 rsf[i].curfun = (void *)curfun;
1181 if ((flags & (SETARGS|ARGVECTOR)) == SETARGS)
1182 curarg = va_arg(args, void *);
1183 } else {
1184 /*
1185 * ',' or '\0' for BOOL
1186 */
1187 rsf[i].type = fmt[1];
1188 }
1189 rsf[i].curarg = curarg;
1190 break;
1191 }
1192 }
1193 }
1194 while (*fmt != ',' && *fmt != '\0') {
1195 /*
1196 * function has extra arg on stack. The code above
1197 * prevents us from fetching this arg twice.
1198 */
1199 if ((*fmt == '&' || *fmt == '~') &&
1200 (flags & (SETARGS|ARGVECTOR)) == SETARGS) {
1201 curarg = va_arg(args, void *);
1202 }
1203 fmt++;
1204 }
1205 if (*fmt != '\0')
1206 fmt++;
1207 else
1208 break;
1209
1210 if ((flags & (SETARGS|ARGVECTOR)) == SETARGS) {
1211 /*
1212 * We set curfun to curarg. We later get the real
1213 * curarg in case that we see a function callback
1214 * but we need curfun first in this case.
1215 */
1216 curarg = va_arg(args, void *);
1217 curfun = (getpargfun)curarg;
1218 }
1219 }
1220 if ((flags & ARGVECTOR) && flagp[1].ga_format != NULL) {
1221 flagp++;
1222 fmt = flagp->ga_format;
1223 if (flags & SETARGS) {
1224 curarg = flagp->ga_arg;
1225 curfun = flagp->ga_funcp;
1226 }
1227 goto again;
1228 }
1229
1230 for (p = argp; *p; p++) {
1231 char tfmt;
1232
1233 i = fl[*p & 0xFF];
1234 tfmt = rsf[i].fmt;
1235 type = rsf[i].type;
1236 if (type == (char)-1) {
1237 return (BADFLAG);
1238 }
1239
1240 if ((flags & SETARGS) &&
1241 (rsf[i].curfun || rsf[i].curarg)) {
1242 if (type == ',' || type == '\0') {
1243 *((int *)rsf[i].curarg) = TRUE;
1244 } else if (type == 'i' || type == 'I') {
1245 if (tfmt == '+')
1246 *((int *)rsf[i].curarg) += 1;
1247 else
1248 *((int *)rsf[i].curarg) = rsf[i].val;
1249 } else if (type == 'l' || type == 'L') {
1250 if (tfmt == '+')
1251 *((long *)rsf[i].curarg) += 1;
1252 else
1253 *((long *)rsf[i].curarg) = rsf[i].val;
1254 } else if (type == 'Q') {
1255 if (tfmt == '+')
1256 *((Llong *)rsf[i].curarg) += 1;
1257 else
1258 *((Llong *)rsf[i].curarg) = rsf[i].val;
1259 } else if (type == 's' || type == 'S') {
1260 if (tfmt == '+')
1261 *((short *)rsf[i].curarg) += 1;
1262 else
1263 *((short *)rsf[i].curarg) = rsf[i].val;
1264 } else if (type == 'c' || type == 'C') {
1265 if (tfmt == '+')
1266 *((char *)rsf[i].curarg) += 1;
1267 else
1268 *((char *)rsf[i].curarg) = rsf[i].val;
1269 } else if (type == '~') {
1270 int ret;
1271 char cfmt[3];
1272
1273 cfmt[0] = '-';
1274 cfmt[1] = rsf[i].c;
1275 cfmt[2] = '\0';
1276
1277 if (rsf[i].curfun == NULL)
1278 return (BADFMT);
1279 ret = ((*(getpargfun)rsf[i].curfun) ("",
1280 rsf[i].curarg,
1281 pac, pav, cfmt));
1282 return (ret);
1283 } else {
1284 return (BADFLAG);
1285 }
1286 }
1287 }
1288 return (NOTAFLAG);
1289}
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define va_end(ap)
Definition: acmsvcex.h:90
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void * curfun
Definition: getargs.c:1027
void * curarg
Definition: getargs.c:1026
char type
Definition: getargs.c:1029
char val
Definition: getargs.c:1031
char fmt
Definition: getargs.c:1030
char c
Definition: getargs.c:1028
#define MAXSF
_In_ FLONG fl
Definition: winddi.h:1279

Referenced by doflag().

◆ getallargs()

EXPORT int getallargs ( int pac,
pav  ,
char fmt,
va_alist   
)

Definition at line 245 of file getargs.c.

251{
253 int ret;
254
255#ifdef PROTOTYPES
256 va_start(args, fmt);
257#else
258 va_start(args);
259#endif
260 for (; ; (*pac)--, (*pav)++) {
261 if ((ret = _getargs(pac, pav, (void *)fmt, SETARGS, GA_NO_PROPS, args)) < NOTAFLAG)
262 break;
263 }
264 va_end(args);
265 return (ret);
266}
#define va_start(ap, A)
Definition: acmsvcex.h:91
EXPORT int _getargs(int *pac, char *const **pav, void *vfmt, int flags, struct ga_props *props, va_list args)
Definition: getargs.c:395

◆ getargerror()

EXPORT char * getargerror ( int  err)

Definition at line 1335 of file getargs.c.

1337{
1338 if (err < RETMIN || err > RETMAX)
1339 return ("Illegal arg error");
1340 return (RNAME(err));
1341}
#define err(...)
#define RNAME(a)
Definition: getargs.c:88
#define RETMAX
Definition: getargs.c:71

Referenced by main().

◆ getargs()

EXPORT int getargs ( int pac,
pav  ,
char fmt,
va_alist   
)

Definition at line 170 of file getargs.c.

176{
178 int ret;
179
180#ifdef PROTOTYPES
181 va_start(args, fmt);
182#else
183 va_start(args);
184#endif
185 ret = _getargs(pac, pav, (void *)fmt, SETARGS, GA_NO_PROPS, args);
186 va_end(args);
187 return (ret);
188}

◆ getfiles()

EXPORT int getfiles ( int pac,
pav  ,
const char fmt 
)

Definition at line 342 of file getargs.c.

346{
347 return (_getargs(pac, pav, (void *)fmt, SCANONLY, GA_NO_PROPS, va_dummy));
348}
#define SCANONLY
Definition: getargs.c:90

◆ getlallargs()

EXPORT int getlallargs ( int pac,
pav  ,
struct ga_props props,
char fmt,
va_alist   
)

Definition at line 278 of file getargs.c.

285{
287 int ret;
288
289#ifdef PROTOTYPES
290 va_start(args, fmt);
291#else
292 va_start(args);
293#endif
295 for (; ; (*pac)--, (*pav)++) {
296 if ((ret = _getargs(pac, pav, (void *)fmt, SETARGS, props, args)) < NOTAFLAG)
297 break;
298 /*
299 * The default is to parse all options on the command line and
300 * to let "--" only make the next argument a non-option.
301 */
302 if (ret == FLAGDELIM && (props->ga_flags & GAF_DELIM_DASHDASH))
303 break;
304 }
305 va_end(args);
306 return (ret);
307}
#define GAF_DELIM_DASHDASH
Definition: getargs.h:116

◆ getlargs()

EXPORT int getlargs ( int pac,
pav  ,
struct ga_props props,
char fmt,
va_alist   
)

Definition at line 200 of file getargs.c.

207{
209 int ret;
210
211#ifdef PROTOTYPES
212 va_start(args, fmt);
213#else
214 va_start(args);
215#endif
216 ret = _getargs(pac, pav, (void *)fmt, SETARGS, props, args);
217 va_end(args);
218 return (ret);
219}

◆ getlfiles()

EXPORT int getlfiles ( int pac,
pav  ,
struct ga_props props,
const char fmt 
)

Definition at line 356 of file getargs.c.

361{
362 return (_getargs(pac, pav, (void *)fmt, SCANONLY, props, va_dummy));
363}

◆ getvallargs()

EXPORT int getvallargs ( int pac,
pav  ,
struct ga_props props,
struct ga_flags vfmt 
)

Definition at line 314 of file getargs.c.

319{
320 int ret;
321
323 for (; ; (*pac)--, (*pav)++) {
324 if ((ret = _getargs(pac, pav, vfmt, SETARGS | ARGVECTOR, props, va_dummy)) < NOTAFLAG)
325 break;
326 /*
327 * The default is to parse all options on the command line and
328 * to let "--" only make the next argument a non-option.
329 */
330 if (ret == FLAGDELIM && (props->ga_flags & GAF_DELIM_DASHDASH))
331 break;
332 }
333 return (ret);
334}

◆ getvargs()

EXPORT int getvargs ( int pac,
pav  ,
struct ga_props props,
struct ga_flags vfmt 
)

Definition at line 226 of file getargs.c.

231{
232 return (_getargs(pac, pav, vfmt, SETARGS | ARGVECTOR, props, va_dummy));
233}

Referenced by main().

◆ getvfiles()

EXPORT int getvfiles ( int pac,
pav  ,
struct ga_props props,
struct ga_flags vfmt 
)

Definition at line 371 of file getargs.c.

376{
377 return (_getargs(pac, pav, vfmt, SCANONLY | ARGVECTOR, props, va_dummy));
378}

Variable Documentation

◆ fmtspecs

LOCAL char fmtspecs[] = "#?*&~+%"

Definition at line 113 of file getargs.c.

◆ props_default

LOCAL struct ga_props props_default = { 0, 0, sizeof (struct ga_props) }

Definition at line 117 of file getargs.c.

Referenced by _getprops().

◆ props_posix

Definition at line 118 of file getargs.c.

Referenced by _getprops().

◆ retnames

LOCAL char* retnames[]
Initial value:
= {
"NOTAFILE",
"BADFMT",
"BADFLAG",
"NOARGS",
"NOTAFLAG",
"FLAGDELIM",
}

Definition at line 80 of file getargs.c.

◆ sccsid

UConst char sccsid[]
static
Initial value:
=
"@(#)getargs.c 2.71 17/07/16 Copyright 1985, 1988, 1994-2017 J. Schilling"

Definition at line 4 of file getargs.c.

◆ va_dummy

LOCAL va_list va_dummy

Definition at line 111 of file getargs.c.

Referenced by doflag(), getfiles(), getlfiles(), getvallargs(), getvargs(), and getvfiles().