summaryrefslogtreecommitdiff
path: root/source/checkParams.c
blob: 47bdeefdf94460c155746c13ffdafd5a0aaaae68 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
	Copyright 2022-2023 Gabriel Bjørnager Jensen.

	This file is part of agbsum.

	agbsum is free software: you can redistribute it
	and/or modify it under the terms of the GNU
	Affero General Public License as published by
	the Free Software Foundation, either version 3
	of the License, or (at your option) any later
	version.

	agbsum 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 Affero General Public License for more
	details.

	You should have received a copy of the GNU
	Affero General Public License along with agbsum.
	If not, see <https://www.gnu.org/licenses/>.
*/

#include <agbsum.h>

#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>

noreturn static void
agb_expectedParamValue (char const charParam)
{
	fprintf (stderr, "Expected value for character parameter '%c'\n", charParam);
	agb_exit (agb_Cnd_Error, NULL);
}

static bool
agb_checkCharParam (struct agb_Data* const restrict data, char const* const restrict param)
{
	// Returns true if the rest of the parameter is
	// used as a value.

	char const charParam = param[0x0];
	if (charParam == '\x0') {return true;}

	char const* const restrict paramval = &param[0x1];

	switch (charParam) {
	default:
		fprintf (stderr, "Invalid character parameter '%c'\n", charParam);
		agb_exit (agb_Cnd_Error, NULL);

	case 'h':
		agb_help ();
		agb_exit (agb_Cnd_Ok, NULL);

	case 'i':
		{
			if (paramval[0x0] == '\x0') {agb_expectedParamValue (charParam);}
			data->path = paramval;
		}
		return true;

	case 'p':
		data->doPatch = true;
		return false;

	case 's':
		data->silent = true;
		return false;
	}
}

void
agb_checkParams (struct agb_Data* const restrict data, int const argc, char const* const* const argv) {
	if (argc < 0x2) {
		agb_help ();
		agb_exit (agb_Cnd_Ok, NULL);
	}

	size_t const numParams = argc; // Prettier.

	for (ptrdiff_t index = 0x1; index < (ptrdiff_t)numParams; ++index) {
		// Iterate over the parameters. One hyphen denotes character parameters (-h) whilst two denote long paramters (--help).

		char const* const param = argv[index];
		if (param[0x0] == '-') {
			if (param[0x1] == '-') {
				char const* const longParam = &param[0x2];

				// Check long parameters.

				if (longParam[0x0] == '\x0') {
					fputs ("Missing long parameter after '--' sequence\n", stderr);
					agb_exit (agb_Cnd_Error, NULL);
				}

				if (!strcmp (longParam, "help")) {
					agb_help ();
					agb_exit (agb_Cnd_Ok, NULL);
				}

				if (!strcmp (longParam, "version")) {
					agb_copyright();
					agb_exit (agb_Cnd_Ok, NULL);
				}

				fprintf (stderr, "Invalid long parameter \"%s\"\n", longParam);
				agb_exit (agb_Cnd_Error, NULL);
			}

			if (param[0x1] == '\x0') {
				fputs ("Missing character parameter after '-'\n", stderr);
				agb_exit (agb_Cnd_Error, NULL);
			}

			// Check character parameters.

			for (char const* charIndex = &param[0x1];; ++charIndex) { if (agb_checkCharParam (data, charIndex)) { break; } }

			continue;
		}

		// We did not find the 'i' parameter, so we don't know where the ROM is.

		if (data->path == NULL) {
			fputs ("ROM not set (missing character parameter 'i')\n", stderr);
			agb_exit (agb_Cnd_Error, NULL);
		}
	}
}