File: file-entities.php.in

package info (click to toggle)
php-doc 20061001-1
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 45,764 kB
  • ctags: 1,611
  • sloc: xml: 502,485; php: 7,645; cpp: 500; makefile: 297; perl: 161; sh: 141; awk: 28
file content (471 lines) | stat: -rw-r--r-- 15,993 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
<?php
/*  
  +----------------------------------------------------------------------+
  | PHP Version 4                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2004 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: file-entities.php.in,v 1.43 2006/03/17 15:10:18 vrana Exp $
*/

/**
 *
 * Create phpdoc/entities/file-entities.ent with respect
 * to all the specialities needed:
 *
 *  . CHM only appendix integration
 *  . Special install part (temporary)
 *  . Reserved constant part (temporary)
 *  . Translated language files with English ones as fallbacks
 *  . Global function index
 *  . additional extension documentation from PECL
 *  . additional extension documentation from standalone extensions
 *
 * Also take in account, that if XSLT style sheets are used,
 * special file:/// prefixed path values are needed.
 *
 */


// Always flush output
ob_implicit_flush();
// This script runs for a long time
set_time_limit(0);

// ......:ARGUMENT PARSING:.....................................................

$not_windows = !eregi('WIN',PHP_OS);

// The dir for PHP. If the cygwin wasn't compiled on Cygwin, the path needs to be stripped.
$out_dir = ($not_windows || eregi('CYGWIN',php_uname()))? "@WORKDIR@" : abs_path(strip_cygdrive("@WORKDIR@"));

// The language encoding to use
$encoding = "@ENCODING@";

// PHP, PECL and additional extension source directories if given
$php_source  = ("@PHP_SOURCE@"  === "no" ? false : abs_path("@PHP_SOURCE@"));
$pecl_source = ("@PECL_SOURCE@" === "no" ? false : abs_path("@PECL_SOURCE@"));
$ext_sources = array();
foreach (explode(":", "@EXT_SOURCE@") as $path) {
    if(!empty($path)) {
        $ext_sources[]= abs_path($path);
    }
}

// ......:ENTITY CREATION:......................................................

// Put all the file entities into $entities
$entities = array();
file_entities("$out_dir/en", "$out_dir/@LANGDIR@", "$out_dir/en", $entities);

$refdir = "$out_dir/en/reference";
$dh = opendir($refdir);
while ($dir = readdir($dh)) {
	if ($dir[0] === ".") continue; // ignore system dir entries and hidden files
	if (is_file("$refdir/$dir/reference.xml")
		&& !is_file("$refdir/$dir/EXCLUDE")) {
		$dirent = str_replace("_","-",$dir);
		$title = get_title("$refdir/$dir/reference.xml");
		if (!$title) $title = $dirent; // extension name is close enough
		$builtin_extensions[$title] = "&reference.$dirent.reference;";
	}
}
ksort($builtin_extensions);

create_part_file("entities/builtin-extensions.xml", $builtin_extensions, 'funcref', '&FunctionReference;', '<para>See also <xref linkend="extensions"/>.</para>');
$entities[] = entstr("builtin.extensions", "$out_dir/entities/builtin-extensions.xml");

// additional documentation embedded in PECL extensions
$pecl_extensions = array();

if($pecl_source) {
    $dh = opendir($pecl_source);

    $pecl_dirs = array();
    while($dir = readdir()) { 
        if($dir[0] === ".") continue; // ignore system dir entries and hidden files
        $pecl_dirs[] = $dir;
    }
    
    foreach ($pecl_dirs as $dir) {
        $docdir = "$pecl_source/$dir/manual";

        if (@is_dir($docdir)) {

            $dirent = str_replace("_","-",$dir);          
            if(@is_dir("$docdir/en")) {
                file_entities("$docdir/en", "$docdir/@LANGDIR@", "$docdir/en", $entities, "reference.$dirent");
            } else if (@is_dir("$docdir/$dir")) {
                file_entities("$docdir/$dir", "$docdir/$dir", "$docdir/$dir", $entities, "reference.$dirent");          
            } else if (@is_dir("$docdir/$dirent")) {
                file_entities("$docdir/$dirent", "$docdir/$dirent", "$docdir/$dirent", $entities, "reference.$dirent");
            } else {
                continue;
            }
            $pecl_extensions[] = "&reference.$dirent.reference;";
	    sort($pecl_extensions);
        }
    }
    closedir($dh);
}

create_part_file("entities/pecl-extensions.xml", $pecl_extensions, 'pecl-funcref', "&PECLReference;");
$entities[] = entstr("pecl.extensions", "$out_dir/entities/pecl-extensions.xml");

// additional documentation embedded in external extension sources
$addon_extensions = array();
foreach ($ext_sources as $ext_dir) {
    $docdir = "$ext_dir/manual";
    $dir = basename($ext_dir);
    $dirent = str_replace("_","-",$dir);
    if(@is_dir("$docdir/en/reference/$dir")) {
        file_entities("$docdir/en/reference/$dir", "$docdir/@LANGDIR@/reference/$dir", "$docdir/en/reference/$dir", $entities, "reference.$dirent");
    } else if (@is_dir("$docdir/$dir")) {
        file_entities("$docdir/$dir", "$docdir/$dir", "$docdir/$dir", $entities, "reference.$dirent");          
    } else if (@is_dir("$docdir/$dirent")) {
        file_entities("$docdir/$dirent", "$docdir/$dirent", "$docdir/$dirent", $entities, "reference.$dirent");         
    } else {
        continue;
    }
    $addon_extensions[] = "&reference.$dirent.reference;";
    $sort($addon_extensions);
}

create_part_file("entities/addon-extensions.xml", $addon_extensions, 'addon-funcref', '&AddOnReference;');
$entities[] = entstr("addon.extensions", "$out_dir/entities/addon-extensions.xml");


// Open file for appending and write out all entitities
$fp = fopen("$out_dir/entities/file-entities.ent", "w");
if (!$fp) {
    die("ERROR: Failed to open $out_dir/entities/file-entities.ent for writing\n");
}

echo "\nCreating file: entities/file-entities.ent...\n";

// File header
fputs($fp, "<!-- DON'T TOUCH - AUTOGENERATED BY file-entities.php -->\n\n");

// The global function index page is special
fputs(
   $fp,
   "<!-- global function index file -->\n" .
   entstr("global.function-index", "$out_dir/funcindex.xml") . "\n"
);

// The missing id file is generated after this pass
fputs(
   $fp,
   "<!-- generated file with missing ids -->\n" .
   entstr("missing-ids", "$out_dir/entities/missing-ids.xml") . "\n" .
   "<!-- all other files -->\n"
);

// Write out all other entities
foreach ($entities as $entity) {
    fputs($fp, $entity);
}
fclose($fp);

// Here is the end of the code
exit;

// ......:FUNCTION DECLARATIONS:................................................

/**
 * Generate absolute path from a relative path, taking accout
 * the current wokring directory.
 *
 * @param string $path Relative path
 * @return string Absolute path generated
 */
function abs_path($path) {

    // This is already an absolute path (begins with / or a drive letter)
    if (preg_match("!^(/|\\w:)!", $path)) { return $path; }

    // Get directory parts

    $absdir  = str_replace("\\", "/", getcwd());
    $absdirs = explode("/", preg_replace("!/scripts$!", "", $absdir));
    $dirs    = explode("/", $path);

    // Generate array representation of absolute path
    foreach ($dirs as $dir) {
        if (empty($dir) or $dir == ".") continue;
        else if ($dir == "..") array_pop($absdirs);
        else array_push($absdirs, $dir);
    }

    // Return with string
    return join("/", $absdirs);
}

/**
 * Create file entities, and put them into the array passed as the
 * last argument (passed by reference).
 *
 * @param string $work_dir English files' directory
 * @param string $trans_dir Translation's directory
 * @param string $orig_dir Original directory
 * @param array $entities Entities string array
 * @return boolean Success signal
 */
function file_entities($work_dir, $trans_dir, $orig_dir, &$entities, $prefix=false) {

    // Compute translated version's path
    $trans_path = str_replace($orig_dir, $trans_dir, $work_dir);
    
    // Try to open English working directory
    $dh = opendir($work_dir);
    if (!$dh) { 
        return FALSE; 
    }

    // If the working directory is a reference functions directory,
    // then start to generate a functions.xml file for that folder.
    if (preg_match("!/functions$!", $work_dir) || preg_match("!/macros$!", $work_dir)) {
        // Start new functions file with empty entity set
        $function_entities = array();
        $functions_file = "$work_dir.xml";

        // Get relative file path to original directory, and form an entity
        $functions_file_entity = str_replace("$orig_dir/", "", $work_dir);
        $functions_file_entity = fname2entname($functions_file_entity, $prefix);
        $entities[] = entstr($functions_file_entity, $functions_file);
    }

    // While we can read that directory
    while (($file = readdir($dh)) !== FALSE) {
        // If file name begins with . skip it
        if ($file[0] == ".") { continue; }

        // If we found a directory, and it's name is not
        // CVS, recursively go into it, and generate entities
        if (is_dir($work_dir . "/" . $file)) {
            if ($file == "CVS") { continue; }
            file_entities($work_dir . "/" . $file, $trans_dir, $orig_dir, $entities, $prefix);
        }

        // If the file name ends in ".xml"
        if (preg_match("!\\.xml$!", $file)) {
            
            // Get relative file name and get entity name for it
            $name = str_replace(
                "$orig_dir/",
                "",
                $work_dir . "/" . preg_replace("!\\.xml$!", "", $file)
            );
            $name = fname2entname($name, $prefix);

            // If this is a functions directory, collect it into
            // the special $function_entities array
            if (isset($function_entities)) {
                $function_entities[] = "&$name;";
            }
            
            // If we have a translated file, use it, otherwise fall back to English
            if (file_exists("$trans_path/$file")) {
                $path = "$trans_path/$file";
            } else {
                $path = "$work_dir/$file";
            }

            // Append to entities array
            $entities[] = entstr($name, $path);

        } // end of "if xml file"
    } // end of readdir loop
    
    // Close directory
    closedir($dh);

    // If we created a function entities list, write it out
    if (isset($function_entities)) {
        
        // Sort by name
        sort($function_entities);
        
        // Write out all entities with newlines
        $fp = fopen($functions_file, "w");
        foreach ($function_entities as $entity) {
            fputs($fp, "$entity\n");
        }
        fclose($fp);
    }

    // Find all files available in the translation but not in the original English tree
    if ($orig_dir != $trans_dir && file_exists($trans_path) && is_dir($trans_path)) {

        // Open translation path
        $dh = @opendir($trans_path);

        if ($dh) {

            while (($file = readdir($dh)) !== FALSE) {
                if ($file[0] =="." || $file == "CVS") { continue; }
                if (is_dir($trans_path."/".$file)) { continue; }
                
                // If this is an XML file
                if (preg_match("!\\.xml$!",$file)) {
                    
                    // Generate relative file path and entity name out of it
                    $name = str_replace(
                        "$orig_dir/",
                        "",
                        $work_dir . "/" . preg_replace("!\\.xml$!", "", $file)
                    );
                    $name = fname2entname($name, $prefix);
                    
                    // If the file found is not in the English dir, append to entities list
                    if (!file_exists("$work_dir/$file")) {
                        $path = "$trans_path/$file";
                        $entities[] = entstr($name, $path);
                    }

                } // if this is an XML file end

            } // readdir iteration end
            closedir($dh);
        }
    }
    
} // end of funciton file_entities()

/**
 * Convert a file name (with path) to an entity name.
 *
 * Converts: _ => - and / => .
 *
 * @param string $fname File name
 * @return string Entity name
 */
function fname2entname($fname, $prefix=false)
{
    $ent = str_replace("_", "-", str_replace("/", ".", $fname));
	if ($prefix && !strstr($ent, $prefix)) {
		$ent = "$prefix.$ent";
	}
	return $ent;
}

/**
 * Return entity string with the given entityname and filename.
 * 
 * @param string $entname Entity name
 * @param string $filename Name of file
 * @return string Entity declaration string
 */
function entstr($entname, $filename)
{
    // If we have no file, than this is not a system entity
    if ($filename == "") {
        return sprintf("<!ENTITY %-40s        ''>\n", $entname);
    } else {
        return sprintf("<!ENTITY %-40s SYSTEM '%s'>\n", $entname, file2jade($filename));
    }
}

/**
 * Return windows style path for cygwin.
 * 
 * @param string $path Orginal path
 * @return string windows style path
 */
function strip_cygdrive($path){
    return preg_replace(array('!^/cygdrive/(\w)/!', '@^/home/.+$@'), array('\1:/', strtr(dirname(dirname(__FILE__)), '\\', '/')), $path);
}


/* Converts a path to the appropriate style for Jade */
function file2jade($path) {

    if ($GLOBALS['not_windows'])
	return $path;

    if ((bool)@WINJADE@) {
        return strip_cygdrive($path);
    } else {
        return preg_replace('@^([a-zA-Z]):/@S', '/cygdrive/$1/', $path);
    }
}

/** 
 * Create a reference <part>
 *
 * @param string Name of file to create (relative to phpdoc dir)
 * @param array  Entities to list in this file
 * @param string XML Id for the files top level <part> tag
 * @param string Title for this <part>
 * @param string Contents of <partintro>
 */
function create_part_file ($filename, $entities, $id, $title, $partintro = "")
{
	global $out_dir, $encoding;

	$fp = fopen("$out_dir/$filename","w");
	fputs($fp, "<?xml version='1.0' encoding='$encoding' ?>\n");
	fputs($fp, "<!-- FILE AUTOGENERATED BY file-entities.php, DO NOT EDIT !!! -->\n");
	if(count($entities)) {
		fputs($fp, "<part id='$id'>\n");
		fputs($fp, " <title>$title</title>\n");
		if ($partintro) {
			fputs($fp, " <partintro>\n  $partintro\n </partintro>\n");
		}

		foreach ($entities as $entity) {
			fputs($fp, "   $entity\n");
		}
		fputs($fp,"</part>\n");
	} else {
		fputs($fp, "<!-- File intentionally left blank -->\n");
	}
	fclose($fp);
}

/**
 * Pull the main title from reference.xml for sorting the table of contents.
 * To avoid bogus sorting, trim whitespace and convert the string to upper case.
 *
 * @param filename Path to reference.xml (relative to phpdoc dir)
 */
function get_title ($filename)
{
	$matches = array();

	$contents = file_get_contents($filename);

	/*
	 * Very basic approach for getting the title. We really should:
	 * - strip all comments (<!-- --> and <![CDATA[ ]]>) before
	 *   searching for <title>
	 * - strip tags from inside <title> ... </title>
	 * - resolve character entities
	 *
	 * ... but this is probably good enough for 98.5% of extensions
	 */

	if (preg_match("#titleabbrev>(.*?)</titleabbrev>#", $contents, $matches)) {
		return strtoupper(trim($matches[1]));
	}

	if (preg_match("#<title>(.*?)</title>#", $contents, $matches)) {
		return strtoupper(trim($matches[1]));
	}

	return null;
}

?>