proper cli

This commit is contained in:
anon 2024-09-15 02:19:58 +02:00
parent 8a85558cf9
commit 6fe925026d
4 changed files with 114 additions and 27 deletions

View File

@ -5,7 +5,7 @@ SOURCE.d := source
OBJECT.d := object
LIB.d := library/
SOURCE := main.c
SOURCE := main.c cli.c
OBJECT := $(addprefix ${OBJECT.d}/,${SOURCE})
OBJECT := ${OBJECT:.c=.o}

71
source/cli.c Normal file
View File

@ -0,0 +1,71 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
extern void yyerror(const char * const fmt, ...);
char * output_file_name = NULL;
char * input_file_name = NULL;
static
const char * help_message = "\
tbsp [options] <file> : convert tbsp source file to C/C++ source file\n\
-h : show help\n\
-o <string> : specify output file\
";
static
char * default_output_name(const char * const name) {
static const char default_extension[] = ".tb.c";
char * r;
const int len = strlen(name);
int i = len;
for (; i != 0; i--) {
if (name[i] == '.') {
break;
}
}
if (i == 0) {
i = len;
}
r = (char *)malloc(i + sizeof(default_extension));
memcpy(r, name, i);
memcpy(r + i, default_extension, sizeof(default_extension));
return r;
}
int handle_arguments(const int argc, const char * const * const argv) {
if (argc < 2) {
puts(help_message);
return 1;
}
int opt;
while ((opt = getopt(argc, (char * const *)argv, "ho:")) != -1) {
switch (opt) {
case 'h': {
puts(help_message);
} exit(0);
case 'o': {
output_file_name = optarg;
} break;
default: {
yyerror("unknown option '%s'", argv[optind]);
} return 1;
}
}
input_file_name = strdup(argv[argc-1]);
if (!output_file_name) {
output_file_name = default_output_name(input_file_name);
}
return 0;
}

7
source/cli.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef CLI_H
#define CLI_H
extern char * const output_file_name;
extern char * const input_file_name;
int handle_arguments(const int argc, const char * const * const argv);
#endif

View File

@ -1,12 +1,23 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include "tbsp.yy.h"
#include "tbsp.tab.h"
#include "cli.h"
// XXX i am so desperate for #embed, you would not believe
#include "TBSP_strings.inc"
#define CHECKED_FOPEN(target, filename, mode) do {\
target = fopen(filename, mode);\
if (!target) {\
yyerror("failed to open '%s'", filename);\
return 1;\
}\
} while (0)
extern int tbsp_yy_init(void);
extern int tbsp_yy_deinit(void);
@ -26,6 +37,7 @@ void yyerror(const char * const fmt, ...) {
va_end(args);
}
static
void put_rule_table(const char * const name, rule_type_t type_mask) {
char * sprint_buffer;
int sprint_r;
@ -47,32 +59,8 @@ void put_rule_table(const char * const name, rule_type_t type_mask) {
fputs("};\n\n", yyout);
}
signed main(const int argc, const char * const * const argv) {
#ifdef DEBUG
yydebug = 1;
#endif
if (argc < 2) {
printf("%s <file>", argv[0]);
}
tbsp_yy_init();
tbsp_tab_init();
yyin = fopen(argv[1], "r");
if (!yyin) {
puts("Failed to open file");
return 1;
}
//yyout = fopen("tbsp.c", "w");
yyout = stdout;
int yyparse_r = yyparse();
if (yyparse_r) {
return 1;
}
static
void put_output(void) {
char * sprint_buffer;
int sprint_r;
(void)sprint_r;
@ -108,6 +96,25 @@ signed main(const int argc, const char * const * const argv) {
// Code section
fputs(verbatim, yyout);
}
signed main(const int argc, const char * const * const argv) {
#ifdef DEBUG
yydebug = 1;
#endif
if (handle_arguments(argc, argv)) { return 1; }
tbsp_yy_init();
tbsp_tab_init();
CHECKED_FOPEN(yyin, input_file_name, "r");
CHECKED_FOPEN(yyout, output_file_name, "w");
int yyparse_r = yyparse();
if (yyparse_r) { return yyparse_r; }
put_output();
// Deinit
for (int i = 0; i < kv_size(rules); i++) {
@ -116,6 +123,8 @@ signed main(const int argc, const char * const * const argv) {
}
tbsp_yy_deinit();
free(output_file_name);
free(input_file_name);
free(verbatim);
free(language);
free(top);