diff options
Diffstat (limited to 'devtools')
-rw-r--r-- | devtools/.gitignore | 2 | ||||
-rw-r--r-- | devtools/clean-c.c | 92 | ||||
-rw-r--r-- | devtools/list-c-types.c | 160 |
3 files changed, 254 insertions, 0 deletions
diff --git a/devtools/.gitignore b/devtools/.gitignore new file mode 100644 index 0000000..e2d9408 --- /dev/null +++ b/devtools/.gitignore @@ -0,0 +1,2 @@ +/clean-c +/list-c-types diff --git a/devtools/clean-c.c b/devtools/clean-c.c new file mode 100644 index 0000000..2f56087 --- /dev/null +++ b/devtools/clean-c.c @@ -0,0 +1,92 @@ +/* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + +static char quote = 0; +static char comment = 0; + +static size_t +clean(char *text, size_t len) +{ + char *w = text; + size_t off; + + for (off = 0; off < len; off++) { + if (comment == '/') { + if (text[off] == '\n') + comment = 0; + } else if (comment == '*') { + if (text[off] == '*' && off + 1 < len && text[off + 1] == '/') { + comment = 0; + off += 1; + } + } else { + *w++ = text[off]; + switch (text[off]) { + case '\"': + case '\'': + quote = quote == text[off] ? 0 : text[off]; + break; + + case '\\': + if (off + 1 < len) { + off++; + w -= !!quote; + *w++ = text[off] == '\n' ? ' ' : text[off]; + } + break; + + case '/': + if (off + 1 < len) { + if (text[off + 1] == '*' || text[off + 1] == '/') { + comment = text[off++ + 1]; + w[-1] = ' '; + } + } + break; + + default: + break; + } + } + } + + return (size_t)(w - text); +} + +int +main(int argc, char *argv[]) +{ + char buf[8 << 10]; + size_t size, off; + ssize_t r; + + (void) argc; + + for (;;) { + r = read(STDIN_FILENO, buf, sizeof(buf)); + if (r <= 0) { + if (!r) + break; + if (errno == EINTR) + continue; + perror(argv[0]); + return 1; + } + size = clean(buf, (size_t)r); + for (off = 0; off < size; off += (size_t)r) { + r = write(STDOUT_FILENO, &buf[off], size - off); + if (r <= 0) { + if (errno == EINTR) + continue; + perror(argv[0]); + return 1; + } + } + } + + return 0; +} diff --git a/devtools/list-c-types.c b/devtools/list-c-types.c new file mode 100644 index 0000000..ec37a53 --- /dev/null +++ b/devtools/list-c-types.c @@ -0,0 +1,160 @@ +/* See LICENSE file for copyright and license details. */ +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + +static char quote = 0; +static int in_name = 0; +static size_t typedef_keyword = 0; +static size_t struct_keyword = 0; +static size_t union_keyword = 0; +static size_t enum_keyword = 0; +static int printing = 0; +static size_t levels = 0; +static size_t brackets = 0; + +static size_t +extract(char *text, size_t len, int *outputln) +{ + const char *keyword; + char *w = text, c; + size_t off; + + *outputln = 0; + + for (off = 0; off < len; off++) { + if (!text[off]) + text[off] = ' '; + + if (printing) { + *w++ = text[off]; + levels += text[off] == '{'; + levels -= text[off] == '}'; + if (!levels && text[off] == ';') { + if ((size_t)(w - text) == len) + *outputln = 1; + else + *w++ = '\n'; + printing = 0; + } + continue; + } + + switch (text[off]) { + case '\"': + case '\'': + in_name = 0; + quote = quote == text[off] ? 0 : text[off]; + break; + + case '\\': + off++; + break; + + default: + if (quote) + break; + + brackets += text[off] == '(' || text[off] == '[' || text[off] == '{'; + brackets -= text[off] == ')' || text[off] == ']' || text[off] == '}'; + if (brackets) + break; + + if (!"typedef"[typedef_keyword]) { + keyword = "typedef"; + goto found_keyword; + } else if (!"struct"[struct_keyword]) { + keyword = "struct"; + goto found_keyword; + } else if (!"union"[union_keyword]) { + keyword = "union"; + goto found_keyword; + } else if (!"enum"[enum_keyword]) { + keyword = "enum"; + goto found_keyword; + } else if (!in_name) { + if (text[off] != "typedef"[typedef_keyword++]) + typedef_keyword = 0; + if (text[off] != "struct"[struct_keyword++]) + struct_keyword = 0; + if (text[off] != "union"[union_keyword++]) + union_keyword = 0; + if (text[off] != "enum"[enum_keyword++]) + enum_keyword = 0; + if (typedef_keyword || struct_keyword || union_keyword || enum_keyword) + break; + } + + if (isalnum(text[off]) || text[off] == '_') + in_name = 1; + else + goto not_alnum; + + break; + found_keyword: + if (isalnum(text[off]) || text[off] == '_') { + in_name = 1; + goto reset_keyword; + } + c = text[off]; + w = stpcpy(w, keyword); + *w++ = c; + printing = 1; + not_alnum: + in_name = 0; + reset_keyword: + typedef_keyword = 0; + struct_keyword = 0; + union_keyword = 0; + enum_keyword = 0; + break; + } + } + + return (size_t)(w - text); +} + +int +main(int argc, char *argv[]) +{ + char buf[8 << 10]; + size_t size, off; + ssize_t r; + int outputln = 0; + + (void) argc; + + for (;;) { + r = read(STDIN_FILENO, buf, sizeof(buf)); + if (r <= 0) { + if (!r) + break; + if (errno == EINTR) + continue; + perror(argv[0]); + return 1; + } + size = extract(buf, (size_t)r, &outputln); + write_again: + for (off = 0; off < size; off += (size_t)r) { + r = write(STDOUT_FILENO, &buf[off], size - off); + if (r <= 0) { + if (errno == EINTR) + continue; + perror(argv[0]); + return 1; + } + } + if (outputln) { + outputln = 0; + buf[0] = '\n'; + size = 1; + goto write_again; + } + } + + return 0; +} |