#! /usr/bin/perl -w
#
# Copyright (C) 2015 Richard Kettlewell
#
# 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
use strict;

our $errors = 0;

sub error {
    print STDERR "$ARGV:$.: ", @_, "\n";
    ++$errors;
}

my $comment = 0;
while(<>) {
    # Whitespace discipline
    error("trailing whitespace") if / $/;
    error("tab character") if /\t/;
    # Strip C comments
    #print STDERR "$comment    $_";
    if($comment) {
        if(/\*\//) {
            $comment = 0;
            s/^.*?\*\///;
            #print STDERR "endc $_";
        } else {
            $_ = "\n";
            #print STDERR "allc $_";
        }
    } else {
        s/\/\*.*?\*\///g;
        #print STDERR "strp $_";
        if(/\/\*/) {
            s/\/\*.*$//;
            $comment = 1;
            #print STDERR "trim $_";
        }
    }
    # Strip C++ comments (but not // inside strings)
    s/^(([^"]|\"([^\\\"]|\\.)*\")*?)\/\/.*/$1/;
    # if(cond) not if (cond)
    error("keyword '$1' followed by whitespace")
        if /\b(for|if|while|switch|sizeof|typeof)\s+\(/;
    # continuation operators at start of line, not end
    error("trailing operator")
        if /(&&|\|\||\+|\*|\/|-)\s*$/;
    error("NULL macro (use nullptr)")
        if /[^A-Z]NULL/;
    error("0 as null pointer (use nullptr)")
        if /\*\)0/;
} continue {
    if(eof) {
        close ARGV;
        $comment = 0;
    }
}

exit !!$errors;
