ReactOS 0.4.16-dev-340-g0540c21
getargs.c
Go to the documentation of this file.
1/* @(#)getargs.c 2.71 17/07/16 Copyright 1985, 1988, 1994-2017 J. Schilling */
2#include <schily/mconfig.h>
3#ifndef lint
4static UConst char sccsid[] =
5 "@(#)getargs.c 2.71 17/07/16 Copyright 1985, 1988, 1994-2017 J. Schilling";
6#endif
7#define NEW
8/*
9 * Copyright (c) 1985, 1988, 1994-2017 J. Schilling
10 *
11 * 1.3.88 Start implementation of release 2
12 */
13/*
14 * Parse arguments on a command line.
15 * Format string type specifier (appearing directly after flag name):
16 * '' BOOL size int set to TRUE (1)
17 * '%' Extended format, next char determines the type:
18 * '%0' BOOL with size modifier set to FALSE (0)
19 * '%1' BOOL with size modifier set to TRUE(1)
20 * '*' string
21 * '?' char
22 * '#' number
23 * '&' call function for any type flag
24 * '~' call function for BOOLEAN flag
25 * '+' inctype +++ NEU +++
26 *
27 * The format string 'f* ' may be used to disallow -ffoo for f*
28 * The same behavior is implemented for 'f# ', 'f? ' and 'f& '.
29 * The ' ' needs to immediately follow the format type specifier.
30 *
31 * The format string 'f*_' may be used to disallow -f foo for f*
32 * The same behavior is implemented for 'f#_', 'f?_' and 'f&_'.
33 * The '_' needs to immediately follow the format type specifier.
34 * This also allows to implement optional arguments to options.
35 * Note: 'f#_' is only implemented for orthogonality, -f will
36 * be converted to an integer value of 0.
37 *
38 * The '#', '+' and '%[01]' types may have size modifiers added:
39 * 'c'/'C' char
40 * 's'/'S' short
41 * 'i'/'I' int (default == no size modifier)
42 * 'l'/'L' long
43 * 'll'/'LL' long long
44 */
45/*
46 * The contents of this file are subject to the terms of the
47 * Common Development and Distribution License, Version 1.0 only
48 * (the "License"). You may not use this file except in compliance
49 * with the License.
50 *
51 * See the file CDDL.Schily.txt in this distribution for details.
52 * A copy of the CDDL is also available via the Internet at
53 * http://www.opensource.org/licenses/cddl1.txt
54 *
55 * When distributing Covered Code, include this CDDL HEADER in each
56 * file and include the License file CDDL.Schily.txt from this distribution.
57 */
58/* LINTLIBRARY */
59#include <schily/mconfig.h>
60#include <schily/standard.h>
61#include <schily/utypes.h>
62#include <schily/getargs.h>
63#include <schily/varargs.h>
64#include <schily/string.h>
65#include <schily/schily.h>
66#include <schily/ctype.h>
67
68/*
69 * Various return values
70 */
71#define RETMAX 2 /* Max. value for getargerror() */
72#define FLAGDELIM 2 /* "--" stopped flag processing */
73#define NOTAFLAG 1 /* Not a flag type argument */
74#define NOARGS 0 /* No more args */
75#define BADFLAG (-1) /* Not a valid flag argument */
76#define BADFMT (-2) /* Error in format string */
77#define NOTAFILE (-3) /* Seems to be a flag type arg */
78#define RETMIN (-3) /* Min. value for getargerror() */
79
80LOCAL char *retnames[] = {
81 "NOTAFILE",
82 "BADFMT",
83 "BADFLAG",
84 "NOARGS",
85 "NOTAFLAG",
86 "FLAGDELIM",
87};
88#define RNAME(a) (retnames[(a)-RETMIN])
89
90#define SCANONLY 0 /* Do not try to set argument values */
91#define SETARGS 1 /* Set argument values from cmdline */
92#define ARGVECTOR 2 /* Use vector instead of list interface */
93#define NOEQUAL 4 /* -opt=val not allowed for -opt val */
94
95LOCAL struct ga_props *_getprops __PR((struct ga_props *));
96
97 int _getargs __PR((int *, char *const **, void *,
98 int,
99 struct ga_props *,
100 va_list));
101LOCAL int dofile __PR((int *, char *const **, const char **,
102 struct ga_props *));
103LOCAL int doflag __PR((int *, char *const **, const char *,
104 void *, int, va_list));
105LOCAL int dosflags __PR((const char *, void *,
106 int *, char *const **,
107 int, va_list));
108LOCAL int checkfmt __PR((const char *));
109LOCAL int checkeql __PR((const char *));
110
112
113LOCAL char fmtspecs[] = "#?*&~+%";
114
115#define isfmtspec(c) (strchr(fmtspecs, c) != NULL)
116
117LOCAL struct ga_props props_default = { 0, 0, sizeof (struct ga_props) };
118LOCAL struct ga_props props_posix = { GAF_POSIX_DEFAULT, 0, sizeof (struct ga_props) };
119
120EXPORT int
122 struct ga_props *props;
123 size_t size;
124 UInt32_t flags;
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}
141
142LOCAL struct ga_props *
144 struct ga_props *props;
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}
160
161/*
162 * get flags until a non flag type argument is reached (old version)
163 */
164/* VARARGS3 */
165#ifdef PROTOTYPES
166EXPORT int
167getargs(int *pac, char *const **pav, const char *fmt, ...)
168#else
169EXPORT int
170getargs(pac, pav, fmt, va_alist)
171 int *pac;
172 char **pav[];
173 char *fmt;
174 va_dcl
175#endif
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}
189
190
191/*
192 * get flags until a non flag type argument is reached (list version)
193 */
194/* VARARGS4 */
195#ifdef PROTOTYPES
196EXPORT int
197getlargs(int *pac, char *const **pav, struct ga_props *props, const char *fmt, ...)
198#else
199EXPORT int
200getlargs(pac, pav, props, fmt, va_alist)
201 int *pac;
202 char **pav[];
203 struct ga_props *props;
204 char *fmt;
205 va_dcl
206#endif
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}
220
221
222/*
223 * get flags until a non flag type argument is reached (vector version)
224 */
225EXPORT int
226getvargs(pac, pav, props, vfmt)
227 int *pac;
228 char * const *pav[];
229 struct ga_props *props;
230 struct ga_flags *vfmt;
231{
232 return (_getargs(pac, pav, vfmt, SETARGS | ARGVECTOR, props, va_dummy));
233}
234
235
236/*
237 * get all flags on the command line, do not stop on files (old version)
238 */
239/* VARARGS3 */
240#ifdef PROTOTYPES
241EXPORT int
242getallargs(int *pac, char *const **pav, const char *fmt, ...)
243#else
244EXPORT int
245getallargs(pac, pav, fmt, va_alist)
246 int *pac;
247 char **pav[];
248 char *fmt;
249 va_dcl
250#endif
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}
267
268
269/*
270 * get all flags on the command line, do not stop on files (list version)
271 */
272/* VARARGS4 */
273#ifdef PROTOTYPES
274EXPORT int
275getlallargs(int *pac, char *const **pav, struct ga_props *props, const char *fmt, ...)
276#else
277EXPORT int
278getlallargs(pac, pav, props, fmt, va_alist)
279 int *pac;
280 char **pav[];
281 struct ga_props *props;
282 char *fmt;
283 va_dcl
284#endif
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}
308
309
310/*
311 * get all flags on the command line, do not stop on files (vector version)
312 */
313EXPORT int
314getvallargs(pac, pav, props, vfmt)
315 int *pac;
316 char * const *pav[];
317 struct ga_props *props;
318 struct ga_flags *vfmt;
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}
335
336
337/*
338 * get next non flag type argument (i.e. a file) (old version)
339 * getfiles() is a dry run getargs()
340 */
341EXPORT int
342getfiles(pac, pav, fmt)
343 int *pac;
344 char *const *pav[];
345 const char *fmt;
346{
347 return (_getargs(pac, pav, (void *)fmt, SCANONLY, GA_NO_PROPS, va_dummy));
348}
349
350
351/*
352 * get next non flag type argument (i.e. a file) (list version)
353 * getlfiles() is a dry run getlargs()
354 */
355EXPORT int
356getlfiles(pac, pav, props, fmt)
357 int *pac;
358 char *const *pav[];
359 struct ga_props *props;
360 const char *fmt;
361{
362 return (_getargs(pac, pav, (void *)fmt, SCANONLY, props, va_dummy));
363}
364
365
366/*
367 * get next non flag type argument (i.e. a file) (vector version)
368 * getvfiles() is a dry run getvargs()
369 */
370EXPORT int
371getvfiles(pac, pav, props, vfmt)
372 int *pac;
373 char *const *pav[];
374 struct ga_props *props;
375 struct ga_flags *vfmt;
376{
377 return (_getargs(pac, pav, vfmt, SCANONLY | ARGVECTOR, props, va_dummy));
378}
379
380
381/*
382 * check args until the next non flag type argmument is reached
383 * *pac is decremented, *pav is incremented so that the
384 * non flag type argument is at *pav[0]
385 *
386 * return code:
387 * +2 FLAGDELIM "--" stopped flag processing
388 * +1 NOTAFLAG not a flag type argument (is a file)
389 * 0 NOARGS no more args
390 * -1 BADFLAG a non-matching flag type argument
391 * -2 BADFMT bad syntax in format string
392 */
393/* LOCAL int */
394EXPORT int
395_getargs(pac, pav, vfmt, flags, props, args)
396 register int *pac;
397 register char *const **pav;
398 void *vfmt;
399 int flags;
400 struct ga_props *props;
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}
427
428
429/*
430 * check if *pargp is a file type argument
431 */
432LOCAL int
433dofile(pac, pav, pargp, props)
434 register int *pac;
435 register char *const **pav;
436 const char **pargp;
437 struct ga_props *props;
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}
490
491
492/*
493 * compare argp with the format string
494 * if a match is found store the result a la scanf in one of the
495 * arguments pointed to in the va_list
496 *
497 * If (flags & SETARGS) == 0, only check arguments for getfiles()
498 * In case that (flags & SETARGS) == 0 or that (flags & ARGVECTOR) != 0,
499 * va_list may be a dummy argument.
500 */
501LOCAL int
502doflag(pac, pav, argp, vfmt, flags, oargs)
503 int *pac;
504 char *const **pav;
505 register const char *argp;
506 void *vfmt;
507 int flags;
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}
1020
1021
1022/*
1023 * parse args for combined single char flags
1024 */
1025typedef struct {
1026 void *curarg; /* The pointer to the arg to modify */
1027 void *curfun; /* The pointer to the function to call */
1028 char c; /* The single char flag character */
1029 char type; /* The type of the single char flag */
1030 char fmt; /* The format type of the single char flag */
1031 char val; /* The value to assign for BOOL flags */
1032} sflags;
1033
1034LOCAL int
1035dosflags(argp, vfmt, pac, pav, flags, oargs)
1036 register const char *argp;
1037 void *vfmt;
1038 int *pac;
1039 char *const **pav;
1040 int flags;
1041 va_list oargs;
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}
1290
1291/*
1292 * If the next format character is a comma or the string delimiter,
1293 * there are no invalid format specifiers. Return success.
1294 * Otherwise raise the getarg_bad_format condition.
1295 */
1296LOCAL int
1298 const char *fmt;
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}
1312
1313/*
1314 * Parse the string as long as valid characters can be found.
1315 * Valid flag identifiers are chosen from the set of
1316 * alphanumeric characters, '-' and '_'.
1317 * If the next character is an equal sign the string
1318 * contains a valid flag identifier.
1319 */
1320LOCAL int
1322 register const char *str;
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}
1333
1334EXPORT char *
1336 int err;
1337{
1338 if (err < RETMIN || err > RETMAX)
1339 return ("Illegal arg error");
1340 return (RNAME(err));
1341}
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
char * astoll(const char *s, Llong *l)
Definition: astoll.c:56
#define UConst
Definition: ccomdefs.h:72
#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
#define GAF_NEED_DASH
Definition: getargs.h:114
#define GAF_NO_EQUAL
Definition: getargs.h:113
#define GAF_NO_PLUS
Definition: getargs.h:112
#define GAF_DELIM_DASHDASH
Definition: getargs.h:116
#define GA_POSIX_PROPS
Definition: getargs.h:106
#define GAF_POSIX
Definition: getargs.h:117
#define GA_NO_PROPS
Definition: getargs.h:105
#define GAF_POSIX_DEFAULT
Definition: getargs.h:132
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
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
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define LOCAL(type)
Definition: jmorecfg.h:289
#define c
Definition: ke_i.h:80
#define __PR(a)
Definition: prototyp.h:106
#define long
Definition: qsort.c:33
EXPORT void raisecond(char *signame, long arg2) const
Definition: raisecond.c:100
#define err(...)
const WCHAR * str
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
Definition: match.c:390
Definition: dsound.c:943
void * ga_arg
Definition: getargs.h:92
getpargfun ga_funcp
Definition: getargs.h:93
const char * ga_format
Definition: getargs.h:91
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
long Llong
Definition: stdint.h:152
LOCAL struct ga_props props_default
Definition: getargs.c:117
#define BADFLAG
Definition: getargs.c:75
#define BADFMT
Definition: getargs.c:76
EXPORT int _getarginit(struct ga_props *props, size_t size, UInt32_t flags)
Definition: getargs.c:121
LOCAL char * retnames[]
Definition: getargs.c:80
#define RNAME(a)
Definition: getargs.c:88
LOCAL int checkeql(const char *str)
Definition: getargs.c:1321
#define MAXSF
EXPORT int getlargs(int *pac, pav, struct ga_props *props, char *fmt, va_alist)
Definition: getargs.c:200
#define SETARGS
Definition: getargs.c:91
EXPORT int getfiles(int *pac, pav, const char *fmt)
Definition: getargs.c:342
EXPORT int getargs(int *pac, pav, char *fmt, va_alist)
Definition: getargs.c:170
static UConst char sccsid[]
Definition: getargs.c:4
LOCAL int doflag(int *pac, char *const **pav, const char *argp, void *vfmt, int flags, va_list oargs)
Definition: getargs.c:502
EXPORT int getlallargs(int *pac, pav, struct ga_props *props, char *fmt, va_alist)
Definition: getargs.c:278
LOCAL int dofile(int *pac, char *const **pav, const char **pargp, struct ga_props *props)
Definition: getargs.c:433
EXPORT int _getargs(int *pac, char *const **pav, void *vfmt, int flags, struct ga_props *props, va_list args)
Definition: getargs.c:395
LOCAL char fmtspecs[]
Definition: getargs.c:113
LOCAL va_list va_dummy
Definition: getargs.c:111
#define NOTAFILE
Definition: getargs.c:77
#define isfmtspec(c)
Definition: getargs.c:115
EXPORT int getallargs(int *pac, pav, char *fmt, va_alist)
Definition: getargs.c:245
#define NOEQUAL
Definition: getargs.c:93
EXPORT int getvallargs(int *pac, pav, struct ga_props *props, struct ga_flags *vfmt)
Definition: getargs.c:314
EXPORT int getvfiles(int *pac, pav, struct ga_props *props, struct ga_flags *vfmt)
Definition: getargs.c:371
#define RETMAX
Definition: getargs.c:71
LOCAL struct ga_props props_posix
Definition: getargs.c:118
#define NOTAFLAG
Definition: getargs.c:73
#define FLAGDELIM
Definition: getargs.c:72
#define NOARGS
Definition: getargs.c:74
LOCAL int checkfmt(char *fmt) const
Definition: getargs.c:1297
LOCAL struct ga_props * _getprops(struct ga_props *props)
Definition: getargs.c:143
EXPORT int getlfiles(int *pac, pav, struct ga_props *props, const char *fmt)
Definition: getargs.c:356
#define SCANONLY
Definition: getargs.c:90
#define ARGVECTOR
Definition: getargs.c:92
EXPORT char * getargerror(int err)
Definition: getargs.c:1335
LOCAL int dosflags(const char *argp, void *vfmt, int *pac, char *const **pav, int flags, va_list oargs)
Definition: getargs.c:1035
EXPORT int getvargs(int *pac, pav, struct ga_props *props, struct ga_flags *vfmt)
Definition: getargs.c:226
#define va_copy(d, s)
Definition: vadefs.h:120
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
_In_ FLONG fl
Definition: winddi.h:1279