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