Add getopt, getopt_long
This commit is contained in:
parent
b8cbbd2af4
commit
b4c1d997b4
@ -93,46 +93,8 @@ static int usage(char * argv[]) {
|
||||
* Parse arguments
|
||||
*/
|
||||
static int parse_args(int argc, char * argv[], int * out) {
|
||||
*out = 1;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] == '-') {
|
||||
char *c = &argv[i][1];
|
||||
*out = *out + 1;
|
||||
while (*c) {
|
||||
switch (*c) {
|
||||
case 'n':
|
||||
yutani_options.nested = 1;
|
||||
break;
|
||||
case 'g':
|
||||
{
|
||||
char * c = strstr(argv[i+1], "x");
|
||||
if (c) {
|
||||
*c = '\0';
|
||||
c++;
|
||||
yutani_options.nest_width = atoi(argv[i+1]);
|
||||
yutani_options.nest_height = atoi(c);
|
||||
}
|
||||
i += 2;
|
||||
goto _next;
|
||||
}
|
||||
case 'h':
|
||||
return usage(argv);
|
||||
case '-':
|
||||
// hm
|
||||
return 0;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognized option: %c\n", *c);
|
||||
break;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
_next:
|
||||
;
|
||||
}
|
||||
#if 0
|
||||
static struct option long_opts[] = {
|
||||
{"nest", no_argument, 0, 'n'},
|
||||
{"nested", no_argument, 0, 'n'},
|
||||
{"geometry", required_argument, 0, 'g'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0,0,0,0}
|
||||
@ -168,7 +130,6 @@ _next:
|
||||
}
|
||||
}
|
||||
*out = optind;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2067,6 +2028,7 @@ int main(int argc, char * argv[]) {
|
||||
yg->resize_on_next = 1;
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_WINDOW_CLOSE:
|
||||
case YUTANI_MSG_SESSION_END:
|
||||
{
|
||||
TRACE("Host session ended. Should exit.");
|
||||
|
38
apps/free.c
38
apps/free.c
@ -7,6 +7,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void show_usage(int argc, char * argv[]) {
|
||||
printf(
|
||||
@ -27,28 +28,21 @@ int main(int argc, char * argv[]) {
|
||||
int use_kilobytes = 0;
|
||||
int show_total = 0;
|
||||
|
||||
if (argc > 1) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] == '-') {
|
||||
char *c = &argv[i][1];
|
||||
while (*c) {
|
||||
switch (*c) {
|
||||
case 'u':
|
||||
show_used = 1;
|
||||
break;
|
||||
case 't':
|
||||
show_total = 1;
|
||||
break;
|
||||
case 'k':
|
||||
use_kilobytes = 1;
|
||||
break;
|
||||
case '?':
|
||||
show_usage(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "utk?")) != -1) {
|
||||
switch (c) {
|
||||
case 'u':
|
||||
show_used = 1;
|
||||
break;
|
||||
case 't':
|
||||
show_total = 1;
|
||||
break;
|
||||
case 'k':
|
||||
use_kilobytes = 1;
|
||||
break;
|
||||
case '?':
|
||||
show_usage(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strcmp(argv[1], "--vga")) {
|
||||
return start_options((char *[]){"/bin/terminal-vga","-l",NULL});
|
||||
return start_options((char *[]){"/bin/terminal-vga",NULL});
|
||||
} else if (!strcmp(argv[1], "--migrate")) {
|
||||
return start_options((char *[]){"/bin/migrate",NULL});
|
||||
} else {
|
||||
|
@ -188,7 +188,6 @@ void resize_finish(int w, int h) {
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
#if 0
|
||||
static struct option long_opts[] = {
|
||||
{"no-repeat", no_argument, 0, 'n'},
|
||||
{"initer", required_argument, 0, 'i'},
|
||||
@ -215,6 +214,7 @@ int main(int argc, char * argv[]) {
|
||||
case 'n':
|
||||
no_repeat = 1;
|
||||
break;
|
||||
#if 0
|
||||
case 'i':
|
||||
initer = atof(optarg);
|
||||
break;
|
||||
@ -230,6 +230,7 @@ int main(int argc, char * argv[]) {
|
||||
case 'C':
|
||||
cony = atof(optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'W':
|
||||
width = atoi(optarg);
|
||||
break;
|
||||
@ -245,7 +246,6 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
yctx = yutani_init();
|
||||
init_decorations();
|
||||
|
31
apps/ls.c
31
apps/ls.c
@ -365,9 +365,8 @@ int main (int argc, char * argv[]) {
|
||||
/* Parse arguments */
|
||||
char * p = ".";
|
||||
|
||||
#if 0
|
||||
if (argc > 1) {
|
||||
int index, c;
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "ahl?")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
@ -384,34 +383,6 @@ int main (int argc, char * argv[]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int optind = 1;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] == '-') {
|
||||
char *c = &argv[i][1];
|
||||
optind++;
|
||||
while (*c) {
|
||||
switch (*c) {
|
||||
case 'a':
|
||||
show_hidden = 1;
|
||||
break;
|
||||
case 'h':
|
||||
human_readable = 1;
|
||||
break;
|
||||
case 'l':
|
||||
long_mode = 1;
|
||||
break;
|
||||
case '?':
|
||||
show_usage(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
#endif
|
||||
|
||||
if (optind < argc) {
|
||||
p = argv[optind];
|
||||
|
@ -210,11 +210,11 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
TRACE("Launching intended startup app...");
|
||||
if (!strcmp(start, "--vga")) {
|
||||
execvp("/bin/terminal-vga", (char *[]){"terminal-vga","-l",NULL});
|
||||
execvp("/bin/terminal-vga", (char *[]){"terminal-vga",NULL});
|
||||
} else if (start) {
|
||||
execvp("/bin/compositor", (char *[]){"comositor","--",start,NULL});
|
||||
execvp("/bin/compositor", (char *[]){"compositor","--",start,NULL});
|
||||
} else {
|
||||
execvp("/bin/compositor", (char *[]){"comositor",NULL});
|
||||
execvp("/bin/compositor", (char *[]){"compositor",NULL});
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -364,9 +364,8 @@ int main(int argc, char ** argv) {
|
||||
|
||||
/* Whether or not to show the MOTD intro */
|
||||
char show_intro = 0;
|
||||
//char skip_intro = 0;
|
||||
char skip_intro = 0;
|
||||
|
||||
#if 0
|
||||
/* Long option names */
|
||||
static struct option long_opts[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
@ -444,8 +443,8 @@ int main(int argc, char ** argv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)skip_intro;
|
||||
#if 0
|
||||
if (telnet) {
|
||||
/* Telnet mode */
|
||||
|
18
apps/sh.c
18
apps/sh.c
@ -826,23 +826,8 @@ int main(int argc, char ** argv) {
|
||||
//add_path_contents("/usr/bin");
|
||||
sort_commands();
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (!strcmp(argv[i], "-c")) {
|
||||
return shell_exec(argv[i+1]);
|
||||
}
|
||||
if (!strcmp(argv[i], "-v")) {
|
||||
show_version();
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[i], "-?")) {
|
||||
show_usage(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (argc > 1) {
|
||||
int index, c;
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "c:v?")) != -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
@ -857,7 +842,6 @@ int main(int argc, char ** argv) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
shell_interactive = 1;
|
||||
|
||||
|
@ -784,7 +784,6 @@ int main(int argc, char ** argv) {
|
||||
|
||||
_login_shell = 0;
|
||||
|
||||
#if 0
|
||||
static struct option long_opts[] = {
|
||||
{"login", no_argument, 0, 'l'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
@ -794,11 +793,6 @@ int main(int argc, char ** argv) {
|
||||
/* Read some arguments */
|
||||
int index, c;
|
||||
while ((c = getopt_long(argc, argv, "hl", long_opts, &index)) != -1) {
|
||||
if (!c) {
|
||||
if (long_opts[index].flag == 0) {
|
||||
c = long_opts[index].val;
|
||||
}
|
||||
}
|
||||
switch (c) {
|
||||
case 'l':
|
||||
_login_shell = 1;
|
||||
@ -814,8 +808,7 @@ int main(int argc, char ** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
putenv("TERM=toaru");
|
||||
#endif
|
||||
//putenv("TERM=toaru");
|
||||
|
||||
#if 1
|
||||
char * _env = malloc(strlen("TERM=toaru"));
|
||||
@ -865,13 +858,11 @@ int main(int argc, char ** argv) {
|
||||
dup2(fd_slave, 1);
|
||||
dup2(fd_slave, 2);
|
||||
|
||||
#if 0
|
||||
if (argv[optind] != NULL) {
|
||||
char * tokens[] = {argv[optind], NULL};
|
||||
int i = execvp(tokens[0], tokens);
|
||||
execvp(tokens[0], tokens);
|
||||
fprintf(stderr, "Failed to launch requested startup application.\n");
|
||||
} else {
|
||||
#endif
|
||||
if (_login_shell) {
|
||||
char * tokens[] = {"/bin/login",NULL};
|
||||
execvp(tokens[0], tokens);
|
||||
@ -883,9 +874,7 @@ int main(int argc, char ** argv) {
|
||||
execvp(tokens[0], tokens);
|
||||
exit(1);
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
exit_application = 1;
|
||||
|
||||
|
@ -538,14 +538,27 @@ term_write_char(
|
||||
#endif
|
||||
}
|
||||
_extra_stuff:
|
||||
if (flags & ANSI_UNDERLINE) {
|
||||
for (uint8_t i = 0; i < char_width; ++i) {
|
||||
term_set_point(x + i, y + char_offset + 2, _fg);
|
||||
if (_use_freetype) {
|
||||
if (flags & ANSI_UNDERLINE) {
|
||||
for (uint8_t i = 0; i < char_width; ++i) {
|
||||
term_set_point(x + i, y + char_offset + 2, _fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flags & ANSI_CROSS) {
|
||||
for (uint8_t i = 0; i < char_width; ++i) {
|
||||
term_set_point(x + i, y + char_offset - 5, _fg);
|
||||
if (flags & ANSI_CROSS) {
|
||||
for (uint8_t i = 0; i < char_width; ++i) {
|
||||
term_set_point(x + i, y + char_offset - 5, _fg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (flags & ANSI_UNDERLINE) {
|
||||
for (uint8_t i = 0; i < char_width; ++i) {
|
||||
term_set_point(x + i, y + char_height - 1, _fg);
|
||||
}
|
||||
}
|
||||
if (flags & ANSI_CROSS) {
|
||||
for (uint8_t i = 0; i < char_width; ++i) {
|
||||
term_set_point(x + i, y + char_height - 7, _fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flags & ANSI_BORDER) {
|
||||
@ -1292,9 +1305,11 @@ void usage(char * argv[]) {
|
||||
"usage: %s [-b] [-F] [-h]\n"
|
||||
"\n"
|
||||
" -F --fullscreen \033[3mRun in fullscreen (background) mode.\033[0m\n"
|
||||
#if 0
|
||||
" -b --bitmap \033[3mUse the integrated bitmap font.\033[0m\n"
|
||||
" -h --help \033[3mShow this help message.\033[0m\n"
|
||||
" -s --scale \033[3mScale the font in FreeType mode by a given amount.\033[0m\n"
|
||||
#endif
|
||||
" -h --help \033[3mShow this help message.\033[0m\n"
|
||||
" -x --grid \033[3mMake resizes round to nearest match for character cell size.\033[0m\n"
|
||||
" -n --no-frame \033[3mDisable decorations.\033[0m\n"
|
||||
"\n"
|
||||
@ -1598,16 +1613,17 @@ int main(int argc, char ** argv) {
|
||||
window_width = char_width * 80;
|
||||
window_height = char_height * 24;
|
||||
|
||||
#if 0
|
||||
static struct option long_opts[] = {
|
||||
{"fullscreen", no_argument, 0, 'F'},
|
||||
#if 0
|
||||
{"bitmap", no_argument, 0, 'b'},
|
||||
{"scale", required_argument, 0, 's'},
|
||||
#endif
|
||||
{"login", no_argument, 0, 'l'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"kernel", no_argument, 0, 'k'},
|
||||
{"grid", no_argument, 0, 'x'},
|
||||
{"no-frame", no_argument, 0, 'n'},
|
||||
{"scale", required_argument, 0, 's'},
|
||||
{"geometry", required_argument, 0, 'g'},
|
||||
{0,0,0,0}
|
||||
};
|
||||
@ -1644,10 +1660,12 @@ int main(int argc, char ** argv) {
|
||||
usage(argv);
|
||||
return 0;
|
||||
break;
|
||||
#if 0
|
||||
case 's':
|
||||
scale_fonts = 1;
|
||||
font_scaling = atof(optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'g':
|
||||
{
|
||||
char * c = strstr(optarg, "x");
|
||||
@ -1665,7 +1683,6 @@ int main(int argc, char ** argv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// XXX
|
||||
//putenv("TERM=toaru");
|
||||
@ -1771,13 +1788,11 @@ int main(int argc, char ** argv) {
|
||||
dup2(fd_slave, 1);
|
||||
dup2(fd_slave, 2);
|
||||
|
||||
#if 0
|
||||
if (argv[optind] != NULL) {
|
||||
char * tokens[] = {argv[optind], NULL};
|
||||
int i = execvp(tokens[0], tokens);
|
||||
execvp(tokens[0], tokens);
|
||||
fprintf(stderr, "Failed to launch requested startup application.\n");
|
||||
} else {
|
||||
#endif
|
||||
if (_login_shell) {
|
||||
char * tokens[] = {"/bin/login",NULL};
|
||||
execvp(tokens[0], tokens);
|
||||
@ -1789,9 +1804,7 @@ int main(int argc, char ** argv) {
|
||||
execvp(tokens[0], tokens);
|
||||
exit(1);
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
exit_application = 1;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <toaru/yutani.h>
|
||||
|
||||
|
@ -1 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
struct option {
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
extern char * optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
extern int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2 /* Unsupported */
|
||||
|
@ -45,6 +45,10 @@ extern off_t lseek(int fd, off_t offset, int whence);
|
||||
|
||||
extern int access(const char * pathname, int mode);
|
||||
|
||||
extern int getopt(int argc, char * const argv[], const char * optstring);
|
||||
|
||||
extern char * optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
|
11
libc/unistd/getopt.c
Normal file
11
libc/unistd/getopt.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
char * optarg = NULL;
|
||||
int optind = 1;
|
||||
int opterr = 1;
|
||||
int optopt = 0;
|
||||
|
||||
int getopt(int argc, char * const argv[], const char * optstring) {
|
||||
return getopt_long(argc, argv, optstring, NULL, 0);
|
||||
}
|
141
libc/unistd/getopt_long.c
Normal file
141
libc/unistd/getopt_long.c
Normal file
@ -0,0 +1,141 @@
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* getopt / getopt_long
|
||||
*/
|
||||
|
||||
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex) {
|
||||
static char * nextchar = NULL;
|
||||
|
||||
if (optind >= argc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!nextchar) {
|
||||
nextchar = argv[optind];
|
||||
if (*nextchar != '-') {
|
||||
return -1;
|
||||
} else {
|
||||
nextchar++;
|
||||
|
||||
if (*nextchar == '\0') {
|
||||
/* Special case - is a non-option argument */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*nextchar == '-') {
|
||||
if (nextchar[1] == '\0') {
|
||||
/* End of arguments */
|
||||
optind++;
|
||||
return -1;
|
||||
} else {
|
||||
if (!longopts) {
|
||||
optind++;
|
||||
return -1;
|
||||
}
|
||||
/* Scan through options */
|
||||
nextchar++;
|
||||
char tmp[strlen(nextchar)+1];
|
||||
strcpy(tmp, nextchar);
|
||||
char * eq = strchr(tmp, '=');
|
||||
if (eq) {
|
||||
*eq = '\0';
|
||||
optarg = nextchar + (eq - tmp + 1);
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
|
||||
int found = -1;
|
||||
for (int index = 0; longopts[index].name; ++index) {
|
||||
if (!strcmp(longopts[index].name, tmp)) {
|
||||
found = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == -1) {
|
||||
if (longindex) {
|
||||
*longindex = -1;
|
||||
}
|
||||
if (opterr) {
|
||||
fprintf(stderr, "unknown long argument: %s\n", tmp);
|
||||
}
|
||||
nextchar = NULL;
|
||||
optind++;
|
||||
optopt = '\0';
|
||||
return '?';
|
||||
} else {
|
||||
if (longindex) {
|
||||
*longindex = found;
|
||||
}
|
||||
if (longopts[found].has_arg == required_argument) {
|
||||
if (!optarg) {
|
||||
optarg = argv[optind+1];
|
||||
optind++;
|
||||
}
|
||||
}
|
||||
nextchar = NULL;
|
||||
optind++;
|
||||
if (!longopts[found].flag) {
|
||||
return longopts[found].val;
|
||||
} else {
|
||||
*longopts[found].flag = longopts[found].val;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*nextchar == '\0') {
|
||||
nextchar = NULL;
|
||||
optind++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*nextchar < 'A' || *nextchar > 'z' || (*nextchar > 'Z' && *nextchar < 'a')) && (*nextchar != '?')) {
|
||||
if (opterr) {
|
||||
fprintf(stderr, "Invalid option character: %c\n", *nextchar);
|
||||
}
|
||||
optopt = *nextchar;
|
||||
nextchar++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
char * opt = strchr(optstring, *nextchar);
|
||||
|
||||
if (!opt) {
|
||||
if (opterr) {
|
||||
fprintf(stderr, "Invalid option character: %c\n", *nextchar);
|
||||
}
|
||||
optopt = *nextchar;
|
||||
nextchar++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
int optout = *nextchar;
|
||||
|
||||
if (opt[1] == ':') {
|
||||
if (nextchar[1] != '\0') {
|
||||
optarg = &nextchar[1];
|
||||
nextchar = NULL;
|
||||
optind++;
|
||||
} else {
|
||||
optarg = argv[optind+1];
|
||||
optind += 2;
|
||||
nextchar = NULL;
|
||||
}
|
||||
} else {
|
||||
nextchar++;
|
||||
}
|
||||
|
||||
return optout;
|
||||
|
||||
} while (optind < argc);
|
||||
|
||||
return -1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user