aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorThomas Albers Raviola <thomas@thomaslabs.org>2025-03-13 15:58:09 +0100
committerThomas Albers Raviola <thomas@thomaslabs.org>2025-03-13 15:58:09 +0100
commit5ba1561999f8df7e0e622db8686ec1c4e0045d5f (patch)
tree1ed2fa10f7cdaa27454c1b3937e07ead78b6536e /src/main.c
Initial commitHEADmaster
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..fc965aa
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,150 @@
+/*
+ ihex
+ Copyright (C) 2025 Thomas Albers Raviola <thomas@thomaslabs.org>
+
+ 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <util.h>
+#include <ihex.h>
+#include <array.h>
+
+static void
+usage(void)
+{
+ fputs("\
+Usage: ihex [OPTION]... [[BASE:]FILE]...\n", stdout);
+ fputs("\
+Convert ihex FILEs into binary data\n\n", stdout);
+ fputs("\
+ -h, --help display this help and exit\n", stdout);
+ fputs("\
+ -o, --output=NAME write output to NAME\n", stdout);
+ fputs("\n\
+The BASE argument is a base 16 encoded number indicating where to place the\n\
+file contents inside the resulting image\n\n", stdout);
+ fputs("\
+ihex home page: <https://thomaslabs.org/software/ihex>\n\
+\n\
+Copyright (C) 2025 Thomas Albers Raviola\n\
+This program comes with ABSOLUTELY NO WARRANTY.\n\
+This is free software: you free to change and redistribute it.\n",
+ stdout);
+}
+
+static const char *opts = "ho:";
+static const struct option longopts[] = {
+ {.name = "help", .has_arg = 0, .flag = NULL, .val = 'h'},
+ {.name = "output", .has_arg = 1, .flag = NULL, .val = 'o'},
+ {0, 0, 0, 0}
+};
+
+static const char *output;
+
+void
+decode_args(int argc, char *argv[])
+{
+ int c;
+ while ((c = getopt_long(argc, argv, opts, longopts, NULL)) != -1) {
+ switch (c) {
+ case 0:
+ break;
+ case 'h':
+ usage();
+ exit(EXIT_SUCCESS);
+ case 'o':
+ output = optarg;
+ break;
+ case '?':
+ usage();
+ exit(EXIT_FAILURE);
+ default:
+ break;
+ }
+ }
+}
+
+int
+decode_filename(char *arg, long *base_address, const char **filename)
+{
+ char *junk;
+ char *sep = strchr(arg, ':');
+
+ if (sep) {
+ *sep++ = '\0';
+ *filename = sep;
+ *base_address = strtol(arg, &junk, 16);
+
+ if (*junk) {
+ fprintf(stderr, "Invalid base address for file %s\n",
+ *filename);
+ return -1;
+ }
+ } else {
+ *filename = arg;
+ *base_address = NO_BASE_ADDRESS;
+ }
+
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int err = 0;
+ unsigned int i;
+ struct array blocks;
+ struct array data;
+
+ decode_args(argc, argv);
+
+ init_array(&blocks, sizeof(struct block));
+ init_array(&data, sizeof(char));
+
+ for (i = optind; i < argc; ++i) {
+ long base_address;
+ const char *filename;
+
+ err = decode_filename(argv[i], &base_address, &filename);
+ if (err < 0)
+ goto error;
+
+ err = read_ihex_file(filename, &blocks, &data, base_address);
+ if (err < 0)
+ goto error;
+ }
+
+ FILE *file = output ? fopen(output, "w") : stdout;
+
+ if (!file) {
+ err = 1;
+ fprintf(stderr, "Could not open output file %s\n", output);
+ goto error;
+ }
+
+ err = write_hex(&blocks, &data, file);
+
+ if (output)
+ fclose(file);
+
+error:
+ free_array(&blocks);
+ free_array(&data);
+ return err;
+}