Skip to content

Instantly share code, notes, and snippets.

@silverweed
Created April 20, 2015 14:14
Show Gist options
  • Save silverweed/84dd2d54884c3c113cd9 to your computer and use it in GitHub Desktop.
Save silverweed/84dd2d54884c3c113cd9 to your computer and use it in GitHub Desktop.
C minifier
#!/usr/bin/gawk -f
# C / C++ code minifier by silverweed
# Strips all superfluous blank spaces still producing compilable code.
# Somewhat tested.
BEGIN {
for (i = 1; i < length(ARGV); ++i) {
if (match(ARGV[i],/^-([0-9]+)$/,mch)) {
maxlines = mch[1]
}
}
is_newline = 1
}
function panic(str) {
print "[ERROR] "str > "/dev/stderr"
exit 1
}
function process(field, nxt) {
is_newline = 0
if (in_string) {
printf "%s ", field
return
}
if (!nxt || nxt ~ /^[+\-*\/^><=,%&"'{}\|\[\]();:\.!]/) {
if (!nxt && field == "else")
printf "%s ", field
else
printf "%s", field
return
}
if (field ~ /^.*[;:,)}\]=*]$/) {
printf "%s", field
} else if (field ~ /^[0-9]+$/) {
printf "%s ", field
} else if (field ~ /^[a-zA-Z_]+$/) {
printf "%s ", field
} else if (field ~ /^[a-zA-Z_]+\(.*\)$/) {
printf "%s", field
} else if (field ~ /^[+\-*\/^><=\|%&"':;\.]+$/) {
printf "%s", field
} else if (field ~ /^[{}()\[\]]+$/) {
printf "%s", field
} else {
printf "%s ", field
}
}
{
if (maxlines && NR > maxlines)
exit 0
}
# strip comments
/^\/\// {
if (!in_string) {
printf ""
is_newline = 1
next
} else next
}
# manage preproc directives
/^[[:space:]]*#.+/ {
if (!in_string) {
if (match($0,/^\s*#\s*(\S+)\s*(.*)\s*$/,mch)) {
if (mch[1] ~ /^include/)
line = "#"mch[1]""mch[2]
else {
line = "#"mch[1]
if (mch[2])
line = line" "mch[2]
}
} else {
panic("Strange line: "$0)
}
if (is_newline)
print line
else
print "\n"line
is_newline = 1
next
} else next
}
{
for (i = 1; i <= NF; ++i) {
# handle start-string and end-string
if ($i ~ /^[^"]*"[^"]*$/) {
if (in_string) {
in_string = 0
} else {
in_string = 1
}
process($i, $(i+1))
continue
}
# handle mid-line comments
if ($i ~ /\/\//) {
next
}
# handle c-style comments
if ($i ~ /\/\*/) {
if (in_comment)
panic("Nested comment found!");
else {
in_comment = 1
continue
}
# handle c-style end-comments
} else if ($i ~ /\*\//) {
if (in_comment) {
in_comment = 0
continue
} else
panic("Found end comment outside a comment!")
# other cases
} else {
if (in_comment)
continue
else
process($i, $(i+1))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment