aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/args_parser.c98
-rw-r--r--src/args_parser.h31
-rw-r--r--src/geml.c34
-rw-r--r--src/io.c63
-rw-r--r--src/io.h48
-rw-r--r--src/utils.c66
-rw-r--r--src/utils.h54
7 files changed, 394 insertions, 0 deletions
diff --git a/src/args_parser.c b/src/args_parser.c
new file mode 100644
index 0000000..be55e43
--- /dev/null
+++ b/src/args_parser.c
@@ -0,0 +1,98 @@
+/* geml - General extendable macro language
+ * args_parser.c Program arguments parser
+ *
+ * Copyright (C) 2016 Karel Kočí
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include "args_parser.h"
+#include "utils.h"
+#include "io.h"
+
+const char *help_text =
+ "Usage: geml [OPTIONS]... INPUT_FILE\n"
+ " General extendable macro language processing tool.\n"
+ "\n"
+ "Options:\n"
+ " -v, --verbose\n"
+ " Increases vebosity of output.\n"
+ " -q, --quiet\n"
+ " Dcreases verbosity of output.\n"
+ " -o, --output OUTPUT_FILE\n"
+ " Sets file in which output is going to be stored\n"
+ " -h, --help\n"
+ " Prints this text.\n"
+ " --version\n"
+ " Prints geml version\n"
+ "\n"
+ "Report bugs to: <" GEML_CONTACT ">\n"
+ ;
+
+const char *version_text = "geml " GEML_VERSION "\n";
+
+enum ARGS_ENUM {
+ ARGS_ENUM_VERSION = 260
+};
+
+const struct option long_options[] = {
+ {"verbose", no_argument, NULL, 'v'},
+ {"quiet", no_argument, NULL, 'q'},
+ {"output", required_argument, NULL, 'o'},
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, ARGS_ENUM_VERSION}
+};
+
+bool args_parse(int argc, char *argv[]) {
+ char *output = NULL;
+
+ int index = 1;
+ int c;
+ while((c = getopt_long(argc, argv, "vqo:h;", long_options, &index)) != -1) {
+ switch (c) {
+ case 'v': // verbose
+ verbosity_inc();
+ break;
+ case 'q': // quiet
+ verbosity_dec();
+ break;
+ case 'o': // output
+ output = optarg;
+ break;
+ case 'h': // help
+ fputs(help_text, stderr);
+ return true;
+ case ARGS_ENUM_VERSION:
+ fputs(version_text, stderr);
+ return true;
+ default:
+ abort();
+ }
+ }
+
+ if (optind < argc) {
+ if (!set_input(argv[optind]))
+ abort();
+ if ((argc - optind) > 1)
+ WARN("Only first input file is accepted, rest is dropped.");
+ }
+ if (output != NULL && !set_output(output))
+ abort();
+
+ return false;
+}
diff --git a/src/args_parser.h b/src/args_parser.h
new file mode 100644
index 0000000..74967dc
--- /dev/null
+++ b/src/args_parser.h
@@ -0,0 +1,31 @@
+/* geml - General extendable macro language
+ * args_parser.h Program arguments parser
+ *
+ * Copyright (C) 2016 Karel Kočí
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdbool.h>
+
+#ifndef _ARGS_PARSE_
+#define _ARGS_PARSE_
+
+/* Parse arguments from command line
+ * Arguments are as arguments as they are in main function
+ * Returns true if program should exit
+ */
+bool args_parse(int argc, char *argv[]);
+
+#endif /* _ARGS_PARSE_ */
diff --git a/src/geml.c b/src/geml.c
new file mode 100644
index 0000000..cae4b52
--- /dev/null
+++ b/src/geml.c
@@ -0,0 +1,34 @@
+/* geml - General extendable macro language
+ * geml.c Main of geml
+ *
+ * Copyright (C) 2016 Karel Kočí
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "utils.h"
+#include "args_parser.h"
+#include "io.h"
+
+int main(int argc, char *argv[]) {
+ io_init();
+ if (args_parse(argc, argv))
+ return 0; // Arguments parsing resulted to correct early exit of program
+
+ return 0;
+}
diff --git a/src/io.c b/src/io.c
new file mode 100644
index 0000000..3f35607
--- /dev/null
+++ b/src/io.c
@@ -0,0 +1,63 @@
+/* geml - General extendable macro language
+ * io.c Hadndles input and output for parser
+ *
+ * Copyright (C) 2016 Karel Kočí
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "io.h"
+
+FILE *outf;
+const char *outf_name;
+
+FILE *inf;
+const char *inf_name;
+
+void io_init(void) {
+ outf = stdout;
+ outf_name = "stdout";
+ inf = stdin;
+ inf_name = "stdin";
+}
+
+bool set_output(const char *file) {
+ FILE *f;
+ f = fopen(file, "w");
+ if (f == NULL) {
+ ERROR("Output file \"%s\" couldn't be opened: %s", file,
+ strerror(errno));
+ return false;
+ }
+ if (outf != stdout)
+ fclose(outf);
+ outf = f;
+ outf_name = file;
+ return true;
+}
+
+bool set_input(const char *file) {
+ FILE *f;
+ f = fopen(file, "r");
+ if (f == NULL) {
+ ERROR("Input file \"%s\" couldn't be opened: %s", file,
+ strerror(errno));
+ return false;
+ }
+ if (inf != stdin)
+ fclose(inf);
+ inf = f;
+ inf_name = file;
+ return true;
+}
diff --git a/src/io.h b/src/io.h
new file mode 100644
index 0000000..b03315a
--- /dev/null
+++ b/src/io.h
@@ -0,0 +1,48 @@
+/* geml - General extendable macro language
+ * io.h Hadndles input and output for parser
+ *
+ * Copyright (C) 2016 Karel Kočí
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#ifndef _IO_H_
+#define _IO_H_
+#include "utils.h"
+
+// Call this function as soon as possible after program start before outf or inf
+// are used.
+void io_init(void);
+
+// Current output file is closed and opens specified file. When NULL is passed,
+// current file is closed and stdout is used.
+bool set_output(const char *file) __attribute__ ((nonnull));
+
+extern FILE *outf;
+extern const char *outf_name;
+
+// Curent input file is closed and opens specified file. When NULL is passed,
+// current file is closed and stdin is used.
+bool set_input(const char *file) __attribute__ ((nonnull));
+
+extern FILE *inf;
+extern const char *inf_name;
+
+#endif /* _IO_H_ */
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 0000000..3d91753
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,66 @@
+/* geml - General extendable macro language
+ * utils.h Various utility functions
+ *
+ * Copyright (C) 2016 Karel Kočí
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include "utils.h"
+
+static enum Verbosity verbosity = V_INFO;
+
+void verbosity_set(enum Verbosity level) {
+ if (level > V_DIE)
+ level = V_DIE;
+ else if (level < V_DEVEL)
+ level = V_DEVEL;
+ verbosity = level;
+}
+
+void verbosity_inc(void) {
+ verbosity--;
+ verbosity_set(verbosity);
+}
+
+void verbosity_dec(void) {
+ verbosity++;
+ verbosity_set(verbosity);
+}
+
+// TODO colors if terminal supports them
+static const char *v_name[] = {
+ "DEVEL",
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR",
+ "DIE"
+};
+
+void print_message(const char *file, const int line, enum Verbosity level, const char *msg, ...) {
+ ASSERT(level <= V_DIE && level >= V_DEVEL);
+ if (level < verbosity)
+ return;
+ fputs(v_name[level + 2], stderr);
+ if (verbosity <= V_DEBUG)
+ fprintf(stderr, ":%s:%d", file, line);
+ fputs(":", stderr);
+ va_list args;
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ fputs("\n", stderr);
+}
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..f93992d
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,54 @@
+/* geml - General extendable macro language
+ * utils.h Various utility functions
+ *
+ * Copyright (C) 2016 Karel Kočí
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+enum Verbosity {
+ V_DEVEL = -2,
+ V_DEBUG,
+ V_INFO, // = 0
+ V_WARN,
+ V_ERROR,
+ V_DIE
+};
+
+// Sets verbosity level
+void verbosity_set(enum Verbosity level);
+void verbosity_inc(void);
+void verbosity_dec(void);
+
+// Prints given message if it isn't lower than chosen verbosity level
+void print_message(const char *file, const int line, enum Verbosity level, const char *msg, ...);
+#define _PRINT_MESSAGE(LEVEL, ...) print_message(__FILE__, __LINE__, LEVEL, __VA_ARGS__)
+#define DIE(...) do { _PRINT_MESSAGE(V_DIE, __VA_ARGS__); abort(); } while(0)
+#define ERROR(...) _PRINT_MESSAGE(V_ERROR, __VA_ARGS__)
+#define WARN(...) _PRINT_MESSAGE(V_WARN, __VA_ARGS__)
+#define INFO(...) _PRINT_MESSAGE(V_INFO, __VA_ARGS__)
+#define DBG(...) _PRINT_MESSAGE(V_DEBUG, __VA_ARGS__)
+#ifdef DEBUG
+#define DVL(...) _PRINT_MESSAGE(V_DEVEL, __VA_ARGS__)
+#else /* DEBUG */
+#define DEVEL(...)
+#endif /* DEBUG */
+
+#define ASSERT(CHECK) do { if (!(CHECK)) { printf("Assertion failed on %s:%d\n", __FILE__, __LINE__); } } while(0)
+
+#endif /* _UTILS_H_ */