<?php // vim: ts=4 sw=4 et tw=78 fdm=marker
/*
  +----------------------------------------------------------------------+
  | PHP Version 4                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.0 of the PHP license,       |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_0.txt.                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors:    Hartmut Holzgraefe <hholzgra@php.net>                    |
  |             Gabor Hojtsy <goba@php.net>                              |
  +----------------------------------------------------------------------+
  
  $Id: missing-entities.php.in 307070 2011-01-04 11:45:55Z rquadling $
*/

set_time_limit(0);

// Print out info for the viewer and log files
echo "Testing the manual for missing elements...\n";

// If we are in a scripts dir, go one dir up
// (because the NSGMLS path is relative to that directory!)
$wrkdir = getcwd();
if (strpos($wrkdir, "scripts") !== FALSE) {
    chdir("..");
}

$outdir = "@SRCDIR@";
$NSGMLS = "@NSGMLS@"; 
$NSGMLS_OUTPUT = "missing-entities.out"; 

if($NSGMLS == "no") {
    touch("entities/missing-ids.xml");
    touch("entities/missing-entities.ent");
    echo "nsgmls unavailable\n";
    return;
}

// Support for Windows systems
$windows = (strpos(PHP_OS, 'WIN') !== false);

// If PHP wasn't compiled on Cygwin, then the path to NSGMLS (if it is
// *nix path in case NSGMLS is installed via Cygwin setup) should be
// fixed for exec command to work
if ($windows 
    && (strpos(php_uname(), 'CYGWIN') === false)
    && (strncmp($NSGMLS, "/usr/bin/", 9) === 0)) 
{
    $cygbin = trim(`cygpath -d /usr/bin/`);
    $NSGMLS = preg_replace('!^/usr/bin/!', $cygbin, $NSGMLS) . '.exe';
}

// '..' components are not allowed in exec path to executable
$NSGMLS = realpath($NSGMLS);


// Execute a test of the manual
$envy = explode(" ", "@SP_OPTIONS@");
array_map('putenv', $envy);
exec(
    "$NSGMLS -f $NSGMLS_OUTPUT -i lang-@LANG@ -D . " .
    "-s {$outdir}/phpbook/phpbook-xml/phpdocxml.dcl manual.xml"
);

// Try to open files for rewriting
$ment = fopen("{$outdir}/entities/missing-entities.ent", "w");
$mids = fopen("{$outdir}/entities/missing-ids.xml", "w");

// Exit if we cannot rewrite the files
if (!$ment || !$mids) {
    die("ERROR: Cannot open files for writing\n");
}

// Write out XML declaration
fwrite($ment, "<" . "?xml version='1.0' encoding='iso-8859-1'?>\n\n");
fwrite($mids, "<" . "?xml version='1.0' encoding='iso-8859-1'?>\n\n");

// Initalize arrays
$missing_ids = array();
$missing_entities = array();

// Open output file
$results = file($NSGMLS_OUTPUT);

// Try to find missing IDs and entities
foreach ($results as $line) {
    
    trim($line);
    
    // missing entity found
    if (strpos($line, "not defined") !== FALSE) {
        $line = preg_replace('!^.[^"]*"!', '<!ENTITY ', $line);
        $line = preg_replace('!".*!', ' "???">', $line);
        $missing_entities[] = $line;
    }
    
    // missing ID found
    else if (strpos($line, "non-existent") !== FALSE) {
         preg_match('!(?<=ID.)".+"!', $line, $id);
        $missing_ids[] = "<para xml:id=" . $id[0] . " xreflabel=" .  $id[0]  . "></para>\n";
        $missing_ids_display[] = "xml:id=" .  $id[0] . "\n";
    }
}

// Find unique elements (one error message can occur several times)
$missing_ids = array_unique($missing_ids);
$missing_entities = array_unique($missing_entities);

// Sort elements (just to make handwork easier, if needed)
sort($missing_ids);
sort($missing_entities);

// missing ids for display
$missing_ids_display=isset($missing_ids_display) ? array_unique($missing_ids_display) : array();
sort($missing_ids_display);

// Write out missing entities to file
echo "Creating file {$outdir}/entities/missing-entities.ent... ";
foreach ($missing_entities as $ent) {
    fwrite($ment, $ent);
}

// That's all for missing entities
fclose($ment);

// print out success info
echo "done\n";
if (!empty($missing_entities)) {
    foreach ($missing_entities as $k => $v) {
            echo "* " . preg_replace('@[\s]+@', ' ', $v) . "\n";
    }
} else {
    echo "* No missing entities were found\n";
}

// If we have missing IDs, write them out as an appendix
echo "Creating file {$outdir}/entities/missing-ids.xml... ";
if (count($missing_ids) > 0) {

    fwrite($mids, "<appendix xml:id=\"missing-stuff\"><title>&MissingStuff;</title>\n");
    foreach ($missing_ids as $idpara) {
        fwrite($mids, $idpara);
    }
    fwrite($mids, "</appendix>\n");
}

// That's all for missing IDs
fclose($mids);

// print out success info
echo "done\n";
if (!empty($missing_ids_display)) {
    foreach ($missing_ids_display as $k => $v) {
        echo "* " . preg_replace('@[\s]+@', ' ', $v) . "\n";
    }
} else {
    echo "* No missing ids found\n";
}

?>
