Skip to content

Commit

Permalink
Move getopt* files to libc folder and convert to C++
Browse files Browse the repository at this point in the history
Signed-off-by: Waldemar Kozaczuk <[email protected]>
Message-Id: <[email protected]>
  • Loading branch information
wkozaczuk authored and nyh committed May 13, 2019
1 parent 83128b2 commit 7a4d96b
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1329,8 +1329,8 @@ libc += misc/error.o
libc += misc/ffs.o
musl += misc/get_current_dir_name.o
libc += misc/gethostid.o
musl += misc/getopt.o
musl += misc/getopt_long.o
libc += misc/getopt.o
libc += misc/getopt_long.o
musl += misc/getsubopt.o
libc += misc/realpath.o
libc += misc/backtrace.o
Expand Down
77 changes: 77 additions & 0 deletions libc/misc/getopt.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include <unistd.h>
#include <wchar.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <libc/libc.hh>

extern "C" {

char *optarg;
int optind=1, opterr=1, optopt, __optpos, __optreset=0;

#define optpos __optpos
weak_alias(__optreset, optreset);

int getopt(int argc, char * const argv[], const char *optstring)
{
int i;
wchar_t c, d;
int k, l;
char *optchar;

if (!optind || __optreset) {
__optreset = 0;
__optpos = 0;
optind = 1;
}

if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1])
return -1;
if (argv[optind][1] == '-' && !argv[optind][2])
return optind++, -1;

if (!optpos) optpos++;
if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
k = 1;
c = 0xfffd; /* replacement char */
}
optchar = argv[optind]+optpos;
optopt = c;
optpos += k;

if (!argv[optind][optpos]) {
optind++;
optpos = 0;
}

for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);

if (d != c) {
if (optstring[0] != ':' && opterr) {
write(2, argv[0], strlen(argv[0]));
write(2, ": illegal option: ", 18);
write(2, optchar, k);
write(2, "\n", 1);
}
return '?';
}
if (optstring[i+1] == ':') {
if (optind >= argc) {
if (optstring[0] == ':') return ':';
if (opterr) {
write(2, argv[0], strlen(argv[0]));
write(2, ": option requires an argument: ", 31);
write(2, optchar, k);
write(2, "\n", 1);
}
return '?';
}
optarg = argv[optind++] + optpos;
optpos = 0;
}
return c;
}

weak_alias(getopt, __posix_getopt);
}
61 changes: 61 additions & 0 deletions libc/misc/getopt_long.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <stddef.h>
#include <getopt.h>
#include <stdio.h>

extern "C" {

extern int __optpos, __optreset;

static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
{
if (!optind || __optreset) {
__optreset = 0;
__optpos = 0;
optind = 1;
}
if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1;
if ((longonly && argv[optind][1]) ||
(argv[optind][1] == '-' && argv[optind][2]))
{
int i;
for (i=0; longopts[i].name; i++) {
const char *name = longopts[i].name;
char *opt = argv[optind]+1;
if (*opt == '-') opt++;
for (; *name && *name == *opt; name++, opt++);
if (*name || (*opt && *opt != '=')) continue;
if (*opt == '=') {
if (!longopts[i].has_arg) continue;
optarg = opt+1;
} else {
if (longopts[i].has_arg == required_argument) {
if (!(optarg = argv[++optind]))
return ':';
} else optarg = NULL;
}
optind++;
if (idx) *idx = i;
if (longopts[i].flag) {
*longopts[i].flag = longopts[i].val;
return 0;
}
return longopts[i].val;
}
if (argv[optind][1] == '-') {
optind++;
return '?';
}
}
return getopt(argc, argv, optstring);
}

int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
{
return __getopt_long(argc, argv, optstring, longopts, idx, 0);
}

int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
{
return __getopt_long(argc, argv, optstring, longopts, idx, 1);
}
}

0 comments on commit 7a4d96b

Please sign in to comment.