<?php
/**
* @brief A generic PHP Compiler in/out script. Run without any
* options to see usage instructions.
*
* @verbatim
*
* Templification - Keeping templates simple and efficient.
* Copyright (C) 2005 Jason Schmidt
*
* To contact Jason Schmidt, you may send mail to one of the following
* addresses. Please note these may change in the future, but every
* effort will be made to actively forward messages to the new
* address(es):
*
* hide@address.com
*
* Jason Schmidt
* 6245 Newberry Road 102
* Indianapolis, Indiana 46256-3103
* United States of America
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* @endverbatim
*
* @author Jason Schmidt
*
* @file phpcompiler.php
*
* @version $Revision $
*
* @date $Date $
*/
/**
* @brief Main execution for this file, which will load a list of
* input files and optionally a list of output files and run the
* hard-coded compiler
*
* @verbatim
* Usage: php Compiler.php [-o OutFile] InFile [Infile...]
* @endverbatim
*
* @see Templification
*
* @public
*
* @author Jason Schmidt
*/
function Main($argv)
{
// Get compiler itself
$class_name = require_once("PhpCompiler.class.php");
$compiler = new $class_name();
// Get option details
$modes = $compiler->GetModes();
$mode_by_name = array();
foreach($modes as $mode)
{
$mode_by_name[$mode["Name"]] = $mode["Default"];
}
// Pull self off list
array_shift($argv);
// Parse list of arguments
$InFile = array();
$OutFile = array();
$show_usage = FALSE;
while($argv)
{
$arg = array_shift($argv);
if("-o" == $arg)
{
$OutFile[] = array_shift($argv);
}
elseif(preg_match("/^--(.*?)=(.*)$/", $arg, $match))
{
$arg = $match[1];
$val = $match[2];
if(isset($mode_by_name[$arg]))
{
if("TRUE" === $val)
{
$mode_by_name[$arg] = TRUE;
}
elseif("FALSE" === $val)
{
$mode_by_name[$arg] = FALSE;
}
else
{
$mode_by_name[$arg] = $arg;
}
}
else
{
print("Unknown argument $arg\n");
$show_usage = TRUE;
}
}
elseif(file_exists($arg))
{
$InFile[] = $arg;
}
else
{
print("Cannot find file $arg\n");
$show_usage = TRUE;
}
}
if(0 == count($InFile))
{
$show_usage = TRUE;
}
if(!$compiler->ChangeMode($mode_by_name))
{
print("Error assigning options\n");
$show_usage = TRUE;
}
if($show_usage)
{
$opts = array(
"[-o OutFile]",
"InFile",
"[InFile...]",
);
foreach($modes as $mode)
{
$param = "--".$mode["Name"];
$value = "";
if(TRUE === $mode["Default"])
{
$value = "=TRUE";
}
elseif(FALSE === $mode["Default"])
{
$value = "=FALSE";
}
$opts[] = "[$param$value]";
}
print("Usage: php Compiler.php ".join(" ",$opts)."\n");
die(1);
}
// Get contents
$Input = "";
foreach($InFile as $filename)
{
$file = file_get_contents($filename);
if(FALSE === $file)
{
print("Error reading contents of $filename\n");
die(1);
}
$Input .= $file;
}
// Output errors should exit status 1, but not die immediately
$die = FALSE;
// Open outfiles
$count = count($OutFile);
$out_handles = array();
for($x = 0; $x < $count; $x++)
{
$out = $OutFile[$x];
$fh = fopen($out, "w");
if(!is_resource($fh))
{
print("Failed to open $out for write\n");
$die = TRUE;
}
else
{
$out_handles[$out] = $fh;
}
}
// Perform the heart of the class
$output = $compiler->Compile($Input);
$errors = $compiler->GetErrors();
// If errors
if(0 < count($errors))
{
$fh = fopen("php://STDERR", "w");
foreach($errors as $pos=>$error)
{
$lines = 0;
$chars = 0;
for($x = $pos-1; $x >= 0; $x --)
{
if("\n" == $Input[$x])
{
$lines++;
}
elseif(0 == $lines)
{
$chars++;
}
}
$lines++;
$chars++;
fwrite($fh, "$lines,$chars: $error\n");
}
fclose($fh);
if("" == $output)
{
die(1);
}
}
// Output as appropriate
if(0 == count($out_handles) && !$die)
{
print($output);
}
else
{
foreach($out_handles as $fn=>$fh)
{
if(FALSE === fwrite($fh, $output))
{
print("Failed writing $fn\n");
$die = TRUE;
}
elseif(TRUE !== fclose($fh))
{
print("Failed closing $fn\n");
$die = TRUE;
}
else
{
print("Wrote $fn\n");
}
}
}
// Exit with appropriate status on error
if($die)
{
die(1);
}
}
return(Main($argv));
?>