#!/usr/bin/perl -w

eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
    if 0; # not running under some shell
###############################################################################
# Sanity check plugin for the Krazy project.                                  #
# Copyright (C) 2008 by Allen Winter <winter@kde.org>                         #
#                                                                             #
# 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 2 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, write to the Free Software Foundation, Inc.,     #
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.               #
#                                                                             #
###############################################################################

# Tests KDE source for typedefs that should be replace by Qt typedefs.

# Program options:
#   --help:          print one-line help message and exit
#   --version:       print one-line version information and exit
#   --priority:      report issues of the specified priority only
#   --strict:        report issues with the specified strictness level only
#   --explain:       print an explanation with solving instructions
#   --installed      file is to be installed
#   --quiet:         suppress all output messages
#   --verbose:       print the offending content

# Exits with status=0 if test condition is not present in the source;
# else exits with the number of failures encountered.

use strict;
use FindBin qw($Bin);
use lib "$Bin/../../../../lib";
use Krazy::PreProcess;
use Krazy::Utils;

my($Prog) = "typedefs";
my($Version) = "1.0";

&parseArgs();

&Help() if &helpArg();
&Version() if &versionArg();
&Explain() if &explainArg();
if ($#ARGV != 0){ &Help(); Exit 0; }

my($f) = $ARGV[0];

# open file and slurp it in (C++ only)
if (&fileType($f) eq "c++" && $f !~ /\.c$/) {
  open(F, "$f") || die "Couldn't open $f";
} else {
  print "okay\n" if (!&quietArg());
  Exit 0;
}
my(@data_lines) = <F>;
close(F);

# Remove C-style comments and #if 0 blocks from the file input
my(@lines) = RemoveIfZeroBlockC( RemoveCommentsC( @data_lines ) );

my($cnt) = 0;
my($linecnt) = 0;
my($lstr) = "";

my($line);
while ($linecnt < $#lines) {
  $line = $lines[$linecnt++];
  if ($line =~ m+//.*[Kk]razy:excludeall=.*$Prog+ ||
      $line =~ m+//.*[Kk]razy:skip+) {
    $cnt = 0;
    last;
  }
  next if ($line =~ m+//.*[Kk]razy:exclude=.*$Prog+);
  $line =~ s+//.*++;  #skip C++ comments

  &doIt($line,  'int8_t','qint8');
  &doIt($line,'u_int8_t','quint8');

  &doIt($line,  'int16_t','qint16');
  &doIt($line,'u_int16_t','quint16');

  &doIt($line,  'int32_t','qint32');
  &doIt($line,'u_int32_t','quint32');

  &doIt($line,  'int64_t','qint64');
  &doIt($line,'u_int64_t','quint64');

  &doIt($line,'u_char', 'uchar');
  &doIt($line,'u_short','ushort');
  &doIt($line,'u_int',  'uint');
  &doIt($line,'u_long', 'ulong');

#other Qt typedefs in qglobal.h:
#qlonglong, qulonglong
#qptrdiff, quintptr
#qreal
}

if (!$cnt) {
  print "okay\n" if (!&quietArg());
  Exit 0;
} else {
  $lstr =~ s/,$//;
  print "$lstr ($cnt)\n" if (!&quietArg());
  Exit $cnt;
}

sub doIt() {
  my($line,$tdef,$qtype) = @_;
  if (&bTypedef($line,$tdef)) {
    $cnt++;
    if ($cnt == 1) {
      $lstr = "line\#" . $linecnt;
    } else {
      $lstr = $lstr . ",\#" . $linecnt;
    }
    $lstr .= " $tdef" . "[$qtype]";
    print "=> $line\n" if (&verboseArg());
  }
}

sub bTypedef() {
  my($l,$tdef) = @_;
  if ($l =~ m/[\s\(;,<]$tdef[\s\*\&>]/) {
    return 1;
  } else {
    return 0;
  }
}

sub Help {
  print "Check for typedefs that should be replaced by Qt typedefs\n";
  Exit 0 if &helpArg();
}

sub Version {
  print "$Prog, version $Version\n";
  Exit 0 if &versionArg();
}

sub Explain {
  print "Please use Qt typedefs (like qint32 and qreal) as defined in QGlobals. These typedefs are guaranteed to have the size in bits that the name states on all platforms. \n";
  Exit 0 if &explainArg();
}
