diff mbox series

[6/8] pdbg: Define common command/flag argument parsers

Message ID 20180620053409.14538-7-alistair@popple.id.au
State Accepted
Headers show
Series Rework option parsing | expand

Commit Message

Alistair Popple June 20, 2018, 5:34 a.m. UTC
Parsers need to take a string argument and convert it into a specific type,
returning the value as a pointer to memory allocated by the parser (or NULL in
the case of an error). This just defines a couple of common parsers useful for
various commands.

It also defines a couple of convenience macros for easier usage of these
parsers.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
 src/parsers.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/parsers.h | 21 +++++++++++++++
 2 files changed, 106 insertions(+)
 create mode 100644 src/parsers.c
 create mode 100644 src/parsers.h

Comments

Rashmica Gupta June 22, 2018, 3:30 a.m. UTC | #1
On 20/06/18 15:34, Alistair Popple wrote:
> Parsers need to take a string argument and convert it into a specific type,
> returning the value as a pointer to memory allocated by the parser (or NULL in
> the case of an error). This just defines a couple of common parsers useful for
> various commands.
>
> It also defines a couple of convenience macros for easier usage of these
> parsers.
>
> Signed-off-by: Alistair Popple <alistair@popple.id.au>
> ---
>  src/parsers.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/parsers.h | 21 +++++++++++++++
>  2 files changed, 106 insertions(+)
>  create mode 100644 src/parsers.c
>  create mode 100644 src/parsers.h
>
> diff --git a/src/parsers.c b/src/parsers.c
> new file mode 100644
> index 0000000..0399933
> --- /dev/null
> +++ b/src/parsers.c
> @@ -0,0 +1,85 @@
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <errno.h>
> +
> +uint64_t *parse_number64(const char *argv)
> +{
> +	uint64_t *n = malloc(sizeof(*n));
> +	char *endptr;
> +
> +	if (!argv)
> +		return NULL;
> +
> +	errno = 0;
> +	*n = strtoull(argv, &endptr, 0);
> +	if (errno || *endptr != '\0')
> +		return NULL;
> +
> +	return n;
> +}
> +
> +uint32_t *parse_number32(const char *argv)
> +{
> +	unsigned long long tmp;
> +	uint32_t *n = malloc(sizeof(*n));
> +	char *endptr;
> +
> +	if (!argv)
> +		return NULL;
> +
> +	errno = 0;
> +	tmp = strtoul(argv, &endptr, 0);
> +	if (errno || *endptr != '\0' || tmp > (uint32_t) -1UL)

What about using UINT32_MAX instead of '(uint32_t)  -1UL'?

> +		return NULL;
> +
> +	*n = tmp;
> +	return n;
> +}
> +
> +/* Parse a GPR number, returning an error if it's greater than 32 */
> +int *parse_gpr(const char *argv)
> +{
> +	int *gpr = malloc(sizeof(*gpr));
> +	char *endptr;
> +
> +	if (!argv)
> +		return NULL;
> +
> +	errno = 0;
> +	*gpr = strtoul(argv, &endptr, 0);
> +	if (errno || *endptr != '\0' || *gpr > 32)
> +		return NULL;
> +
> +	return gpr;
> +}
> +
> +/* Parse an SPR. Currently only supports SPR by numbers but could be extended to
> + * support names (eg. lr) */
> +int *parse_spr(const char *argv)
> +{
> +	int *spr = malloc(sizeof(*spr));
> +	char *endptr;
> +
> +	if (!argv)
> +		return NULL;
> +
> +	errno = 0;
> +	*spr = strtoul(argv, &endptr, 0);
> +	if (errno || *endptr != '\0' || *spr > 0x3ff)
> +		return NULL;
> +
> +	return spr;
> +}
> +
> +
> +/* A special parser that always returns true. Allows for boolean flags which
> + * don't take arguments. Sets the associated field to true if specified,
> + * otherwise sets it to the default value (usually false). */
> +bool *parse_flag_noarg(const char *argv)
> +{
> +	bool *result = malloc(sizeof(*result));
> +
> +	*result = true;
> +	return result;
> +}
> diff --git a/src/parsers.h b/src/parsers.h
> new file mode 100644
> index 0000000..b5f23cf
> --- /dev/null
> +++ b/src/parsers.h
> @@ -0,0 +1,21 @@
> +#ifndef __PARSERS_H
> +#define __PARSERS_H
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +#define ADDRESS (parse_number64, NULL)
> +#define ADDRESS32 (parse_number32, NULL)
> +#define DATA (parse_number64, NULL)
> +#define DATA32 (parse_number32, NULL)
> +#define DEFAULT_DATA(default) (parse_number64, default)
> +#define GPR (parse_gpr, NULL)
> +#define SPR (parse_spr, NULL)
> +
> +uint64_t *parse_number64(const char *argv);
> +uint32_t *parse_number32(const char *argv);
> +int *parse_gpr(const char *argv);
> +int *parse_spr(const char *argv);
> +bool *parse_flag_noarg(const char *argv);
> +
> +#endif
Alistair Popple June 25, 2018, 6:04 a.m. UTC | #2
> > +	errno = 0;
> > +	tmp = strtoul(argv, &endptr, 0);
> > +	if (errno || *endptr != '\0' || tmp > (uint32_t) -1UL)
> 
> What about using UINT32_MAX instead of '(uint32_t)  -1UL'?

Good idea! Thanks.

- Alistair
diff mbox series

Patch

diff --git a/src/parsers.c b/src/parsers.c
new file mode 100644
index 0000000..0399933
--- /dev/null
+++ b/src/parsers.c
@@ -0,0 +1,85 @@ 
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+
+uint64_t *parse_number64(const char *argv)
+{
+	uint64_t *n = malloc(sizeof(*n));
+	char *endptr;
+
+	if (!argv)
+		return NULL;
+
+	errno = 0;
+	*n = strtoull(argv, &endptr, 0);
+	if (errno || *endptr != '\0')
+		return NULL;
+
+	return n;
+}
+
+uint32_t *parse_number32(const char *argv)
+{
+	unsigned long long tmp;
+	uint32_t *n = malloc(sizeof(*n));
+	char *endptr;
+
+	if (!argv)
+		return NULL;
+
+	errno = 0;
+	tmp = strtoul(argv, &endptr, 0);
+	if (errno || *endptr != '\0' || tmp > (uint32_t) -1UL)
+		return NULL;
+
+	*n = tmp;
+	return n;
+}
+
+/* Parse a GPR number, returning an error if it's greater than 32 */
+int *parse_gpr(const char *argv)
+{
+	int *gpr = malloc(sizeof(*gpr));
+	char *endptr;
+
+	if (!argv)
+		return NULL;
+
+	errno = 0;
+	*gpr = strtoul(argv, &endptr, 0);
+	if (errno || *endptr != '\0' || *gpr > 32)
+		return NULL;
+
+	return gpr;
+}
+
+/* Parse an SPR. Currently only supports SPR by numbers but could be extended to
+ * support names (eg. lr) */
+int *parse_spr(const char *argv)
+{
+	int *spr = malloc(sizeof(*spr));
+	char *endptr;
+
+	if (!argv)
+		return NULL;
+
+	errno = 0;
+	*spr = strtoul(argv, &endptr, 0);
+	if (errno || *endptr != '\0' || *spr > 0x3ff)
+		return NULL;
+
+	return spr;
+}
+
+
+/* A special parser that always returns true. Allows for boolean flags which
+ * don't take arguments. Sets the associated field to true if specified,
+ * otherwise sets it to the default value (usually false). */
+bool *parse_flag_noarg(const char *argv)
+{
+	bool *result = malloc(sizeof(*result));
+
+	*result = true;
+	return result;
+}
diff --git a/src/parsers.h b/src/parsers.h
new file mode 100644
index 0000000..b5f23cf
--- /dev/null
+++ b/src/parsers.h
@@ -0,0 +1,21 @@ 
+#ifndef __PARSERS_H
+#define __PARSERS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define ADDRESS (parse_number64, NULL)
+#define ADDRESS32 (parse_number32, NULL)
+#define DATA (parse_number64, NULL)
+#define DATA32 (parse_number32, NULL)
+#define DEFAULT_DATA(default) (parse_number64, default)
+#define GPR (parse_gpr, NULL)
+#define SPR (parse_spr, NULL)
+
+uint64_t *parse_number64(const char *argv);
+uint32_t *parse_number32(const char *argv);
+int *parse_gpr(const char *argv);
+int *parse_spr(const char *argv);
+bool *parse_flag_noarg(const char *argv);
+
+#endif