#! /usr/bin/perl

# Author : KITA http://t-kita.net  Copyright : public domain
# replace htmlentities(x) with 
#   htmlentities(x,ENT_COMPAT,$SESSION->encoding) 
# in specified PHP files.
# Original files are backuped as *.orig0 .

# usage example :
# ./replace-htmlentities.pl `find -name '*.php'`

# unsupported cases :
# - parentheses in quoted string like
#    htmlentities( msg("OK. (:->") )
# - commas in quoted string like
#    htmlentities("a, b and c.")  ... comma is assumed as argument separator
#    ( but no problems for the cases like htmlentities(func(x,y)) )
# - already have plural arguments like
#    htmlentities(x,1)

$pat= "htmlentities";

foreach(@ARGV){
    $filename= $_;
    open FH, "<$filename";
    $/ = undef; # load the whole file
    $con= <FH>;

    $pos= 0; $changed= 0;
    while(1){
	$idx= index($con, $pat, $pos);
	if ($idx==-1){ last; }
	# $stat = -1 : beginning
	#       =  0 : in the most outer parenthesis pair
	#       =  1,2,.. : in the n-th inner parenthesis pair
	if ( substr($con,$idx-1,1) =~ '[a-zA-Z0-9_$]' ){
	    # print "# $filename ?$pat\n";
	    $pos= $idx+1; next; 
	}
	$stat= -1; $parg= "";
	for($i=0; $i<10000; $i++){
	    $c= substr($con,$idx+length($pat)+$i,1);
	    if ($stat==-1 and $c eq " "){
		next;  # skip spaces
	    }elsif($stat==-1 and $c eq "("){
		$stat= 0;
	    }elsif($stat==-1){
		last;  # not 'htmlentities()'
	    }elsif($stat==0 and $c eq ","){
		$stat= -2;
		last;  # already more than one argument
	    }elsif($stat==0 and $c eq ")"){
		last; # end
	    }elsif($stat>=0 and $c eq "("){
		$stat++;
		$parg.= $c;
	    }elsif($stat>=1 and $c eq ")"){
		$stat--;
		$parg.= $c;
	    }else{
		$parg.= $c;
	    }
	    # printf("%d %s\n",$stat,$parg)
	}
	if ($stat==0){
	    $arglen= $i+1;
	    # replace
	    $con= substr($con,0,$idx) . 
		"htmlentities(" .  $parg . 
##		",ENT_COMPAT,get_string('thischarset','moodle'))" . 
		',ENT_COMPAT,$SESSION->encoding)' . 
		substr($con,$idx+length($pat)+$arglen);
	    print "$filename:[pos:$idx,parg:$parg]\n";
	    $changed= 1;
	}else{
	    print "# $filename:[pos:$idx,parg:$parg,stat:$stat] not replaced.\n";
	}
	$pos= $idx+1;
    }
    close FH;
    if ($changed!=0){
	rename "$filename", "$filename.orig0";
	open FH, ">$filename";
	print FH $con; close FH;
    }
}
