/*
* Helper application to test normalization of declaration specifiers.
- * Copyright © 2021-2023 Nick Bowler
+ * Copyright © 2021-2024 Nick Bowler
*
* 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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <getopt.h>
#include "cdecl.h"
#include "cdecl-internal.h"
-#include "test.h"
#define PROGNAME "normalize"
-static const char *progname = PROGNAME;
+#include "test.h"
+
static const char sopts[] = "f:VH";
static const struct option lopts[] = {
{ "file", 1, NULL, 'f' },
return CDECL_TYPE_IDENT;
}
+static const char *to_specstring(unsigned type)
+{
+ switch (type) {
+ case CDECL_STOR_TYPEDEF: return "typedef";
+ case CDECL_STOR_EXTERN: return "extern";
+ case CDECL_STOR_STATIC: return "static";
+ case CDECL_STOR_AUTO: return "auto";
+ case CDECL_STOR_REGISTER: return "register";
+ case CDECL_FUNC_INLINE: return "inline";
+ case CDECL_QUAL_RESTRICT: return "restrict";
+ case CDECL_QUAL_VOLATILE: return "volatile";
+ case CDECL_QUAL_CONST: return "const";
+ case CDECL_TYPE_VOID: return "void";
+ case CDECL_TYPE_SIGNED: return "signed";
+ case CDECL_TYPE_UNSIGNED: return "unsigned";
+ case CDECL_TYPE_CHAR: return "char";
+ case CDECL_TYPE_SHORT: return "short";
+ case CDECL_TYPE_LONG: return "long";
+ case CDECL_TYPE_INT: return "int";
+ case CDECL_TYPE_FLOAT: return "float";
+ case CDECL_TYPE_DOUBLE: return "double";
+ case CDECL_TYPE_COMPLEX: return "_Complex";
+ case CDECL_TYPE_IMAGINARY: return "_Imaginary";
+ case CDECL_TYPE_BOOL: return "_Bool";
+ case CDECL_TYPE_STRUCT: return "struct";
+ case CDECL_TYPE_UNION: return "union";
+ case CDECL_TYPE_ENUM: return "enum";
+ }
+
+ return "";
+}
+
+static void print_spec(struct cdecl_declspec *spec)
+{
+ const char *s = to_specstring(spec->type);
+
+ printf("%s", s);
+ if (spec->ident) {
+ if (s[0])
+ putchar(' ');
+ printf("%s", spec->ident);
+ }
+}
+
int do_normalize(char *line, size_t n)
{
- struct cdecl_declspec *specs = NULL, **newspec = &specs;
+ struct cdecl_declspec *s, *specs = NULL, **newspec = &specs;
char *tok = NULL;
while ((tok = strtok(tok ? NULL : line, " "))) {
newspec = &spec->next;
}
- line = malloc_nofail(n);
- line[0] = 0;
- if (specs) {
- struct output_state dst = { line, n };
-
- specs = cdecl__normalize_specs(specs);
- cdecl__emit_specs(&dst, specs, -1);
+ specs = cdecl__normalize_specs(specs);
+ for (s = specs; s; s = s->next) {
+ print_spec(s);
+ if (s->next)
+ putchar(' ');
}
- printf("%s\n", line);
- free(line);
+ putchar('\n');
while (specs) {
struct cdecl_declspec *c = specs;
}
}
- if (filename) {
- infile = fopen(filename, "r");
- if (!infile) {
- perror(filename);
- return EXIT_FAILURE;
- }
+ if (filename && !freopen(filename, "r", stdin)) {
+ print_error("%s: %s", filename, strerror(errno));
+ return EXIT_FAILURE;
}
- while ((rc = getline(&line, &n, infile)) >= 0) {
- if (rc > 0 && line[rc-1] == '\n')
- line[rc-1] = 0;
+ while (test_getline(&line, &n)) {
if (do_normalize(line, n) < 0)
ret = EXIT_FAILURE;
}