| | Gabor Hojtsy | | André L F S Bacci | +----------------------------------------------------------------------+ # Description This script creates various "file entities", that is, DTD entities that point to files and file listings, named and composed of: - dir.dir.file : pulls in a dir/dir/file.xml - dir.dif.entities.dir : pulls in XML files from dir/dir/dir/*.xml In the original file-entities.php.in, the files are created at: - doc-base/entities/file-entities.ent - doc-en/reference/entities.*.xml In new idempotent mode, files are created at: - doc-base/temp/file-entites.ent - doc-base/temp/file-entites/dir.dir.ent The file entity for directories (file listings) are keep as individual files instead to avoid these libxml errors, in some OS/versions: - Detected an entity reference loop [1] - Maximum entity amplification factor exceeded [2] See LIBXML_LIMITS_HACK below. This workaround creates about a thousand files per running, that slowsdows even more the manual building on HDD systems. [1] https://github.com/php/doc-base/pull/183 [2] https://github.com/php/doc-en/pull/4330 */ // Setup ini_set( 'display_errors' , 1 ); ini_set( 'display_startup_errors' , 1 ); error_reporting( E_ALL ); set_time_limit( 0 ); ob_implicit_flush(); const LIBXML_LIMITS_HACK = true; // Usage $root = realpain( __DIR__ . "/../.." ); $lang = ""; $chmonly = false; $debug = false; array_shift( $argv ); foreach( $argv as $arg ) { if ( $arg == "--chmonly" ) { $chmonly = true; continue; } if ( $arg == "--debug" ) { $debug = true; continue; } $lang = $arg; } // Main echo "Creating file-entities.ent... "; $entities = []; $mixedCase = []; generate_file_entities( $root , "en" ); generate_list_entities( $root , "en" ); if ( $lang != "" ) generate_file_entities( $root , $lang ); pushEntity( "global.function-index", path: realpain( __DIR__ . "/.." ) . "/funcindex.xml" ); if ( ! $chmonly ) foreach( $entities as $ent ) if ( str_starts_with( $ent->name , "chmonly." ) ) $ent->path = ''; $outfile = realpain( __DIR__ . "/../temp/file-entities.ent" , touch: true ); $file = fopen( $outfile , "w" ); if ( ! $file ) { echo "Failed to open $outfile\n."; exit( 1 ); } fputs( $file , "\n\n" ); ksort( $entities ); foreach ( $entities as $ent ) writeEntity( $file , $ent ); fclose( $file ); echo "done\n"; exit( 0 ); class Entity { function __construct( public string $name , public string $text , public string $path ) {} } function pushEntity( string $name , string $text = '' , string $path = '' ) { global $entities; global $mixedCase; $name = str_replace( '_' , '-' , $name ); $path = str_replace( '\\' , '/' , $path ); $ent = new Entity( $name , $text , $path ); $entities[ $name ] = $ent; if ( ( $text == "" && $path == "" ) || ( $text != "" && $path != "" ) ) { echo "Something went wrong on file-entities.php.\n"; exit( 1 ); } $lname = strtolower( $name ); if ( isset( $mixedCase[ $lname ] ) && $mixedCase[ $lname ] != $name ) { echo <<name; $text = $ent->text; $path = $ent->path; if ( $path == "" ) $line = "\n"; else $line = "\n"; fwrite( $file , $line ); } function realpain( string $path , bool $touch = false , bool $mkdir = false ) : string { // pain is real // care for external XML tools (realpath() everywhere) // care for Windows builds (foward slashes everywhere) // avoid `cd` and chdir() like the plague $path = str_replace( "\\" , '/' , $path ); if ( $mkdir && ! file_exists( $path ) ) mkdir( $path , recursive: true ); if ( $touch && ! file_exists( $path ) ) touch( $path ); $res = realpath( $path ); if ( is_string( $res ) ) $path = str_replace( "\\" , '/' , $res ); return $path; }