Created
July 22, 2014 01:27
-
-
Save CoolOppo/93671a9c373f8686e3c5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* nobraces.ci: Python-style indentation for C | |
By Ben Hoyt, 22 Sep 2007, http://benhoyt.com/ | |
Basically you just write C code, indenting it like you would anyway, | |
but use colons after control flow statements like in Python. Oh, and | |
leave off all those nasty end-of-line semicolons. | |
Okay, so it's a joke. Mostly. :-) Inspired by the Python parallel, | |
Tim Hatch's "pybraces" (C-style braces in Python): | |
http://timhatch.com/projects/pybraces/ | |
This filter ain't very clever. It doesn't handle continuation lines | |
or comments after code on a line. In short, I didn't feel like writing | |
a C parser. If someone fleshed it out, this might even be useful ... | |
To use it, type something like: | |
nobraces < nobraces.ci > nobraces.c | |
cc nobraces.c | |
OH WAIT! It's written in itself, so you won't be able to compile it | |
without a compiled version of nobraces ... hey, what on earth! :-) | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <ctype.h> | |
#define MAX_LINE 1000 | |
#define MAX_LEVELS 20 | |
#define TAB_SIZE 4 | |
/* indentation levels stack, see: | |
http://docs.python.org/ref/indentation.html */ | |
int levels[MAX_LEVELS+1] = {0} | |
int level_idx = 0 | |
/* return top item on levels stack (don't pop) */ | |
int levels_top(void): | |
return levels[level_idx] | |
/* push item onto levels stack */ | |
void levels_push(int level): | |
if (level_idx >= MAX_LEVELS): | |
printf("More than %d indent levels!\n", MAX_LEVELS) | |
exit(1) | |
levels[++level_idx] = level | |
/* pop and return top item from levels stack */ | |
int levels_pop(void): | |
return levels[level_idx--] | |
/* print n spaces */ | |
void spaces(int n): | |
while (n--): | |
putchar(' ') | |
/* dedent to less-indented level, generating '}' chars as we go */ | |
void dedents(int to_level): | |
while (levels_top() > to_level): | |
levels_pop() | |
spaces(levels_top()) | |
printf("}\n") | |
/* expand tabs to spaces and copy back into line (must be MAX_LINE big) */ | |
char *expand_tabs(char *line): | |
char *tabbed, *expanded, temp_line[MAX_LINE] | |
int column | |
column = 0 | |
expanded = temp_line | |
for (tabbed=line; *tabbed; tabbed++): | |
if (*tabbed == '\t'): | |
*expanded++ = ' ' | |
while (++column%TAB_SIZE != 0): | |
*expanded++ = ' ' | |
else: | |
*expanded++ = *tabbed | |
column++ | |
*expanded = 0 | |
strcpy(line, temp_line) | |
return line | |
/* strip whitespace chars from end of string */ | |
char *rstrip(char *line): | |
char *end | |
end = line + strlen(line) - 1 | |
while (end >= line && isspace(*end)): | |
*end-- = 0 | |
return line | |
/* get line's indent level (number of chars till first non-space char) */ | |
int get_indent(char *line): | |
int i | |
for (i=0; isspace(*line); i++): | |
line++ | |
return i | |
/* nobraces, here we come */ | |
int main(void): | |
char line[MAX_LINE] | |
int indent, len, in_comment | |
/* read and process lines till EOF */ | |
in_comment = 0 | |
while (fgets(line, MAX_LINE, stdin)): | |
/* massage line, get indent level and length */ | |
rstrip(line) | |
expand_tabs(line) | |
indent = get_indent(line) | |
len = strlen(line) | |
/* ignore blank lines */ | |
if (line[indent] == 0): | |
continue | |
/* leave preprocessor directives alone */ | |
if (line[indent] == '#'): | |
puts(line) | |
continue | |
/* ignore single- and multi-line comments */ | |
if (line[indent] == '/' && line[indent+1] == '/'): | |
continue | |
if (line[indent] == '/' && line[indent+1] == '*'): | |
in_comment = 1 | |
if (in_comment): | |
if (strstr(line, "*/")): | |
in_comment = 0 | |
continue | |
/* from http://docs.python.org/ref/indentation.html */ | |
if (indent > levels_top()): | |
spaces(levels_top()) | |
printf("{\n") | |
levels_push(indent) | |
else if (indent < levels_top()): | |
dedents(indent) | |
/* drop ':' from control structures, add ';' to statements */ | |
if (line[len-1] == ':'): | |
line[len-1] = 0 | |
puts(line) | |
else: | |
fputs(line, stdout) | |
printf(";\n") | |
/* output any last end braces */ | |
dedents(0) | |
return 0 |
bogen
commented
Jun 14, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment