Add getopt, getopt_long

This commit is contained in:
K. Lange 2018-05-02 18:58:47 +09:00
parent b8cbbd2af4
commit b4c1d997b4
15 changed files with 231 additions and 148 deletions

View File

@ -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.");

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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();

View File

@ -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];

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -1,5 +1,4 @@
#include <stdio.h>
#include <getopt.h>
#include <toaru/yutani.h>

View File

@ -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 */

View File

@ -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
View 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
View 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;
}