proper cli
This commit is contained in:
parent
8a85558cf9
commit
6fe925026d
2
Makefile
2
Makefile
@ -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
71
source/cli.c
Normal 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
7
source/cli.h
Normal 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
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user