xref: /aosp_15_r20/external/giflib/getarg.c (revision 324bb76b8d05e2a05aa88511fff61cf3f9ca5892)
1*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
2*324bb76bSAndroid Build Coastguard Worker 
3*324bb76bSAndroid Build Coastguard Worker getarg.c - routines to grab the parameters from the command line:
4*324bb76bSAndroid Build Coastguard Worker 
5*324bb76bSAndroid Build Coastguard Worker Names of all the routines except the main one start with GA (Get
6*324bb76bSAndroid Build Coastguard Worker Arguments) to prevent conflicts.
7*324bb76bSAndroid Build Coastguard Worker 
8*324bb76bSAndroid Build Coastguard Worker The following routines are available in this module:
9*324bb76bSAndroid Build Coastguard Worker 
10*324bb76bSAndroid Build Coastguard Worker 1. int GAGetArgs(argc, argv, CtrlStr, Variables...)
11*324bb76bSAndroid Build Coastguard Worker where argc, argv are received on entry.
12*324bb76bSAndroid Build Coastguard Worker CtrlStr is the contrl string (see below)
13*324bb76bSAndroid Build Coastguard Worker Variables are all the variables to be set according to CtrlStr.
14*324bb76bSAndroid Build Coastguard Worker Note that all the variables MUST be transfered by address.
15*324bb76bSAndroid Build Coastguard Worker Return 0 on correct parsing, otherwise error number (see GetArg.h).
16*324bb76bSAndroid Build Coastguard Worker 
17*324bb76bSAndroid Build Coastguard Worker 2. GAPrintHowTo(CtrlStr)
18*324bb76bSAndroid Build Coastguard Worker Print the control string to stderr, in the correct format.
19*324bb76bSAndroid Build Coastguard Worker This feature is very useful in case of an error during GetArgs parsing.
20*324bb76bSAndroid Build Coastguard Worker Chars equal to SPACE_CHAR are not printed (regular spaces are NOT
21*324bb76bSAndroid Build Coastguard Worker allowed, and so using SPACE_CHAR you can create space in PrintHowTo).
22*324bb76bSAndroid Build Coastguard Worker 
23*324bb76bSAndroid Build Coastguard Worker 3. GAPrintErrMsg(Error)
24*324bb76bSAndroid Build Coastguard Worker Describe the error to stderr, according to Error (usually returned by
25*324bb76bSAndroid Build Coastguard Worker GAGetArgs).
26*324bb76bSAndroid Build Coastguard Worker 
27*324bb76bSAndroid Build Coastguard Worker CtrlStr format:
28*324bb76bSAndroid Build Coastguard Worker 
29*324bb76bSAndroid Build Coastguard Worker The control string passed to GetArgs controls the way argv (argc) are
30*324bb76bSAndroid Build Coastguard Worker parsed. Each entry in this string must not have any spaces in it. The
31*324bb76bSAndroid Build Coastguard Worker First Entry is the name of the program, which is usually ignored except
32*324bb76bSAndroid Build Coastguard Worker when GAPrintHowTo is called. All the other entries (except the last one
33*324bb76bSAndroid Build Coastguard Worker which we will come back to later) must have the following format:
34*324bb76bSAndroid Build Coastguard Worker 
35*324bb76bSAndroid Build Coastguard Worker 1. One letter which sets the option letter.
36*324bb76bSAndroid Build Coastguard Worker 2. '!' or '%' to determines if this option is really optional ('%') or
37*324bb76bSAndroid Build Coastguard Worker    required ('!')...
38*324bb76bSAndroid Build Coastguard Worker 3. '-' must always be given.
39*324bb76bSAndroid Build Coastguard Worker 4. Alphanumeric string, usually ignored, but used by GAPrintHowTo to
40*324bb76bSAndroid Build Coastguard Worker    print the meaning of this option.
41*324bb76bSAndroid Build Coastguard Worker 5. Sequences starts with '!' or '%'. Again if '!' then this sequence
42*324bb76bSAndroid Build Coastguard Worker    must exist (only if its option flag is given of course), and if '%'
43*324bb76bSAndroid Build Coastguard Worker    it is optional. Each sequence will continue with one or two
44*324bb76bSAndroid Build Coastguard Worker    characters which defines the kind of the input:
45*324bb76bSAndroid Build Coastguard Worker a: d, x, o, u - integer is expected (decimal, hex, octal base or unsigned).
46*324bb76bSAndroid Build Coastguard Worker b: D, X, O, U - long integer is expected (same as above).
47*324bb76bSAndroid Build Coastguard Worker c: f - float number is expected.
48*324bb76bSAndroid Build Coastguard Worker d: F - double number is expected.
49*324bb76bSAndroid Build Coastguard Worker e: s - string is expected.
50*324bb76bSAndroid Build Coastguard Worker f: *? - any number of '?' kind (d, x, o, u, D, X, O, U, f, F, s)
51*324bb76bSAndroid Build Coastguard Worker    will match this one. If '?' is numeric, it scans until
52*324bb76bSAndroid Build Coastguard Worker    non-numeric input is given. If '?' is 's' then it scans
53*324bb76bSAndroid Build Coastguard Worker    up to the next option or end of argv.
54*324bb76bSAndroid Build Coastguard Worker 
55*324bb76bSAndroid Build Coastguard Worker If the last parameter given in the CtrlStr, is not an option (i.e. the
56*324bb76bSAndroid Build Coastguard Worker second char is not in ['!', '%'] and the third one is not '-'), all what
57*324bb76bSAndroid Build Coastguard Worker remained from argv is linked to it.
58*324bb76bSAndroid Build Coastguard Worker 
59*324bb76bSAndroid Build Coastguard Worker The variables passed to GAGetArgs (starting from 4th parameter) MUST
60*324bb76bSAndroid Build Coastguard Worker match the order of the CtrlStr:
61*324bb76bSAndroid Build Coastguard Worker 
62*324bb76bSAndroid Build Coastguard Worker For each option, one integer address must be passed. This integer must
63*324bb76bSAndroid Build Coastguard Worker be initialized with 0. If that option is given in the command line, it will
64*324bb76bSAndroid Build Coastguard Worker be set.
65*324bb76bSAndroid Build Coastguard Worker 
66*324bb76bSAndroid Build Coastguard Worker In addition, the sequences that might follow an option require the
67*324bb76bSAndroid Build Coastguard Worker following parameters to pass:
68*324bb76bSAndroid Build Coastguard Worker 
69*324bb76bSAndroid Build Coastguard Worker 1. d, x, o, u - pointer to integer (int *).
70*324bb76bSAndroid Build Coastguard Worker 2. D, X, O, U - pointer to long (long *).
71*324bb76bSAndroid Build Coastguard Worker 3. f - pointer to float (float *).
72*324bb76bSAndroid Build Coastguard Worker 4. F - pointer to double (double *).
73*324bb76bSAndroid Build Coastguard Worker 5. s - pointer to char (char *). NO allocation is needed!
74*324bb76bSAndroid Build Coastguard Worker 6. *? - TWO variables are passed for each wild request. the first
75*324bb76bSAndroid Build Coastguard Worker    one is (address of) integer, and it will return number of
76*324bb76bSAndroid Build Coastguard Worker    parameters actually matched this sequence, and the second
77*324bb76bSAndroid Build Coastguard Worker    one is a pointer to pointer to ? (? **), and will return an
78*324bb76bSAndroid Build Coastguard Worker    address to a block of pointers to ? kind, terminated with
79*324bb76bSAndroid Build Coastguard Worker    NULL pointer. NO pre-allocation is required. The caller is
80*324bb76bSAndroid Build Coastguard Worker    responsible for freeing this memory, including the pointed to
81*324bb76bSAndroid Build Coastguard Worker    memory.
82*324bb76bSAndroid Build Coastguard Worker 
83*324bb76bSAndroid Build Coastguard Worker Note that these two variables are pretty like the argv/argc pair...
84*324bb76bSAndroid Build Coastguard Worker 
85*324bb76bSAndroid Build Coastguard Worker Examples:
86*324bb76bSAndroid Build Coastguard Worker 
87*324bb76bSAndroid Build Coastguard Worker "Example1 i%-OneInteger!d s%-Strings!*s j%- k!-Float!f Files"
88*324bb76bSAndroid Build Coastguard Worker 
89*324bb76bSAndroid Build Coastguard Worker Will match: Example1 -i 77 -s String1 String2 String3 -k 88.2 File1 File2
90*324bb76bSAndroid Build Coastguard Worker or: Example1 -s String1 -k 88.3 -i 999 -j
91*324bb76bSAndroid Build Coastguard Worker but not: Example1 -i 77 78 (option i expects one integer, k must be).
92*324bb76bSAndroid Build Coastguard Worker 
93*324bb76bSAndroid Build Coastguard Worker Note the option k must exist, and that the order of the options is not
94*324bb76bSAndroid Build Coastguard Worker important. In the first examples File1 & File2 will match the Files
95*324bb76bSAndroid Build Coastguard Worker in the command line.
96*324bb76bSAndroid Build Coastguard Worker 
97*324bb76bSAndroid Build Coastguard Worker A call to GAPrintHowTo with this CtrlStr will print to stderr:
98*324bb76bSAndroid Build Coastguard Worker Example1 [-i OneIngeter] [-s Strings...] [-j] -k Float Files...
99*324bb76bSAndroid Build Coastguard Worker 
100*324bb76bSAndroid Build Coastguard Worker Notes:
101*324bb76bSAndroid Build Coastguard Worker 
102*324bb76bSAndroid Build Coastguard Worker 1. This module assumes that all the pointers to all kind of data types
103*324bb76bSAndroid Build Coastguard Worker have the same length and format, i.e. sizeof(int *) == sizeof(char *).
104*324bb76bSAndroid Build Coastguard Worker 
105*324bb76bSAndroid Build Coastguard Worker SPDX-License-Identifier: MIT
106*324bb76bSAndroid Build Coastguard Worker 
107*324bb76bSAndroid Build Coastguard Worker **************************************************************************/
108*324bb76bSAndroid Build Coastguard Worker 
109*324bb76bSAndroid Build Coastguard Worker #include <stdarg.h>
110*324bb76bSAndroid Build Coastguard Worker #include <stdbool.h>
111*324bb76bSAndroid Build Coastguard Worker #include <stdio.h>
112*324bb76bSAndroid Build Coastguard Worker #include <stdlib.h>
113*324bb76bSAndroid Build Coastguard Worker #include <string.h>
114*324bb76bSAndroid Build Coastguard Worker 
115*324bb76bSAndroid Build Coastguard Worker #include "getarg.h"
116*324bb76bSAndroid Build Coastguard Worker 
117*324bb76bSAndroid Build Coastguard Worker #define MAX_PARAM 100 /* maximum number of parameters allowed. */
118*324bb76bSAndroid Build Coastguard Worker #define CTRL_STR_MAX_LEN 1024
119*324bb76bSAndroid Build Coastguard Worker 
120*324bb76bSAndroid Build Coastguard Worker #define SPACE_CHAR '|' /* The character not to print using HowTo. */
121*324bb76bSAndroid Build Coastguard Worker 
122*324bb76bSAndroid Build Coastguard Worker #define ARG_OK false
123*324bb76bSAndroid Build Coastguard Worker 
124*324bb76bSAndroid Build Coastguard Worker #define ISSPACE(x) ((x) <= ' ') /* Not conventional - but works fine! */
125*324bb76bSAndroid Build Coastguard Worker 
126*324bb76bSAndroid Build Coastguard Worker /* The two characters '%' and '!' are used in the control string: */
127*324bb76bSAndroid Build Coastguard Worker #define ISCTRLCHAR(x) (((x) == '%') || ((x) == '!'))
128*324bb76bSAndroid Build Coastguard Worker 
129*324bb76bSAndroid Build Coastguard Worker static char *GAErrorToken; /* On error, ErrorToken is set to point to it. */
130*324bb76bSAndroid Build Coastguard Worker static int GATestAllSatis(char *CtrlStrCopy, char *CtrlStr,
131*324bb76bSAndroid Build Coastguard Worker                           const char **argv_end, const char ***argv,
132*324bb76bSAndroid Build Coastguard Worker                           void *Parameters[MAX_PARAM], int *ParamCount);
133*324bb76bSAndroid Build Coastguard Worker static int GAUpdateParameters(void *Parameters[], int *ParamCount, char *Option,
134*324bb76bSAndroid Build Coastguard Worker                               char *CtrlStrCopy, char *CtrlStr, char **argv_end,
135*324bb76bSAndroid Build Coastguard Worker                               char ***argv);
136*324bb76bSAndroid Build Coastguard Worker static int GAGetParmeters(void *Parameters[], int *ParamCount,
137*324bb76bSAndroid Build Coastguard Worker                           char *CtrlStrCopy, char *Option, char **argv_end,
138*324bb76bSAndroid Build Coastguard Worker                           char ***argv);
139*324bb76bSAndroid Build Coastguard Worker static int GAGetMultiParmeters(void *Parameters[], int *ParamCount,
140*324bb76bSAndroid Build Coastguard Worker                                char *CtrlStrCopy, char **argv_end,
141*324bb76bSAndroid Build Coastguard Worker                                char ***argv);
142*324bb76bSAndroid Build Coastguard Worker static void GASetParamCount(const char *CtrlStr, const int Max,
143*324bb76bSAndroid Build Coastguard Worker                             int *ParamCount);
144*324bb76bSAndroid Build Coastguard Worker static bool GAOptionExists(const char **argv_end, const char **argv);
145*324bb76bSAndroid Build Coastguard Worker 
146*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
147*324bb76bSAndroid Build Coastguard Worker  Allocate or die
148*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
xmalloc(unsigned size)149*324bb76bSAndroid Build Coastguard Worker static void *xmalloc(unsigned size) {
150*324bb76bSAndroid Build Coastguard Worker 
151*324bb76bSAndroid Build Coastguard Worker 	void *p;
152*324bb76bSAndroid Build Coastguard Worker 
153*324bb76bSAndroid Build Coastguard Worker 	if ((p = malloc(size)) != NULL) {
154*324bb76bSAndroid Build Coastguard Worker 		return p;
155*324bb76bSAndroid Build Coastguard Worker 	}
156*324bb76bSAndroid Build Coastguard Worker 
157*324bb76bSAndroid Build Coastguard Worker 	fprintf(stderr, "Not enough memory, exit.\n");
158*324bb76bSAndroid Build Coastguard Worker 	exit(2);
159*324bb76bSAndroid Build Coastguard Worker 
160*324bb76bSAndroid Build Coastguard Worker 	return NULL; /* Makes warning silent. */
161*324bb76bSAndroid Build Coastguard Worker }
162*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
163*324bb76bSAndroid Build Coastguard Worker  Routine to access the command line argument and interpret them:
164*324bb76bSAndroid Build Coastguard Worker  Return ARG_OK (0) is case of successful parsing, error code else...
165*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GAGetArgs(int argc,char ** argv,char * CtrlStr,...)166*324bb76bSAndroid Build Coastguard Worker bool GAGetArgs(int argc, char **argv, char *CtrlStr, ...) {
167*324bb76bSAndroid Build Coastguard Worker 
168*324bb76bSAndroid Build Coastguard Worker 	int i, ParamCount = 0;
169*324bb76bSAndroid Build Coastguard Worker 	void *Parameters[MAX_PARAM]; /* Save here parameter addresses. */
170*324bb76bSAndroid Build Coastguard Worker 	char CtrlStrCopy[CTRL_STR_MAX_LEN];
171*324bb76bSAndroid Build Coastguard Worker 	const char **argv_end = (const char **)argv + argc;
172*324bb76bSAndroid Build Coastguard Worker 	va_list ap;
173*324bb76bSAndroid Build Coastguard Worker 
174*324bb76bSAndroid Build Coastguard Worker 	strncpy(CtrlStrCopy, CtrlStr, sizeof(CtrlStrCopy) - 1);
175*324bb76bSAndroid Build Coastguard Worker 	GASetParamCount(CtrlStr, strlen(CtrlStr), &ParamCount);
176*324bb76bSAndroid Build Coastguard Worker 	va_start(ap, CtrlStr);
177*324bb76bSAndroid Build Coastguard Worker 	for (i = 1; i <= ParamCount; i++) {
178*324bb76bSAndroid Build Coastguard Worker 		Parameters[i - 1] = va_arg(ap, void *);
179*324bb76bSAndroid Build Coastguard Worker 	}
180*324bb76bSAndroid Build Coastguard Worker 	va_end(ap);
181*324bb76bSAndroid Build Coastguard Worker 
182*324bb76bSAndroid Build Coastguard Worker 	argv++; /* Skip the program name (first in argv/c list). */
183*324bb76bSAndroid Build Coastguard Worker 	while (argv < (char **)argv_end) {
184*324bb76bSAndroid Build Coastguard Worker 		bool Error = false;
185*324bb76bSAndroid Build Coastguard Worker 		if (!GAOptionExists(argv_end, (const char **)argv)) {
186*324bb76bSAndroid Build Coastguard Worker 			break; /* The loop. */
187*324bb76bSAndroid Build Coastguard Worker 		}
188*324bb76bSAndroid Build Coastguard Worker 		char *Option = *argv++;
189*324bb76bSAndroid Build Coastguard Worker 		if ((Error = GAUpdateParameters(
190*324bb76bSAndroid Build Coastguard Worker 		         Parameters, &ParamCount, Option, CtrlStrCopy, CtrlStr,
191*324bb76bSAndroid Build Coastguard Worker 		         (char **)argv_end, &argv)) != false) {
192*324bb76bSAndroid Build Coastguard Worker 			return Error;
193*324bb76bSAndroid Build Coastguard Worker 		}
194*324bb76bSAndroid Build Coastguard Worker 	}
195*324bb76bSAndroid Build Coastguard Worker 	/* Check for results and update trail of command line: */
196*324bb76bSAndroid Build Coastguard Worker 	return GATestAllSatis(CtrlStrCopy, CtrlStr, argv_end,
197*324bb76bSAndroid Build Coastguard Worker 	                      (const char ***)&argv, Parameters,
198*324bb76bSAndroid Build Coastguard Worker 	                      &ParamCount) != ARG_OK;
199*324bb76bSAndroid Build Coastguard Worker }
200*324bb76bSAndroid Build Coastguard Worker 
201*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
202*324bb76bSAndroid Build Coastguard Worker  Routine to search for unsatisfied flags - simply scan the list for !-
203*324bb76bSAndroid Build Coastguard Worker  sequence. Before this scan, this routine updates the rest of the command
204*324bb76bSAndroid Build Coastguard Worker  line into the last two parameters if it is requested by the CtrlStr
205*324bb76bSAndroid Build Coastguard Worker  (last item in CtrlStr is NOT an option).
206*324bb76bSAndroid Build Coastguard Worker  Return ARG_OK if all satisfied, CMD_ERR_AllSatis error else.
207*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GATestAllSatis(char * CtrlStrCopy,char * CtrlStr,const char ** argv_end,const char *** argv,void * Parameters[MAX_PARAM],int * ParamCount)208*324bb76bSAndroid Build Coastguard Worker static int GATestAllSatis(char *CtrlStrCopy, char *CtrlStr,
209*324bb76bSAndroid Build Coastguard Worker                           const char **argv_end, const char ***argv,
210*324bb76bSAndroid Build Coastguard Worker                           void *Parameters[MAX_PARAM], int *ParamCount) {
211*324bb76bSAndroid Build Coastguard Worker 
212*324bb76bSAndroid Build Coastguard Worker 	int i;
213*324bb76bSAndroid Build Coastguard Worker 	static char *LocalToken = NULL;
214*324bb76bSAndroid Build Coastguard Worker 
215*324bb76bSAndroid Build Coastguard Worker 	/* If LocalToken is not initialized - do it now. Note that this string
216*324bb76bSAndroid Build Coastguard Worker 	 * should be writable as well so we can not assign it directly.
217*324bb76bSAndroid Build Coastguard Worker 	 */
218*324bb76bSAndroid Build Coastguard Worker 	if (LocalToken == NULL) {
219*324bb76bSAndroid Build Coastguard Worker 		LocalToken = (char *)malloc(3);
220*324bb76bSAndroid Build Coastguard Worker 		strcpy(LocalToken, "-?");
221*324bb76bSAndroid Build Coastguard Worker 	}
222*324bb76bSAndroid Build Coastguard Worker 
223*324bb76bSAndroid Build Coastguard Worker 	/* Check if last item is an option. If not then copy rest of command
224*324bb76bSAndroid Build Coastguard Worker 	 * line into it as 1. NumOfprm, 2. pointer to block of pointers.
225*324bb76bSAndroid Build Coastguard Worker 	 */
226*324bb76bSAndroid Build Coastguard Worker 	for (i = strlen(CtrlStr) - 1; i > 0 && !ISSPACE(CtrlStr[i]); i--) {
227*324bb76bSAndroid Build Coastguard Worker 		;
228*324bb76bSAndroid Build Coastguard Worker 	}
229*324bb76bSAndroid Build Coastguard Worker 	if (!ISCTRLCHAR(CtrlStr[i + 2])) {
230*324bb76bSAndroid Build Coastguard Worker 		GASetParamCount(CtrlStr, i,
231*324bb76bSAndroid Build Coastguard Worker 		                ParamCount); /* Point in correct param. */
232*324bb76bSAndroid Build Coastguard Worker 		*(int *)Parameters[(*ParamCount)++] = argv_end - *argv;
233*324bb76bSAndroid Build Coastguard Worker 		*(char ***)Parameters[(*ParamCount)++] = *(char ***)argv;
234*324bb76bSAndroid Build Coastguard Worker 	}
235*324bb76bSAndroid Build Coastguard Worker 
236*324bb76bSAndroid Build Coastguard Worker 	i = 0;
237*324bb76bSAndroid Build Coastguard Worker 	while (++i < (int)strlen(CtrlStrCopy)) {
238*324bb76bSAndroid Build Coastguard Worker 		if ((CtrlStrCopy[i] == '-') && (CtrlStrCopy[i - 1] == '!')) {
239*324bb76bSAndroid Build Coastguard Worker 			GAErrorToken = LocalToken;
240*324bb76bSAndroid Build Coastguard Worker 			LocalToken[1] =
241*324bb76bSAndroid Build Coastguard Worker 			    CtrlStrCopy[i - 2]; /* Set the correct flag. */
242*324bb76bSAndroid Build Coastguard Worker 			return CMD_ERR_AllSatis;
243*324bb76bSAndroid Build Coastguard Worker 		}
244*324bb76bSAndroid Build Coastguard Worker 	}
245*324bb76bSAndroid Build Coastguard Worker 
246*324bb76bSAndroid Build Coastguard Worker 	return ARG_OK;
247*324bb76bSAndroid Build Coastguard Worker }
248*324bb76bSAndroid Build Coastguard Worker 
249*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
250*324bb76bSAndroid Build Coastguard Worker  Routine to update the parameters according to the given Option:
251*324bb76bSAndroid Build Coastguard Worker  **************************************************************************/
GAUpdateParameters(void * Parameters[],int * ParamCount,char * Option,char * CtrlStrCopy,char * CtrlStr,char ** argv_end,char *** argv)252*324bb76bSAndroid Build Coastguard Worker static int GAUpdateParameters(void *Parameters[], int *ParamCount, char *Option,
253*324bb76bSAndroid Build Coastguard Worker                               char *CtrlStrCopy, char *CtrlStr, char **argv_end,
254*324bb76bSAndroid Build Coastguard Worker                               char ***argv) {
255*324bb76bSAndroid Build Coastguard Worker 
256*324bb76bSAndroid Build Coastguard Worker 	int i;
257*324bb76bSAndroid Build Coastguard Worker 	bool BooleanTrue = Option[2] != '-';
258*324bb76bSAndroid Build Coastguard Worker 
259*324bb76bSAndroid Build Coastguard Worker 	if (Option[0] != '-') {
260*324bb76bSAndroid Build Coastguard Worker 		GAErrorToken = Option;
261*324bb76bSAndroid Build Coastguard Worker 		return CMD_ERR_NotAnOpt;
262*324bb76bSAndroid Build Coastguard Worker 	}
263*324bb76bSAndroid Build Coastguard Worker 	i = 0; /* Scan the CtrlStrCopy for that option: */
264*324bb76bSAndroid Build Coastguard Worker 	while (i + 2 < (int)strlen(CtrlStrCopy)) {
265*324bb76bSAndroid Build Coastguard Worker 		if ((CtrlStrCopy[i] == Option[1]) &&
266*324bb76bSAndroid Build Coastguard Worker 		    (ISCTRLCHAR(CtrlStrCopy[i + 1])) &&
267*324bb76bSAndroid Build Coastguard Worker 		    (CtrlStrCopy[i + 2] == '-')) {
268*324bb76bSAndroid Build Coastguard Worker 			/* We found that option! */
269*324bb76bSAndroid Build Coastguard Worker 			break;
270*324bb76bSAndroid Build Coastguard Worker 		}
271*324bb76bSAndroid Build Coastguard Worker 		i++;
272*324bb76bSAndroid Build Coastguard Worker 	}
273*324bb76bSAndroid Build Coastguard Worker 	if (i + 2 >= (int)strlen(CtrlStrCopy)) {
274*324bb76bSAndroid Build Coastguard Worker 		GAErrorToken = Option;
275*324bb76bSAndroid Build Coastguard Worker 		return CMD_ERR_NoSuchOpt;
276*324bb76bSAndroid Build Coastguard Worker 	}
277*324bb76bSAndroid Build Coastguard Worker 
278*324bb76bSAndroid Build Coastguard Worker 	/* If we are here, then we found that option in CtrlStr - Strip it off:
279*324bb76bSAndroid Build Coastguard Worker 	 */
280*324bb76bSAndroid Build Coastguard Worker 	CtrlStrCopy[i] = CtrlStrCopy[i + 1] = CtrlStrCopy[i + 2] = (char)' ';
281*324bb76bSAndroid Build Coastguard Worker 	GASetParamCount(CtrlStr, i, ParamCount); /* Set it to point in
282*324bb76bSAndroid Build Coastguard Worker 	                                            correct prm. */
283*324bb76bSAndroid Build Coastguard Worker 	i += 3;
284*324bb76bSAndroid Build Coastguard Worker 	/* Set boolean flag for that option. */
285*324bb76bSAndroid Build Coastguard Worker 	*(bool *)Parameters[(*ParamCount)++] = BooleanTrue;
286*324bb76bSAndroid Build Coastguard Worker 	if (ISSPACE(CtrlStrCopy[i])) {
287*324bb76bSAndroid Build Coastguard Worker 		return ARG_OK; /* Only a boolean flag is needed. */
288*324bb76bSAndroid Build Coastguard Worker 	}
289*324bb76bSAndroid Build Coastguard Worker 	/* Skip the text between the boolean option and data follows: */
290*324bb76bSAndroid Build Coastguard Worker 	while (!ISCTRLCHAR(CtrlStrCopy[i])) {
291*324bb76bSAndroid Build Coastguard Worker 		i++;
292*324bb76bSAndroid Build Coastguard Worker 	}
293*324bb76bSAndroid Build Coastguard Worker 	/* Get the parameters and return the appropriete return code: */
294*324bb76bSAndroid Build Coastguard Worker 	return GAGetParmeters(Parameters, ParamCount, &CtrlStrCopy[i], Option,
295*324bb76bSAndroid Build Coastguard Worker 	                      argv_end, argv);
296*324bb76bSAndroid Build Coastguard Worker }
297*324bb76bSAndroid Build Coastguard Worker 
298*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
299*324bb76bSAndroid Build Coastguard Worker  Routine to get parameters according to the CtrlStr given from argv/argc
300*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GAGetParmeters(void * Parameters[],int * ParamCount,char * CtrlStrCopy,char * Option,char ** argv_end,char *** argv)301*324bb76bSAndroid Build Coastguard Worker static int GAGetParmeters(void *Parameters[], int *ParamCount,
302*324bb76bSAndroid Build Coastguard Worker                           char *CtrlStrCopy, char *Option, char **argv_end,
303*324bb76bSAndroid Build Coastguard Worker                           char ***argv) {
304*324bb76bSAndroid Build Coastguard Worker 
305*324bb76bSAndroid Build Coastguard Worker 	int i = 0, ScanRes;
306*324bb76bSAndroid Build Coastguard Worker 
307*324bb76bSAndroid Build Coastguard Worker 	while (!(ISSPACE(CtrlStrCopy[i]))) {
308*324bb76bSAndroid Build Coastguard Worker 
309*324bb76bSAndroid Build Coastguard Worker 		if ((*argv) == argv_end) {
310*324bb76bSAndroid Build Coastguard Worker 			GAErrorToken = Option;
311*324bb76bSAndroid Build Coastguard Worker 			return CMD_ERR_NumRead;
312*324bb76bSAndroid Build Coastguard Worker 		}
313*324bb76bSAndroid Build Coastguard Worker 
314*324bb76bSAndroid Build Coastguard Worker 		switch (CtrlStrCopy[i + 1]) {
315*324bb76bSAndroid Build Coastguard Worker 		case 'd': /* Get signed integers. */
316*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(*((*argv)++), "%d",
317*324bb76bSAndroid Build Coastguard Worker 			                 (int *)Parameters[(*ParamCount)++]);
318*324bb76bSAndroid Build Coastguard Worker 			break;
319*324bb76bSAndroid Build Coastguard Worker 		case 'u': /* Get unsigned integers. */
320*324bb76bSAndroid Build Coastguard Worker 			ScanRes =
321*324bb76bSAndroid Build Coastguard Worker 			    sscanf(*((*argv)++), "%u",
322*324bb76bSAndroid Build Coastguard Worker 			           (unsigned *)Parameters[(*ParamCount)++]);
323*324bb76bSAndroid Build Coastguard Worker 			break;
324*324bb76bSAndroid Build Coastguard Worker 		case 'x': /* Get hex integers. */
325*324bb76bSAndroid Build Coastguard Worker 			ScanRes =
326*324bb76bSAndroid Build Coastguard Worker 			    sscanf(*((*argv)++), "%x",
327*324bb76bSAndroid Build Coastguard Worker 			           (unsigned int *)Parameters[(*ParamCount)++]);
328*324bb76bSAndroid Build Coastguard Worker 			break;
329*324bb76bSAndroid Build Coastguard Worker 		case 'o': /* Get octal integers. */
330*324bb76bSAndroid Build Coastguard Worker 			ScanRes =
331*324bb76bSAndroid Build Coastguard Worker 			    sscanf(*((*argv)++), "%o",
332*324bb76bSAndroid Build Coastguard Worker 			           (unsigned int *)Parameters[(*ParamCount)++]);
333*324bb76bSAndroid Build Coastguard Worker 			break;
334*324bb76bSAndroid Build Coastguard Worker 		case 'D': /* Get signed long integers. */
335*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(*((*argv)++), "%ld",
336*324bb76bSAndroid Build Coastguard Worker 			                 (long *)Parameters[(*ParamCount)++]);
337*324bb76bSAndroid Build Coastguard Worker 			break;
338*324bb76bSAndroid Build Coastguard Worker 		case 'U': /* Get unsigned long integers. */
339*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
340*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%lu",
341*324bb76bSAndroid Build Coastguard Worker 			    (unsigned long *)Parameters[(*ParamCount)++]);
342*324bb76bSAndroid Build Coastguard Worker 			break;
343*324bb76bSAndroid Build Coastguard Worker 		case 'X': /* Get hex long integers. */
344*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
345*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%lx",
346*324bb76bSAndroid Build Coastguard Worker 			    (unsigned long *)Parameters[(*ParamCount)++]);
347*324bb76bSAndroid Build Coastguard Worker 			break;
348*324bb76bSAndroid Build Coastguard Worker 		case 'O': /* Get octal long integers. */
349*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
350*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%lo",
351*324bb76bSAndroid Build Coastguard Worker 			    (unsigned long *)Parameters[(*ParamCount)++]);
352*324bb76bSAndroid Build Coastguard Worker 			break;
353*324bb76bSAndroid Build Coastguard Worker 		case 'f': /* Get float number. */
354*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(*((*argv)++), "%f",
355*324bb76bSAndroid Build Coastguard Worker 			                 (float *)Parameters[(*ParamCount)++]);
356*324bb76bSAndroid Build Coastguard Worker 			break;
357*324bb76bSAndroid Build Coastguard Worker 		case 'F': /* Get double float number. */
358*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(*((*argv)++), "%lf",
359*324bb76bSAndroid Build Coastguard Worker 			                 (double *)Parameters[(*ParamCount)++]);
360*324bb76bSAndroid Build Coastguard Worker 			break;
361*324bb76bSAndroid Build Coastguard Worker 		case 's':            /* It as a string. */
362*324bb76bSAndroid Build Coastguard Worker 			ScanRes = 1; /* Allways O.K. */
363*324bb76bSAndroid Build Coastguard Worker 			*(char **)Parameters[(*ParamCount)++] = *((*argv)++);
364*324bb76bSAndroid Build Coastguard Worker 			break;
365*324bb76bSAndroid Build Coastguard Worker 		case '*': /* Get few parameters into one: */
366*324bb76bSAndroid Build Coastguard Worker 			ScanRes = GAGetMultiParmeters(Parameters, ParamCount,
367*324bb76bSAndroid Build Coastguard Worker 			                              &CtrlStrCopy[i], argv_end,
368*324bb76bSAndroid Build Coastguard Worker 			                              argv);
369*324bb76bSAndroid Build Coastguard Worker 			if ((ScanRes == 0) && (CtrlStrCopy[i] == '!')) {
370*324bb76bSAndroid Build Coastguard Worker 				GAErrorToken = Option;
371*324bb76bSAndroid Build Coastguard Worker 				return CMD_ERR_WildEmpty;
372*324bb76bSAndroid Build Coastguard Worker 			}
373*324bb76bSAndroid Build Coastguard Worker 			break;
374*324bb76bSAndroid Build Coastguard Worker 		default:
375*324bb76bSAndroid Build Coastguard Worker 			ScanRes = 0; /* Make optimizer warning silent. */
376*324bb76bSAndroid Build Coastguard Worker 		}
377*324bb76bSAndroid Build Coastguard Worker 		/* If reading fails and this number is a must (!) then error: */
378*324bb76bSAndroid Build Coastguard Worker 		if ((ScanRes == 0) && (CtrlStrCopy[i] == '!')) {
379*324bb76bSAndroid Build Coastguard Worker 			GAErrorToken = Option;
380*324bb76bSAndroid Build Coastguard Worker 			return CMD_ERR_NumRead;
381*324bb76bSAndroid Build Coastguard Worker 		}
382*324bb76bSAndroid Build Coastguard Worker 		if (CtrlStrCopy[i + 1] != '*') {
383*324bb76bSAndroid Build Coastguard Worker 			i += 2; /* Skip to next parameter (if any). */
384*324bb76bSAndroid Build Coastguard Worker 		} else {
385*324bb76bSAndroid Build Coastguard Worker 			i += 3; /* Skip the '*' also! */
386*324bb76bSAndroid Build Coastguard Worker 		}
387*324bb76bSAndroid Build Coastguard Worker 	}
388*324bb76bSAndroid Build Coastguard Worker 
389*324bb76bSAndroid Build Coastguard Worker 	return ARG_OK;
390*324bb76bSAndroid Build Coastguard Worker }
391*324bb76bSAndroid Build Coastguard Worker 
392*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
393*324bb76bSAndroid Build Coastguard Worker  Routine to get a few parameters into one pointer such that the returned
394*324bb76bSAndroid Build Coastguard Worker  pointer actually points on a block of pointers to the parameters...
395*324bb76bSAndroid Build Coastguard Worker  For example *F means a pointer to pointers on floats.
396*324bb76bSAndroid Build Coastguard Worker  Returns number of parameters actually read.
397*324bb76bSAndroid Build Coastguard Worker  This routine assumes that all pointers (on any kind of scalar) has the
398*324bb76bSAndroid Build Coastguard Worker  same size (and the union below is totally ovelapped bteween dif. arrays)
399*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GAGetMultiParmeters(void * Parameters[],int * ParamCount,char * CtrlStrCopy,char ** argv_end,char *** argv)400*324bb76bSAndroid Build Coastguard Worker static int GAGetMultiParmeters(void *Parameters[], int *ParamCount,
401*324bb76bSAndroid Build Coastguard Worker                                char *CtrlStrCopy, char **argv_end,
402*324bb76bSAndroid Build Coastguard Worker                                char ***argv) {
403*324bb76bSAndroid Build Coastguard Worker 
404*324bb76bSAndroid Build Coastguard Worker 	int i = 0, ScanRes, NumOfPrm = 0;
405*324bb76bSAndroid Build Coastguard Worker 	void **Pmain, **Ptemp;
406*324bb76bSAndroid Build Coastguard Worker 	union TmpArray { /* Save here the temporary data before copying it to */
407*324bb76bSAndroid Build Coastguard Worker 		void *VoidArray[MAX_PARAM]; /* the returned pointer block. */
408*324bb76bSAndroid Build Coastguard Worker 		int *IntArray[MAX_PARAM];
409*324bb76bSAndroid Build Coastguard Worker 		long *LngArray[MAX_PARAM];
410*324bb76bSAndroid Build Coastguard Worker 		float *FltArray[MAX_PARAM];
411*324bb76bSAndroid Build Coastguard Worker 		double *DblArray[MAX_PARAM];
412*324bb76bSAndroid Build Coastguard Worker 		char *ChrArray[MAX_PARAM];
413*324bb76bSAndroid Build Coastguard Worker 	} TmpArray;
414*324bb76bSAndroid Build Coastguard Worker 
415*324bb76bSAndroid Build Coastguard Worker 	do {
416*324bb76bSAndroid Build Coastguard Worker 		switch (CtrlStrCopy[2]) { /* CtrlStr == '!*?' or '%*?' where ?
417*324bb76bSAndroid Build Coastguard Worker 			                     is. */
418*324bb76bSAndroid Build Coastguard Worker 		case 'd':                 /* Format to read the parameters: */
419*324bb76bSAndroid Build Coastguard Worker 			TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
420*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(*((*argv)++), "%d",
421*324bb76bSAndroid Build Coastguard Worker 			                 (int *)TmpArray.IntArray[NumOfPrm++]);
422*324bb76bSAndroid Build Coastguard Worker 			break;
423*324bb76bSAndroid Build Coastguard Worker 		case 'u':
424*324bb76bSAndroid Build Coastguard Worker 			TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
425*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
426*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%u",
427*324bb76bSAndroid Build Coastguard Worker 			    (unsigned int *)TmpArray.IntArray[NumOfPrm++]);
428*324bb76bSAndroid Build Coastguard Worker 			break;
429*324bb76bSAndroid Build Coastguard Worker 		case 'o':
430*324bb76bSAndroid Build Coastguard Worker 			TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
431*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
432*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%o",
433*324bb76bSAndroid Build Coastguard Worker 			    (unsigned int *)TmpArray.IntArray[NumOfPrm++]);
434*324bb76bSAndroid Build Coastguard Worker 			break;
435*324bb76bSAndroid Build Coastguard Worker 		case 'x':
436*324bb76bSAndroid Build Coastguard Worker 			TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
437*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
438*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%x",
439*324bb76bSAndroid Build Coastguard Worker 			    (unsigned int *)TmpArray.IntArray[NumOfPrm++]);
440*324bb76bSAndroid Build Coastguard Worker 			break;
441*324bb76bSAndroid Build Coastguard Worker 		case 'D':
442*324bb76bSAndroid Build Coastguard Worker 			TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
443*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(*((*argv)++), "%ld",
444*324bb76bSAndroid Build Coastguard Worker 			                 (long *)TmpArray.IntArray[NumOfPrm++]);
445*324bb76bSAndroid Build Coastguard Worker 			break;
446*324bb76bSAndroid Build Coastguard Worker 		case 'U':
447*324bb76bSAndroid Build Coastguard Worker 			TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
448*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
449*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%lu",
450*324bb76bSAndroid Build Coastguard Worker 			    (unsigned long *)TmpArray.IntArray[NumOfPrm++]);
451*324bb76bSAndroid Build Coastguard Worker 			break;
452*324bb76bSAndroid Build Coastguard Worker 		case 'O':
453*324bb76bSAndroid Build Coastguard Worker 			TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
454*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
455*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%lo",
456*324bb76bSAndroid Build Coastguard Worker 			    (unsigned long *)TmpArray.IntArray[NumOfPrm++]);
457*324bb76bSAndroid Build Coastguard Worker 			break;
458*324bb76bSAndroid Build Coastguard Worker 		case 'X':
459*324bb76bSAndroid Build Coastguard Worker 			TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
460*324bb76bSAndroid Build Coastguard Worker 			ScanRes = sscanf(
461*324bb76bSAndroid Build Coastguard Worker 			    *((*argv)++), "%lx",
462*324bb76bSAndroid Build Coastguard Worker 			    (unsigned long *)TmpArray.IntArray[NumOfPrm++]);
463*324bb76bSAndroid Build Coastguard Worker 			break;
464*324bb76bSAndroid Build Coastguard Worker 		case 'f':
465*324bb76bSAndroid Build Coastguard Worker 			TmpArray.FltArray[NumOfPrm] = xmalloc(sizeof(float));
466*324bb76bSAndroid Build Coastguard Worker 			ScanRes =
467*324bb76bSAndroid Build Coastguard Worker 			    sscanf(*((*argv)++), "%f",
468*324bb76bSAndroid Build Coastguard Worker 			           // cppcheck-suppress invalidPointerCast
469*324bb76bSAndroid Build Coastguard Worker 			           (float *)TmpArray.LngArray[NumOfPrm++]);
470*324bb76bSAndroid Build Coastguard Worker 			break;
471*324bb76bSAndroid Build Coastguard Worker 		case 'F':
472*324bb76bSAndroid Build Coastguard Worker 			TmpArray.DblArray[NumOfPrm] = xmalloc(sizeof(double));
473*324bb76bSAndroid Build Coastguard Worker 			ScanRes =
474*324bb76bSAndroid Build Coastguard Worker 			    sscanf(*((*argv)++), "%lf",
475*324bb76bSAndroid Build Coastguard Worker 			           // cppcheck-suppress invalidPointerCast
476*324bb76bSAndroid Build Coastguard Worker 			           (double *)TmpArray.LngArray[NumOfPrm++]);
477*324bb76bSAndroid Build Coastguard Worker 			break;
478*324bb76bSAndroid Build Coastguard Worker 		case 's':
479*324bb76bSAndroid Build Coastguard Worker 			while ((*argv < argv_end) && ((**argv)[0] != '-')) {
480*324bb76bSAndroid Build Coastguard Worker 				TmpArray.ChrArray[NumOfPrm++] = *((*argv)++);
481*324bb76bSAndroid Build Coastguard Worker 			}
482*324bb76bSAndroid Build Coastguard Worker 			ScanRes = 0; /* Force quit from do - loop. */
483*324bb76bSAndroid Build Coastguard Worker 			NumOfPrm++;  /* Updated again immediately after loop! */
484*324bb76bSAndroid Build Coastguard Worker 			(*argv)++;   /* "" */
485*324bb76bSAndroid Build Coastguard Worker 			break;
486*324bb76bSAndroid Build Coastguard Worker 		default:
487*324bb76bSAndroid Build Coastguard Worker 			ScanRes = 0; /* Make optimizer warning silent. */
488*324bb76bSAndroid Build Coastguard Worker 		}
489*324bb76bSAndroid Build Coastguard Worker 	} while (ScanRes == 1); /* Exactly one parameter was read. */
490*324bb76bSAndroid Build Coastguard Worker 	(*argv)--;
491*324bb76bSAndroid Build Coastguard Worker 	NumOfPrm--;
492*324bb76bSAndroid Build Coastguard Worker 
493*324bb76bSAndroid Build Coastguard Worker 	/* Now allocate the block with the exact size, and set it: */
494*324bb76bSAndroid Build Coastguard Worker 	Ptemp = Pmain = xmalloc((unsigned)(NumOfPrm + 1) * sizeof(void *));
495*324bb76bSAndroid Build Coastguard Worker 	/* And here we use the assumption that all pointers are the same: */
496*324bb76bSAndroid Build Coastguard Worker 	for (i = 0; i < NumOfPrm; i++) {
497*324bb76bSAndroid Build Coastguard Worker 		*Ptemp++ = TmpArray.VoidArray[i];
498*324bb76bSAndroid Build Coastguard Worker 	}
499*324bb76bSAndroid Build Coastguard Worker 	*Ptemp = NULL; /* Close the block with NULL pointer. */
500*324bb76bSAndroid Build Coastguard Worker 
501*324bb76bSAndroid Build Coastguard Worker 	/* That it save the number of parameters read as first parameter to
502*324bb76bSAndroid Build Coastguard Worker 	 * return and the pointer to the block as second, and return: */
503*324bb76bSAndroid Build Coastguard Worker 	*(int *)Parameters[(*ParamCount)++] = NumOfPrm;
504*324bb76bSAndroid Build Coastguard Worker 	*(void ***)Parameters[(*ParamCount)++] = Pmain;
505*324bb76bSAndroid Build Coastguard Worker 	/* free(Pmain); -- can not free here as caller needs to access memory */
506*324bb76bSAndroid Build Coastguard Worker 	return NumOfPrm;
507*324bb76bSAndroid Build Coastguard Worker }
508*324bb76bSAndroid Build Coastguard Worker 
509*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
510*324bb76bSAndroid Build Coastguard Worker  Routine to scan the CtrlStr, up to Max and count the number of parameters
511*324bb76bSAndroid Build Coastguard Worker  to that point:
512*324bb76bSAndroid Build Coastguard Worker  1. Each option is counted as one parameter - boolean variable (int)
513*324bb76bSAndroid Build Coastguard Worker  2. Within an option, each %? or !? is counted once - pointer to something
514*324bb76bSAndroid Build Coastguard Worker  3. Within an option, %*? or !*? is counted twice - one for item count
515*324bb76bSAndroid Build Coastguard Worker  and one for pointer to block pointers.
516*324bb76bSAndroid Build Coastguard Worker  Note ALL variables are passed by address and so of fixed size (address).
517*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GASetParamCount(char const * CtrlStr,const int Max,int * ParamCount)518*324bb76bSAndroid Build Coastguard Worker static void GASetParamCount(char const *CtrlStr, const int Max,
519*324bb76bSAndroid Build Coastguard Worker                             int *ParamCount) {
520*324bb76bSAndroid Build Coastguard Worker 	int i;
521*324bb76bSAndroid Build Coastguard Worker 
522*324bb76bSAndroid Build Coastguard Worker 	*ParamCount = 0;
523*324bb76bSAndroid Build Coastguard Worker 	for (i = 0; i < Max; i++) {
524*324bb76bSAndroid Build Coastguard Worker 		if (ISCTRLCHAR(CtrlStr[i])) {
525*324bb76bSAndroid Build Coastguard Worker 			if (CtrlStr[i + 1] == '*') {
526*324bb76bSAndroid Build Coastguard Worker 				*ParamCount += 2;
527*324bb76bSAndroid Build Coastguard Worker 			} else {
528*324bb76bSAndroid Build Coastguard Worker 				(*ParamCount)++;
529*324bb76bSAndroid Build Coastguard Worker 			}
530*324bb76bSAndroid Build Coastguard Worker 		}
531*324bb76bSAndroid Build Coastguard Worker 	}
532*324bb76bSAndroid Build Coastguard Worker }
533*324bb76bSAndroid Build Coastguard Worker 
534*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
535*324bb76bSAndroid Build Coastguard Worker  Routine to check if more option (i.e. first char == '-') exists in the
536*324bb76bSAndroid Build Coastguard Worker  given list argc, argv:
537*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GAOptionExists(const char ** argv_end,const char ** argv)538*324bb76bSAndroid Build Coastguard Worker static bool GAOptionExists(const char **argv_end, const char **argv) {
539*324bb76bSAndroid Build Coastguard Worker 
540*324bb76bSAndroid Build Coastguard Worker 	while (argv < argv_end) {
541*324bb76bSAndroid Build Coastguard Worker 		if ((*argv++)[0] == '-') {
542*324bb76bSAndroid Build Coastguard Worker 			return true;
543*324bb76bSAndroid Build Coastguard Worker 		}
544*324bb76bSAndroid Build Coastguard Worker 	}
545*324bb76bSAndroid Build Coastguard Worker 	return false;
546*324bb76bSAndroid Build Coastguard Worker }
547*324bb76bSAndroid Build Coastguard Worker 
548*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
549*324bb76bSAndroid Build Coastguard Worker  Routine to print some error messages, for this module:
550*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GAPrintErrMsg(int Error)551*324bb76bSAndroid Build Coastguard Worker void GAPrintErrMsg(int Error) {
552*324bb76bSAndroid Build Coastguard Worker 
553*324bb76bSAndroid Build Coastguard Worker 	fprintf(stderr, "Error in command line parsing - ");
554*324bb76bSAndroid Build Coastguard Worker 	switch (Error) {
555*324bb76bSAndroid Build Coastguard Worker 	case 0:;
556*324bb76bSAndroid Build Coastguard Worker 		fprintf(stderr, "Undefined error");
557*324bb76bSAndroid Build Coastguard Worker 		break;
558*324bb76bSAndroid Build Coastguard Worker 	case CMD_ERR_NotAnOpt:
559*324bb76bSAndroid Build Coastguard Worker 		fprintf(stderr, "None option Found");
560*324bb76bSAndroid Build Coastguard Worker 		break;
561*324bb76bSAndroid Build Coastguard Worker 	case CMD_ERR_NoSuchOpt:
562*324bb76bSAndroid Build Coastguard Worker 		fprintf(stderr, "Undefined option Found");
563*324bb76bSAndroid Build Coastguard Worker 		break;
564*324bb76bSAndroid Build Coastguard Worker 	case CMD_ERR_WildEmpty:
565*324bb76bSAndroid Build Coastguard Worker 		fprintf(stderr, "Empty input for '!*?' seq.");
566*324bb76bSAndroid Build Coastguard Worker 		break;
567*324bb76bSAndroid Build Coastguard Worker 	case CMD_ERR_NumRead:
568*324bb76bSAndroid Build Coastguard Worker 		fprintf(stderr, "Failed on reading number");
569*324bb76bSAndroid Build Coastguard Worker 		break;
570*324bb76bSAndroid Build Coastguard Worker 	case CMD_ERR_AllSatis:
571*324bb76bSAndroid Build Coastguard Worker 		fprintf(stderr, "Fail to satisfy");
572*324bb76bSAndroid Build Coastguard Worker 		break;
573*324bb76bSAndroid Build Coastguard Worker 	}
574*324bb76bSAndroid Build Coastguard Worker 	fprintf(stderr, " - '%s'.\n", GAErrorToken);
575*324bb76bSAndroid Build Coastguard Worker }
576*324bb76bSAndroid Build Coastguard Worker 
577*324bb76bSAndroid Build Coastguard Worker /***************************************************************************
578*324bb76bSAndroid Build Coastguard Worker  Routine to print correct format of command line allowed:
579*324bb76bSAndroid Build Coastguard Worker ***************************************************************************/
GAPrintHowTo(char * CtrlStr)580*324bb76bSAndroid Build Coastguard Worker void GAPrintHowTo(char *CtrlStr) {
581*324bb76bSAndroid Build Coastguard Worker 
582*324bb76bSAndroid Build Coastguard Worker 	int i = 0;
583*324bb76bSAndroid Build Coastguard Worker 	bool SpaceFlag;
584*324bb76bSAndroid Build Coastguard Worker 
585*324bb76bSAndroid Build Coastguard Worker 	fprintf(stderr, "Usage: ");
586*324bb76bSAndroid Build Coastguard Worker 	/* Print program name - first word in ctrl. str. (optional): */
587*324bb76bSAndroid Build Coastguard Worker 	while (!(ISSPACE(CtrlStr[i])) && (!ISCTRLCHAR(CtrlStr[i + 1]))) {
588*324bb76bSAndroid Build Coastguard Worker 		fprintf(stderr, "%c", CtrlStr[i++]);
589*324bb76bSAndroid Build Coastguard Worker 	}
590*324bb76bSAndroid Build Coastguard Worker 
591*324bb76bSAndroid Build Coastguard Worker 	while (i < (int)strlen(CtrlStr)) {
592*324bb76bSAndroid Build Coastguard Worker 		// cppcheck-suppress arrayIndexThenCheck
593*324bb76bSAndroid Build Coastguard Worker 		while ((ISSPACE(CtrlStr[i])) && (i < (int)strlen(CtrlStr))) {
594*324bb76bSAndroid Build Coastguard Worker 			i++;
595*324bb76bSAndroid Build Coastguard Worker 		}
596*324bb76bSAndroid Build Coastguard Worker 		switch (CtrlStr[i + 1]) {
597*324bb76bSAndroid Build Coastguard Worker 		case '%':
598*324bb76bSAndroid Build Coastguard Worker 			fprintf(stderr, " [-%c", CtrlStr[i++]);
599*324bb76bSAndroid Build Coastguard Worker 			i += 2; /* Skip the '%-' or '!- after the char! */
600*324bb76bSAndroid Build Coastguard Worker 			SpaceFlag = true;
601*324bb76bSAndroid Build Coastguard Worker 			while (!ISCTRLCHAR(CtrlStr[i]) &&
602*324bb76bSAndroid Build Coastguard Worker 			       (i < (int)strlen(CtrlStr)) &&
603*324bb76bSAndroid Build Coastguard Worker 			       (!ISSPACE(CtrlStr[i]))) {
604*324bb76bSAndroid Build Coastguard Worker 				if (SpaceFlag) {
605*324bb76bSAndroid Build Coastguard Worker 					if (CtrlStr[i++] == SPACE_CHAR) {
606*324bb76bSAndroid Build Coastguard Worker 						fprintf(stderr, " ");
607*324bb76bSAndroid Build Coastguard Worker 					} else {
608*324bb76bSAndroid Build Coastguard Worker 						fprintf(stderr, " %c",
609*324bb76bSAndroid Build Coastguard Worker 						        CtrlStr[i - 1]);
610*324bb76bSAndroid Build Coastguard Worker 					}
611*324bb76bSAndroid Build Coastguard Worker 					SpaceFlag = false;
612*324bb76bSAndroid Build Coastguard Worker 				} else if (CtrlStr[i++] == SPACE_CHAR) {
613*324bb76bSAndroid Build Coastguard Worker 					fprintf(stderr, " ");
614*324bb76bSAndroid Build Coastguard Worker 				} else {
615*324bb76bSAndroid Build Coastguard Worker 					fprintf(stderr, "%c", CtrlStr[i - 1]);
616*324bb76bSAndroid Build Coastguard Worker 				}
617*324bb76bSAndroid Build Coastguard Worker 			}
618*324bb76bSAndroid Build Coastguard Worker 			while (!ISSPACE(CtrlStr[i]) &&
619*324bb76bSAndroid Build Coastguard Worker 			       (i < (int)strlen(CtrlStr))) {
620*324bb76bSAndroid Build Coastguard Worker 				if (CtrlStr[i] == '*') {
621*324bb76bSAndroid Build Coastguard Worker 					fprintf(stderr, "...");
622*324bb76bSAndroid Build Coastguard Worker 				}
623*324bb76bSAndroid Build Coastguard Worker 				i++; /* Skip the rest of it. */
624*324bb76bSAndroid Build Coastguard Worker 			}
625*324bb76bSAndroid Build Coastguard Worker 			fprintf(stderr, "]");
626*324bb76bSAndroid Build Coastguard Worker 			break;
627*324bb76bSAndroid Build Coastguard Worker 		case '!':
628*324bb76bSAndroid Build Coastguard Worker 			fprintf(stderr, " -%c", CtrlStr[i++]);
629*324bb76bSAndroid Build Coastguard Worker 			i += 2; /* Skip the '%-' or '!- after the char! */
630*324bb76bSAndroid Build Coastguard Worker 			SpaceFlag = true;
631*324bb76bSAndroid Build Coastguard Worker 			while (!ISCTRLCHAR(CtrlStr[i]) &&
632*324bb76bSAndroid Build Coastguard Worker 			       (i < (int)strlen(CtrlStr)) &&
633*324bb76bSAndroid Build Coastguard Worker 			       (!ISSPACE(CtrlStr[i]))) {
634*324bb76bSAndroid Build Coastguard Worker 				if (SpaceFlag) {
635*324bb76bSAndroid Build Coastguard Worker 					if (CtrlStr[i++] == SPACE_CHAR) {
636*324bb76bSAndroid Build Coastguard Worker 						fprintf(stderr, " ");
637*324bb76bSAndroid Build Coastguard Worker 					} else {
638*324bb76bSAndroid Build Coastguard Worker 						fprintf(stderr, " %c",
639*324bb76bSAndroid Build Coastguard Worker 						        CtrlStr[i - 1]);
640*324bb76bSAndroid Build Coastguard Worker 					}
641*324bb76bSAndroid Build Coastguard Worker 					SpaceFlag = false;
642*324bb76bSAndroid Build Coastguard Worker 				} else if (CtrlStr[i++] == SPACE_CHAR) {
643*324bb76bSAndroid Build Coastguard Worker 					fprintf(stderr, " ");
644*324bb76bSAndroid Build Coastguard Worker 				} else {
645*324bb76bSAndroid Build Coastguard Worker 					fprintf(stderr, "%c", CtrlStr[i - 1]);
646*324bb76bSAndroid Build Coastguard Worker 				}
647*324bb76bSAndroid Build Coastguard Worker 			}
648*324bb76bSAndroid Build Coastguard Worker 			while (!ISSPACE(CtrlStr[i]) &&
649*324bb76bSAndroid Build Coastguard Worker 			       (i < (int)strlen(CtrlStr))) {
650*324bb76bSAndroid Build Coastguard Worker 				if (CtrlStr[i] == '*') {
651*324bb76bSAndroid Build Coastguard Worker 					fprintf(stderr, "...");
652*324bb76bSAndroid Build Coastguard Worker 				}
653*324bb76bSAndroid Build Coastguard Worker 				i++; /* Skip the rest of it. */
654*324bb76bSAndroid Build Coastguard Worker 			}
655*324bb76bSAndroid Build Coastguard Worker 			break;
656*324bb76bSAndroid Build Coastguard Worker 		default: /* Not checked, but must be last one! */
657*324bb76bSAndroid Build Coastguard Worker 			fprintf(stderr, " ");
658*324bb76bSAndroid Build Coastguard Worker 			while (!ISSPACE(CtrlStr[i]) &&
659*324bb76bSAndroid Build Coastguard Worker 			       (i < (int)strlen(CtrlStr)) &&
660*324bb76bSAndroid Build Coastguard Worker 			       !ISCTRLCHAR(CtrlStr[i])) {
661*324bb76bSAndroid Build Coastguard Worker 				fprintf(stderr, "%c", CtrlStr[i++]);
662*324bb76bSAndroid Build Coastguard Worker 			}
663*324bb76bSAndroid Build Coastguard Worker 			fprintf(stderr, "\n");
664*324bb76bSAndroid Build Coastguard Worker 			return;
665*324bb76bSAndroid Build Coastguard Worker 		}
666*324bb76bSAndroid Build Coastguard Worker 	}
667*324bb76bSAndroid Build Coastguard Worker 	fprintf(stderr, "\n");
668*324bb76bSAndroid Build Coastguard Worker }
669*324bb76bSAndroid Build Coastguard Worker 
670*324bb76bSAndroid Build Coastguard Worker /* end */
671