/* See LICENSE file for copyright and license details. */ #include #include #include #include #include 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; }