Skip to content

Commit 4309883

Browse files
authored
Idempotent build: configure.php (#202)
1 parent df18cd2 commit 4309883

File tree

1 file changed

+69
-65
lines changed

1 file changed

+69
-65
lines changed

configure.php

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
+----------------------------------------------------------------------+
2020
*/
2121

22-
error_reporting(-1);
23-
$cvs_id = '$Id$';
22+
ini_set( 'display_errors' , 1 );
23+
ini_set( 'display_startup_errors' , 1 );
24+
error_reporting( E_ALL );
25+
ob_implicit_flush();
2426

25-
echo "configure.php: $cvs_id\n";
27+
echo "configure.php on PHP " . phpversion() . "\n\n";
2628

2729
const RNG_SCHEMA_DIR = __DIR__ . DIRECTORY_SEPARATOR . 'docbook' . DIRECTORY_SEPARATOR . 'docbook-v5.2-os' . DIRECTORY_SEPARATOR . 'rng' . DIRECTORY_SEPARATOR;
2830
const RNG_SCHEMA_FILE = RNG_SCHEMA_DIR . 'docbook.rng';
@@ -101,7 +103,6 @@ function checking($for) // {{{
101103

102104
if ($ac['quiet'] != 'yes') {
103105
echo "Checking {$for}... ";
104-
flush();
105106
}
106107
} // }}}
107108

@@ -191,40 +192,44 @@ function make_scripts_executable($filename) // {{{
191192
}
192193
} // }}}
193194

194-
// Loop through and print out all XML validation errors {{{
195-
function print_xml_errors($details = true) {
195+
function print_xml_errors()
196+
{
196197
global $ac;
198+
$report = $ac['LANG'] == 'en' || $ac['XPOINTER_REPORTING'] == 'yes';
199+
$output = ( $ac['STDERR_TO_STDOUT'] == 'yes' ) ? STDOUT : STDERR ;
200+
197201
$errors = libxml_get_errors();
198-
$output = ( $ac['STDERR_TO_STDOUT'] == 'yes' ) ? STDOUT : STDERR;
199-
if ($errors && count($errors) > 0) {
200-
foreach($errors as $err) {
201-
if ($ac['LANG'] != 'en' && // translations
202-
$ac['XPOINTER_REPORTING'] != 'yes' && // can disable
203-
strncmp($err->message, 'XPointer evaluation failed:', 27) == 0) {
204-
continue;
205-
}
206-
$errmsg = wordwrap(" " . trim($err->message), 80, "\n ");
207-
if ($details && $err->file) {
208-
$file = file(urldecode($err->file)); // libxml appears to urlencode() its errors strings
209-
if (isset($file[$err->line])) {
210-
$line = rtrim($file[$err->line - 1]);
211-
$padding = str_repeat("-", $err->column) . "^";
212-
fprintf($output, "\nERROR (%s:%s:%s)\n%s\n%s\n%s\n", $err->file, $err->line, $err->column, $line, $padding, $errmsg);
213-
} else {
214-
fprintf($output, "\nERROR (%s:unknown)\n%s\n", $err->file, $errmsg);
215-
}
216-
} else {
217-
fprintf($output, "%s\n", $errmsg);
218-
}
219-
// Error too severe, stopping
220-
if ($err->level === LIBXML_ERR_FATAL) {
221-
fprintf($output, "\n\nPrevious errors too severe. Stopping here.\n\n");
222-
break;
223-
}
224-
}
225-
}
226202
libxml_clear_errors();
227-
} // }}}
203+
204+
$filePrefix = "file:///";
205+
$tempPrefix = realpath( __DIR__ . "/temp" ) . "/";
206+
$rootPrefix = realpath( __DIR__ . "/.." ) . "/";
207+
208+
if ( count( $errors ) > 0 )
209+
fprintf( $output , "\n" );
210+
211+
foreach( $errors as $error )
212+
{
213+
$mssg = rtrim( $error->message );
214+
$file = $error->file;
215+
$line = $error->line;
216+
$clmn = $error->column;
217+
218+
if ( str_starts_with( $mssg , 'XPointer evaluation failed:' ) && ! $report )
219+
continue; // Translations can omit these, to focus on fatal errors
220+
221+
if ( str_starts_with( $file , $filePrefix ) )
222+
$file = substr( $file , strlen( $filePrefix ) );
223+
if ( str_starts_with( $file , $tempPrefix ) )
224+
$file = substr( $file , strlen( $tempPrefix ) );
225+
if ( str_starts_with( $file , $rootPrefix ) )
226+
$file = substr( $file , strlen( $rootPrefix ) );
227+
228+
$prefix = $error->level === LIBXML_ERR_FATAL ? "FATAL" : "error";
229+
230+
fwrite( $output , "[$prefix $file {$line}:{$clmn}] {$mssg}\n" );
231+
}
232+
}
228233

229234
function find_xml_files($path) // {{{
230235
{
@@ -351,16 +356,6 @@ function getFileModificationHistory(): array {
351356
$php_bin_names = array('php', 'php5', 'cli/php', 'php.exe', 'php5.exe', 'php-cli.exe', 'php-cgi.exe');
352357
// }}}
353358

354-
// Reject old PHP installations {{{
355-
if (phpversion() < 5) {
356-
echo "PHP 5 or above is required. Version detected: " . phpversion() . "\n";
357-
exit(100);
358-
} else {
359-
echo "PHP version: " . phpversion() . "\n";
360-
} // }}}
361-
362-
echo "\n";
363-
364359
$acd = array( // {{{
365360
'srcdir' => $srcdir,
366361
'basedir' => $basedir,
@@ -676,10 +671,6 @@ function getFileModificationHistory(): array {
676671
libxml_use_internal_errors(true);
677672
}
678673

679-
$compact = defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0;
680-
$big_lines = defined('LIBXML_BIGLINES') ? LIBXML_BIGLINES : 0;
681-
$LIBXML_OPTS = LIBXML_NOENT | $big_lines | $compact;
682-
683674
if ($ac['VERSION_FILES'] === 'yes') {
684675
$dom = new DOMDocument;
685676
$dom->preserveWhiteSpace = false;
@@ -777,22 +768,39 @@ function getFileModificationHistory(): array {
777768
checking('whether to save an invalid .manual.xml');
778769
checkvalue($ac['FORCE_DOM_SAVE']);
779770

780-
echo "Loading and parsing {$ac["INPUT_FILENAME"]}... ";
781-
flush();
782771

783772
$dom = new DOMDocument();
784773

785-
// realpath() is important: omitting it causes severe performance degradation
786-
// and doubled memory usage on Windows.
787-
$didLoad = $dom->load(realpath("{$ac['srcdir']}/{$ac["INPUT_FILENAME"]}"), $LIBXML_OPTS);
774+
function dom_load( DOMDocument $dom , string $filename ) : bool
775+
{
776+
$filename = realpath( $filename );
777+
$options = LIBXML_NOENT | LIBXML_COMPACT | LIBXML_BIGLINES | LIBXML_PARSEHUGE;
778+
return $dom->load( $filename , $options );
779+
}
780+
781+
function dom_saveload( DOMDocument $dom , string $filename = "" )
782+
{
783+
if ( $filename == "" )
784+
$filename = __DIR__ . "/temp/manual.xml";
785+
786+
$dom->save( $filename );
787+
dom_load( $dom , $filename );
788+
}
788789

789-
// Check if the XML was simply broken, if so then just bail out
790-
if ($didLoad === false) {
790+
echo "Loading and parsing {$ac["INPUT_FILENAME"]}... ";
791+
792+
if ( dom_load( $dom , "{$ac['srcdir']}/{$ac["INPUT_FILENAME"]}" ) )
793+
{
794+
dom_saveload( $dom ); // correct file/line/column on error messages
795+
echo "done.\n";
796+
}
797+
else
798+
{
791799
echo "failed.\n";
792800
print_xml_errors();
793801
errors_are_bad(1);
794802
}
795-
echo "done.\n";
803+
796804

797805
echo "Running XInclude/XPointer... ";
798806
$total = 0;
@@ -892,7 +900,7 @@ function getFileModificationHistory(): array {
892900
}
893901

894902
echo "Validating {$ac["INPUT_FILENAME"]}... ";
895-
flush();
903+
896904
if ($ac['PARTIAL'] != '' && $ac['PARTIAL'] != 'no') { // {{{
897905
$dom->relaxNGValidate(RNG_SCHEMA_FILE); // we don't care if the validation works or not
898906
$node = $dom->getElementById($ac['PARTIAL']);
@@ -934,15 +942,11 @@ function getFileModificationHistory(): array {
934942
$mxml = $ac["OUTPUT_FILENAME"];
935943

936944
/* TODO: For some reason libxml does not validate the RelaxNG schema unless reloading the document in full */
937-
$dom->save($mxml);
938-
$dom->load($mxml, $LIBXML_OPTS);
945+
dom_saveload( $dom ); // idempotent path
946+
$dom->save($mxml); // non idempotent, historical path
939947
if ($dom->relaxNGValidate(RNG_SCHEMA_FILE)) {
940948
echo "done.\n";
941-
printf("\nAll good. Saving %s... ", basename($ac["OUTPUT_FILENAME"]));
942-
flush();
943-
$dom->save($mxml);
944-
945-
echo "done.\n";
949+
printf("\nAll good. Saved %s\n", basename($ac["OUTPUT_FILENAME"]));
946950
echo "All you have to do now is run 'phd -d {$mxml}'\n";
947951
echo "If the script hangs here, you can abort with ^C.\n";
948952
echo <<<CAT

0 commit comments

Comments
 (0)