#!/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 Volker Krause <vkrause@kde.org>                       #
# Copyright (C) 2008-2010 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 invalid icon names

# 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) = "iconnames";
my($Version) = "1.6";

&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++, non-headers only)
my($filetype) = fileType($f);
if ($filetype eq "c++" || $filetype eq "desktop" || $filetype eq "qml") {
  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 ) );

# Check Condition
my($cnt) = 0;
my($linecnt) = 0;
my($lstr) = "";

# this list is autogenerated based on the data in kdesdk/scripts/qt4/icons-kde3tokde4-renamer
# and most likely incomplete
my %icon_map = map {($_) => 1} qw {
001_star_butterfly
002_text_document
005_spreadsheet_document
006_drawing_document
008_presentation_document
009_presentation_document
010_presentation_compressed
012_html_document
015_math_document
016_template
14_ellipse
14_flatten
14_gradient
14_group
14_image
14_insertknots
14_layer_deletelayer
14_layer_lowerlayer
14_layer_newlayer
14_layer_novisible
14_layer_raiselayer
14_layer_visible
14_pattern
14_pencil
14_polygon
14_polyline
14_rectangle
14_rotate
14_roundcorners
14_roundrect
14_select
14_selectnodes
14_shear
14_sinus
14_spiral
14_star
14_text
14_transform
14_ungroup
14_whirl
14_zoom
1downarrow
1leftarrow
1rightarrow
1uparrow
2downarrow
2leftarrow
2rightarrow
2uparrow
3downarrow
3floppy_mount
3floppy-mount
3floppy_unmount
3leftarrow
3rightarrow
3uparrow
500_setup
501_printeradmin
5floppy_mount
5floppy-mount
5floppy_unmount
5floppy-unmount
abentry
about_kde
about-kde
access
account
account_open
add
add_group
add_sub_task
add_user
adept_commit
adept_distupgrade
adept_install
adept_notifier_warning
adept_purge
adept_remove
adept_sourceseditor
adept_update
akregator_empty
aktion
albumfoldercomment
albumfoldernew
alevt
align_left
alignobjs
align_right
aobottom
aogrid
aoleft
aopos2grid
aoright
aotop
applixware
apply
appointment
apport
ark_adddir
ark-adddir
ark_addfile
ark-addfile
ark_delete
ark-delete
ark_extract
ark-extract
ark_view
ark-view
arts
artsaudiomanager
artsbuilder
artsbuilderexecute
artscontrol
artsenvironment
artsfftscope
artsmediatypes
artsmidimanager
atlantik_buy_estate
atlantikdesigner
attach
back
binary
blender3d
blender3dblockdevice
blockdevice
bookmark
bookmark_add
bookmark_folder
bookmark-folder
bookmarks_list_add
bookmark_toolbar
bottom
bring_forward
bring_stencil_to_front
bt
button
button_apply
button_cancel
bzflag
cam
camera
camera_mount
camera-mount
camera_test
camera_unmount
camera-unmount
cancel
cdaudio_mount
cdaudio-mount
cdaudio_unmount
cdaudio-unmount
cdimage
CD-Rom
cdrom_audio
cdrom_mount
cdrom-mount
cdrom_unmount
cdrom-unmount
cdsmall
cdtje
cdtrack
cdwriter_mount
cdwriter-mount
cdwriter_unmount
cdwriter-unmount
centrejust
certificate
char
chardevice
charselect
charset
check
civworld
clear_left
close
colorize
colorpicker
colorscm
combo
compact_flash_mount
compact_flash_unmount
compfile
configure_shortcuts
configure_toolbars
connect_established
connect_no
connect_to_network
contact
contents2
contexthelp
copy
copy_stencil
core
cpufreq_applet
cssvalidator
cursor
cut
cut_stencil
daemon
daemons
database
dateeditkonqsidebar_mediaplayer
dcgui-qt
deb
decrypted
default-applications-capplet
delete
delete_group
deletelayer
delete_table_row
delete_user
desktop
dia_gnome_icon
digikamcameraclient
digikamimageplugins
digitalcam
display
div_center
djvu
dlgedit
document
down
drawing
dsl
dvd_mount
dvd-mount
dvd_unmount
dvd-unmount
dvi
edit
edit_add
editclear
editcopy
editcut
editdelete
editpaste
edit_remove
edittrash
edit_user
emoticon
empty
emptytrash
encrypted
energy
enum_list
enumList
eog
equalizer
exclamation
exec
exec_wine
exifinfo
exit
FaxRecieving
file-broken
fileclose
fileexport
filefind
file-find
fileimport
file_important
file_locked
file-open
fileopenurl
file_temporary
finances_section
find
findf
finish
firefox
firewire_mount
firewire_unmount
folder_apollon
folder_binary
folder_bomb
folder_cd
folder_closed
folder_crystal
folder_cyan
folder_cyan_open
folder_deb
folder_favorite
folder_fonts
folder_games
folder_green
folder_green_open
folder_grey
folder_grey_open
folder-home
folder_home2
folder_html
folder_image
folder_important
folder_inbox
folder_locked
folder_mail
folder_man
folder_midi
folder_music
folder_new
folder_open
folder_orange
folder_orange_open
folder_outbox
folder_print
folder_print2
folder_red
folder_red_open
folder_rpm
folder_sent_mail
folder_sound
folder_synch
folder_tar
folder_txt
folder_video
folder_violet
folder_violet_open
folder_wine
folder_yellow
folder_yellow_open
font
font-bitmap
font-truetype
font-type1
form
form_newobj
forms
formula
forward
frame
frame_edit
ftp
galeon
gettext
gf
gfloppy
gksu
glade
globe
gnome2
gnome-about-logo
gnome_apps
gnome-error
gnome_info
gnome_question
gnome-starthere
gnome-terminal
gnome-warning
gnutelladown
gnutellaup
go
gohome
goto
goto-page
gpg
gpgsm
green_ball
groupbox
group_stencils
gtk_camera
gvdirpart
gxmessage
handheld
harddrive
hd
hdd_mount
hdd-mount
hdd_unmount
hdd-unmount
hdd_usb
hdd-usb-mount
hdd-usb-unmount
hdd_win_mount
hdd_win_unmount
help
help-about-kde
history_clear
hotmail
html
hwinfo
iconthemes
idea
identity
image
imagegallery
images_display
images-display
indent
inetd
info
inline_image
input_devices_settings
inscol
insertcell
insert_table_row
insrow
ipod_mount
ipod-mount
ipod_unmount
ipod-unmount
isdn-config
item_add
item_remove
jar
java-jar
javascript
joystick
juk_dock
juk_time
kaboodleloop
kaffeine4
kaffeine-pause
kaffeine-play
kaffeine-record
karbon-karbon
kate2
kazaadown
kazaaup
kbabeldict
kbearsitemanager
kbearsitemanagerdb
kbtobexclient
kbtserialchat
kcdlabel
kchart-chrt
kcontrol
kdbg
kde1
kde2
kde3
kde4
kde5
kde6
kdeprint_addprinter
kdeprint-addprinter
kdeprint_addpseudo
kdeprint-addpseudo
kdeprint_configmgr
kdeprint_configsrv
kdeprint_defaulthard
kdeprint_defaultsoft
kdeprint_printer
kdeprint_printer_class
kdeprint_printer_infos
kdeprint-printer-infos
kdeprint_printstate
kdeprint_queuestate
kdeprint-queuestate-kdeprint
kdeprint_report
kdeprint_restartsrv
kdeprint_stopprinter
kdeprint-stopprinter-kdeprint
kdeprint_testprinter
kdeprint-testprinter
kdeprint_uploadsmb
kdetv
kdevelop3
kdevelop_down
kdisknav
kdmconfig
kerberos-client
kernel
kexi-kexi
key_bindings
keyboard
keyboard-capplet
keyboardlayout
key_enter
kfaxview
kfind
kfocus
kformula-kfo
kget_dock
kget_dock_download
kget-list
kgpg_docked
kicker
kig-doc
kimdaba
kivio_arrow
kivio_connector
kivio-flw
kivio_text
kivio_zoom
kivio_zoom_hand
kivio_zoom_height
kivio_zoom_minus
kivio_zoom_page
kivio_zoom_plus
kivio_zoom_width
kjobviewer
klipper_doc
klpq
kmaillight
kmaway
kmdr_editor
kmultiple
knewstuff
knotes_close
knotes_delete
knotify
komparator
konserve3floppy-unmount
kontact_contacts
kontact_date
kontact_journal
kontact_mail
kontact_news
kontact_notes
kontact_summary
kontact_summary_green
kontact_todo
konv_message
kopete2
kopete-emoticons
korgac_disabled
korganizer_todo
koshell
kpilotDaemon
kpovmodeler-doc
kpresenter-kpr
kprintfax
krec_record
krita-kra
kroete
kservices
ksim_cpu
kspread-ksp
ktnef_extract_all_to
ktnef_extract_to
ktplugins
ktqueuemanager
ktremove
ktstart
ktstart_all
ktstop
ktstop_all
kugardata
kugar-kud
kverbosuser
kviewshell
kwavecontrol
kword-kwd
kwordquiz-doc
kwrite2
kxconfig
kxkb
kxsldbg
label
LabPlot
laptop
laptoppower
layer_print
lbreakout
ldap_lookup
ledger
leftjust
lessen
line
lineedit
linewidth
link_overlay
linuxconf
linux_hdd_mount
linux_hdd_unmount
listbox
listview
locationbar_erase
locationbar-erase
locked
lockzoom
log
logjam
looknfeel
lvm
lyx
mail
mailappt
mail_custom_forward
mail_custom_reply
mail_custom_reply_all
mail_delete
mail_find
mail_flag
mail_forward
mail_generic
mail_get
mail_ham
mail_new
mail_new3
mail_post_to3
mail_reply
mail_replyall
mail_replylist
mail_section
mail_send
mail_send_via
mail_todo
make
make_kdevelop
man
media-player-48
megami
memory_stick_mount
memory-stick-mount
memory_stick_unmount
memory-stick-unmount
message
messagebox_critical
messagebox_info
messagebox_warning
midi
misc
misc2
mldonkey
moc-src
mo_mount
monop_board
mo_unmount
mouse
mouse-capplet
mouse_pointer
mozilla_m
mozilla_mailnews
mozilla-navigator
multimedia
mute
mycomp
my_mac
napster
napsterdown
napsterup
navigator_first
navigator_last
navigator_new
navigator_next
navigator_prev
netscape-doc
network
network_disconnected
network_local
network-local
newlayer
news
news_subscribe
news_unsubscribe
newevent
newjournal
newtodo
next
nfs_mount
nfs-mount
nfs_unmount
nfs-unmount
no
noatunback
noatunfback
noatunfforward
noatunforward
noatunloopnone
noatunloopplaylist
noatunlooprandom
noatunloopsong
noatunpause
noatunplay
noatunplaylist
noatunstop
nomailappt
novisible
odf-odb
odf-odc
odf-odf
odf-odg
odf-odi
odf-odp
odf-ods
odf-odt
oilpaint
ok
okle
online_status
ooo_calc_tpl
ooo_impress_tpl
openftdown
openftup
openoffice1
openterm
opentermblue
opentermred
options
palette_halftone
palette_lineart
panel
partitioner
paste
paste_stencil
payee
pda_black
pda_blue
pdf
penguin
personal
phppg
phrase
phrasebook
phrasebook_closed
phrasebook_new
phrasebook_open
phrasebook_save
phrasehistory_open
phrasehistory_print
phrasehistory_save
phrase_new
phrase_open
phrase_save
piano
pipe
pixmaplabel
pk
plan
planner
plasmoid
player_eject
player_end
player_fwd
player_pause
player_play
player_playlist
player_playlist_2
player_record
player_rew
player_start
player_stop
player_time
player_volume
playing
playlist
podcast
postscript
powertweak
presentation
previous
print_class
printer1
printer2
printing_section
printmgr
print_printer
progress
project_open
psi
pwmanager
pybliographic
pysol
quanta_be
queries
query
query_erase
query_newobj
radio
realplay
reconcile
recur
recycled
red_ball
redo
refresh
reload3
reload_all_tabs
reload_page
relokate
remove
report
report_newobj
reports
resdiropen
reset
resfiledel
resfileedit
resfileinfo
resfileopen
restart
rightjust
rotate_ccw
rotate_cw
rotate_left
rotate_right
rotation_acw
rotation_cw
rpm
rss_tag
running
runprocesscatcher
runprog
samba_client
samba_server
samba-server
save
saveall
save_all
schedule
sd_mmc_mount
sd-mmc-mount
sd_mmc_unmount
sd-mmc-unmount
searchtool
select_item
send_backward
send_stencil_to_back
server
settings-sound
shell
shellscript
shells_section
sim
slider
slp
smallclock
smart_media_mount
smart-media-mount
smart_media_unmount
smart-media-unmount
smb4k
socket
soffice
software2
sort_decrease
sort_incr
soulseek
soulseekdown
soulseekup
sound
source
source-c
source-cpp
source-h
source-java
source-moc
source-p
source-php
source-pl
source-py
special_paste
spellcheck_actual
spin
sppausegame
spreadsheet
spring
staroffice
start
state_data
state_edit
state_sql
state_text
stop
strempty
stylesheet
submit
superkaramba-theme
suse
svn_add
svn_branch
svn_merge
svn_remove
svn_status
svn_switch
swf
synaescope
sysadmin
system
system-floppy
systemprotocol
tab_breakoff
tab_duplicate
table
table_newobj
tablet
tabwidget
tag_a
tag_bold
tag_br
tag-folder
tag_i
tag_image
tag_li
tag_mail
tag_ol
tag_sub
tag_sup
tag_u
tag_ul
tag_ulink
tdsl
tea_anim1
tea_anim2
telnet
terminal
tex
text_center
textedit
text_left
text_right
text_sub
text_super
text_under
tgz
timeedit
timezone2
timings
todo
tool_clipboard
tool_color_picker
tool_delete
tool_dock
tool_pan
tool_paste
tool_pause
tool_preferences
tool_restart
tool_resume
tool_shutdown
tool_timer
top
torrent
transaction_export
transaction_find
transaction_import
transsearch
trashcan_empty
trashcan_full
tv
tvtime
txt
umbrellofile
undo
ungroup_stencils
unindent
unlock
unlocked
unsortedList
up
usbdisk_mount
usbdisk_unmount
usb_mount
usbpendrive_mount
usbpendrive_unmount
usb_unmount
userconfig
user-info
vcalendar
vcard
vectorgfx
video
view_choose
view_fit_width
view_fit_window
view_icon
view_left_right
view_remove
view_sidetree
view_tree
visible
visor
volume
waiting
wallet_closed
wallet_open
warning
widget-doc
widgetstack
wilber
window-capplet
window_fullscreen
window_list
window_new
window_suppressed
wineconfig
winprops
wizard
wmaker_apps
wordprocessing
www
x11
xapp
xawtv
xcalc
xcdroast
xchat
xclipboard
xclock
xconsole
xedit
xemacs
xsldbg_break
xsldbg_data
xsldbg_delete
xsldbg_enable
xsldbg_output
xsldbg_refresh
xsldbg_source
xsldbg_stepdown
xsldbg_stepup
xterm-terminal
yellow_ball
yellowinfo
yesno
Ym
zip_external_mount
zip_external_unmount
zip_mount
zip_unmountdf-odb
};

my($line,$pline);
while ($linecnt < $#lines) {
  $line = $lines[$linecnt++];
  if ($filetype eq "c++" || $filetype eq "qml") {
    # C++ Checking
    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

    $pline = $line;
    $pline =~ s/\[\s\".*\"\s*\]//g;
    $pline =~ s/KStandardDirs::locate\s*\(.*\)//g;
    $pline =~ s/readPathEntry\s*\(.*\)//g;
    $pline =~ s/QRegExp\s*\(.*\)//g;
    $pline =~ s/i18n\s*\(.*\)//g;
    $pline =~ s/i18nc\s*\(.*\)//g;
    $pline =~ s/i18ncp\s*\(.*\)//g;
    $pline =~ s/htmlIcon\s*\(.*\)//g;
    $pline =~ s/loadIcon\s*\(.*\)//g;
    $pline =~ s/\"PNG\"//g;
    $pline =~ s/\"pixmap\(\)\"//g;

    # does this cover everything? without any filtering we get too much noise
    if ( $pline =~ m/Icon\s*\(/ || $pline =~ m/iconPath\s*\(/ ||
	 $pline =~ m/[Pp]ixmap\s*\(/ ) {

      next if ($pline =~ m/PixmapNode/);
      next if ($pline =~ m/KNotification/);
      next if ($pline =~ m/readIcon/);
      next if ($pline =~ m/readEntry/);
      next if ($pline =~ m/setTabIcon/);

      my @strings = split( /\"/, $pline );
      for ( my $i = 1; $i < $#strings; $i = $i + 2 ) {
	my $string = $strings[$i];
	if ( $icon_map{$string} ) {
	  $cnt++;
	  if ($cnt == 1) {
	    $lstr = "line\#" . $linecnt;
	  } else {
	    $lstr = $lstr . "," . $linecnt;
	  }
	  print "=> $line" if (&verboseArg());
	}
      }
    }
  }

  if ($filetype eq "desktop") {
    # Desktop Checking
    if ($line =~ m/^\s*Icon\s*=/) {
      my ($fred,$string) = split( /=/, $line );
      if ( $icon_map{$string} ) {
	$cnt++;
	if ($cnt == 1) {
	  $lstr = "line\#" . $linecnt;
	} else {
	  $lstr = $lstr . "," . $linecnt;
	}
	print "=> $line" if (&verboseArg());
      }
    }
  }

}
close(F);

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

sub Help {
  print "Check for invalid icon names\n";
  Exit 0 if &helpArg();
}

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

sub Explain {
  print "Browse available icons with 'kdialog --geticon actions'. Request new icons at <http://techbase.kde.org/Projects/Oxygen/Missing_Icons>.\n";
  Exit 0 if &explainArg();
}
