proper argument parsing

This commit is contained in:
anon 2024-08-04 14:38:58 +02:00
parent f6500e6d79
commit a959df320f
7 changed files with 101 additions and 59 deletions

View File

@ -14,7 +14,7 @@ LINKasd += $$(pkgconf --libs ncurses readline sqlite3)
OBJECT.d:=object/ OBJECT.d:=object/
SOURCE.d:=source/ SOURCE.d:=source/
SOURCE:=bash_history.yy.cpp main.cpp cli.cpp tui.cpp storage.cpp damerau_levenshtein.cpp SOURCE:=argument_yy.tab.cpp bash_history.yy.cpp main.cpp cli.cpp tui.cpp storage.cpp damerau_levenshtein.cpp
OBJECT:=$(addprefix ${OBJECT.d},$(addsuffix .o,$(basename ${SOURCE}))) OBJECT:=$(addprefix ${OBJECT.d},$(addsuffix .o,$(basename ${SOURCE})))
SOURCE:=$(addprefix ${SOURCE.d},${SOURCE}) SOURCE:=$(addprefix ${SOURCE.d},${SOURCE})
@ -24,7 +24,10 @@ ${OUTPUT}: ${OBJECT}
${LINK.cpp} ${OBJECT} ${LINKasd} -o ${OUTPUT} ${LINK.cpp} ${OBJECT} ${LINKasd} -o ${OUTPUT}
object/%.yy.cpp: source/%.l object/%.yy.cpp: source/%.l
${LEX} --prefix=$*_ --header-file=$(basename $@).hpp -o $@ $< flex --prefix=$*_ --header-file=$(basename $@).hpp -o $@ $<
object/%.tab.cpp: source/%.y
bison --name-prefix=$*_ --header=$(basename $@).hpp -o $@ $<
object/%.o: object/%.l.cpp object/%.o: object/%.l.cpp
${COMPILE.cpp} $< -o $@ ${COMPILE.cpp} $< -o $@

View File

@ -1,3 +1,4 @@
+ make case insensitive search optional + make case insensitive search optional
+ make fuzzy searching optional + make fuzzy searching optional
+ make (potentially slow) queries cancel using multi threading + make (potentially slow) queries cancel using multi threading
+ the same suggestion should only show up once

29
source/argument_yy.y Normal file
View File

@ -0,0 +1,29 @@
%token HELP VERSION
%token TUI ENABLE
%token LEVENSTEIN
%{
#include "stdio.h"
extern void usage(void);
extern void version(void);
extern void enable(void);
extern void argument_yy_error(const char * const s);
extern int argument_yy_lex(void);
%}
%%
histui_args: global_args verb_and_args
;
global_args: %empty
| HELP { usage(); exit(0); }
| VERSION { version(); exit(0); }
;
verb_and_args: ENABLE { enable(); exit(0); }
| TUI tui_args { ; }
;
tui_args: %empty
| LEVENSTEIN { ; }
;
%%

View File

@ -4,19 +4,17 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
using namespace std; #include "argument_yy.tab.hpp"
int * arg_tokens;
[[ noreturn ]]
void version() { void version() {
puts( puts(
# include "version.inc" # include "version.inc"
); );
exit(0);
} }
[[ noreturn ]] void usage(void) {
void usage(int exit_value) {
// TODO // TODO
puts( puts(
"histui [options] <verb>\n" "histui [options] <verb>\n"
@ -27,37 +25,56 @@ void usage(int exit_value) {
"\t\tenable : print a bash script to enable histui in the current shell\n" "\t\tenable : print a bash script to enable histui in the current shell\n"
"\t\ttui : run histui normally\n" "\t\ttui : run histui normally\n"
); );
exit(exit_value);
} }
void parse_global_options(const int argc, const char * const * const argv) { int argument_yy_lex(void) {
for(int i = 1; i < argc; i++) { static int i = 0;
if (argv[i][0] != '-') { return arg_tokens[i++];
return;
}
if (not strcmp(argv[i], "-v")
|| not strcmp(argv[i], "--version")) {
version();
}
if (not strcmp(argv[i], "-h")
|| not strcmp(argv[i], "--help")) {
usage();
}
}
} }
verb_t get_verb(const int argc, const char * const * const argv) { void argument_yy_error([[ maybe_unused ]] const char * const s) {
for(int i = 1; i < argc; i++) { puts("Argument parsing failed.");
if (argv[i][0] == '-') { usage();
continue; exit(2);
} }
if (not strcmp(argv[i], "tui")) {
return TUI; void parse_arguments(const int argc, const char * const * const argv) {
} if (argc < 2) {
if (not strcmp(argv[i], "enable")) { usage();
return ENABLE; exit(1);
} }
return ERROR;
} /* Lexical analysis of a poor man.
return ERROR; * Using Flex would be problematic because our input
* is not stored in an actual buffer (not in a defined
* behaviour way anyways).
*/
int tokens[argc];
int token_empty_head = 0;
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--help")
|| !strcmp(argv[i], "-h")) {
tokens[token_empty_head++] = HELP;
} else
if (!strcmp(argv[i], "--version")
|| !strcmp(argv[i], "-v")) {
tokens[token_empty_head++] = VERSION;
} else
if (!strcmp(argv[i], "tui")) {
tokens[token_empty_head++] = TUI;
} else
if (!strcmp(argv[i], "enable")) {
tokens[token_empty_head++] = ENABLE;
} else
if (!strcmp(argv[i], "--levenstein")) {
tokens[token_empty_head++] = LEVENSTEIN;
} else {
tokens[token_empty_head++] = YYUNDEF;
}
}
tokens[token_empty_head++] = YYEOF;
arg_tokens = tokens;
argument_yy_parse();
} }

View File

@ -1,11 +1,3 @@
#pragma once #pragma once
typedef enum { void parse_arguments(const int argc, const char * const * const argv);
TUI,
ENABLE,
ERROR,
} verb_t;
extern void parse_global_options(const int argc, const char * const * const argv);
extern verb_t get_verb(const int argc, const char * const * const argv);
[[ noreturn ]] void usage(int exit_value = 0);

View File

@ -40,17 +40,19 @@ bind -x '"\e[A": _histui_run'
bind -x '"\C-r": _histui_run' bind -x '"\C-r": _histui_run'
)delim" )delim"
); );
exit(0); }
void export_result(const char * const result) {
int fd[2];
pipe(fd);
dprintf(3, result);
close(fd[0]);
close(fd[1]);
} }
signed main(int argc, char * argv[]) { signed main(int argc, char * argv[]) {
parse_global_options(argc, argv); // NOTE: never returns on error
verb_t verb = get_verb(argc, argv); parse_arguments(argc, argv);
switch (verb) {
case ENABLE: enable();
case ERROR: usage(1);
case TUI: break;
}
init(); init();
@ -72,11 +74,7 @@ signed main(int argc, char * argv[]) {
} }
query(rl_line_buffer, 1, selection_offset + selection_relative); query(rl_line_buffer, 1, selection_offset + selection_relative);
int fd[2]; export_result(get_entry().command);
pipe(fd);
dprintf(3, get_entry().command);
close(fd[0]);
close(fd[1]);
deinit(); deinit();

View File

@ -4,6 +4,8 @@
#include <sqlite3.h> #include <sqlite3.h>
#include "damerau_levenshtein.hpp" #include "damerau_levenshtein.hpp"
//const char * * const query_method;
static sqlite3 * db; static sqlite3 * db;
static sqlite3_stmt * stmt = NULL; static sqlite3_stmt * stmt = NULL;