-
Notifications
You must be signed in to change notification settings - Fork 2
/
android_popt.cc
124 lines (108 loc) · 3.49 KB
/
android_popt.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* Copyright (C) 2015 The Android Open Source Project
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <popt.h>
// #define LOCAL_DEBUG
/*
* popt has been deprecated for some time, and is replaced by GNOME's glib
* option parser. Instead of pulling in either of those dependencies, this
* stub implements just enough of popt to get things working.
*/
poptContext poptGetContext(const char *name, int argc, const char **argv,
const struct poptOption *options, unsigned int flags) {
// Convert into getopt format, sanity checking our limited
// capabilities along the way
int count = 0;
for (; options[count].longName; count++) {
}
struct option *long_options = (struct option *)
calloc(count, sizeof(struct option));
for (int i = 0; options[i].longName; i++) {
long_options[i].name = options[i].longName;
long_options[i].flag = 0;
if (!options[i].val) {
fprintf(stderr, __FILE__ ": val required\n");
abort();
}
long_options[i].val = options[i].val;
switch (options[i].argInfo) {
case POPT_ARG_NONE:
long_options[i].has_arg = no_argument;
break;
case POPT_ARG_STRING:
case POPT_ARG_INT:
if (!options[i].arg) {
fprintf(stderr, __FILE__ ": arg required\n");
abort();
}
long_options[i].has_arg = required_argument;
break;
default:
fprintf(stderr, __FILE__ ": unsupported argInfo\n");
abort();
}
}
poptContext con = (poptContext) calloc(1, sizeof(struct _poptContext));
con->argc = argc;
con->argv = argv;
con->options = options;
con->long_options = long_options;
return con;
}
poptContext poptFreeContext(poptContext con) {
free(con->long_options);
free(con);
return 0;
}
void poptResetContext(poptContext con) {
optind = 1;
}
void poptSetOtherOptionHelp(poptContext con, const char *text) {
con->otherHelp = text;
}
void poptPrintUsage(poptContext con, FILE *fp, int flags) {
fprintf(fp, "USAGE: %s %s\n", con->argv[0], con->otherHelp);
int i = 0;
for (; con->options[i].longName; i++) {
fprintf(fp, "\t--%s\t%s\n", con->options[i].longName,
con->options[i].descrip);
}
fprintf(fp, "\n");
}
int poptGetNextOpt(poptContext con) {
int i = -1;
int res = getopt_long(con->argc, (char *const *) con->argv, "",
con->long_options, &i);
#ifdef LOCAL_DEBUG
fprintf(stderr, "getopt_long()=%c\n", res);
#endif
if (res == 0 || res == '?') {
return -1;
}
// Copy over found argument value
switch (con->options[i].argInfo) {
case POPT_ARG_STRING:
*((char**) con->options[i].arg) = strdup(optarg);
break;
case POPT_ARG_INT:
*((int*) con->options[i].arg) = atoi(optarg);
break;
}
return res;
}
const char *poptGetArg(poptContext con) {
const char *res = con->argv[optind++];
#ifdef LOCAL_DEBUG
fprintf(stderr, "poptGetArg()=%s\n", res);
#endif
return res;
}