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