ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
langcheck.php
Go to the documentation of this file.
1<?php
13header('Content-Type: text/html; charset=utf-8');
14
15set_time_limit(0);
16error_reporting(E_ALL);
17$time_start = explode(' ', microtime());
18
19function colorize($level, $string) {
20 static $colors, $end;
21 if ( !isset($colors) ) {
22 if ( PHP_SAPI != 'cli' ) {
23 $end = '</span>';
24 $colors = array(
25 TYPE_NOTICE => '<span style="color:#080;font-weight:bold;">',
26 TYPE_WARNING => '<span style="color:#CC0; font-weight: bold;">',
27 TYPE_ERROR => '<span style="color:#F00; font-weight: bold;">',
28 TYPE_OK => '<span style="color: #080; font-weight: bold;">'
29 );
30 } else {
31 $end = chr(27).'[0m';
32 $colors = array(
33 TYPE_NOTICE => chr(27).'[1m',
34 TYPE_WARNING => chr(27).'[1;33m',
35 TYPE_ERROR => chr(27).'[1;31m',
36 TYPE_OK => chr(27).'[1;32m'
37 );
38 }
39 }
40
41 if ( !isset($colors[$level]) ) {
42 trigger_error("no colors for level $level", E_USER_ERROR);
43 }
44
45 return $colors[$level].$string.$end;
46}
47
48define ('TYPE_NOTICE', 0);
49define ('TYPE_WARNING', 1);
50define ('TYPE_ERROR', 2);
51define ('TYPE_OK', 3);
52
54$error_cache = array();
56 global $error_cache;
57
58 if(count($error_cache)) {
59 echo colorize(TYPE_ERROR, "Failed");
60 if ( PHP_SAPI == 'cli' ) {
61 echo "\n\n";
62 } else {
63 echo "<br /><ol>\n";
64 }
65 foreach($error_cache as $error_msg) {
66 if ( PHP_SAPI == 'cli' ) {
67 echo "\n";
68 } else {
69 echo "<li>";
70 }
71 switch($error_msg['t']) {
72 case TYPE_NOTICE:
73 $msg = 'NOTICE';
74 break;
75 case TYPE_WARNING:
76 $msg = 'WARNING';
77 break;
78 case TYPE_ERROR:
79 $msg = 'ERROR';
80 break;
81 }
82 echo colorize($error_msg['t'], $msg);
83 if ( PHP_SAPI == 'cli' ) {
84 echo "\t" . $error_msg['m'];
85 } else {
86 echo " " . $error_msg['m'] . "</li>";
87 }
88 }
89 if ( PHP_SAPI == 'cli' ) {
90 echo "\n";
91 } else {
92 echo "</ol>\n";
93 }
94 } else {
95 echo colorize(TYPE_OK, "OK");
96 if ( PHP_SAPI == 'cli' ) {
97 echo "\n";
98 } else {
99 echo "\n<br />";
100 }
101 }
102 echo "\n";
103
104 $error_cache = array();
105}
106
109
110 $error_cache[] = array('t' => $type, 'm' => $message);
111 if(TYPE_ERROR == $type) {
112 $error_abort = true;
113 }
114}
115
116function dupfind_strtolower(&$value){
117 $value = strtolower($value);
118}
119
120if ( PHP_SAPI != 'cli' ) { ?>
121<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
122 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
123<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
124<head>
125 <title>GeSHi Language File Validation Script</title>
126 <style type="text/css">
127 <!--
128 html {
129 background-color: #f0f0f0;
130 }
131 body {
132 font-family: Verdana, Arial, sans-serif;
133 margin: 10px;
134 border: 2px solid #e0e0e0;
135 background-color: #fcfcfc;
136 padding: 5px;
137 font-size: 10pt;
138 }
139 h2 {
140 margin: .1em 0 .2em .5em;
141 border-bottom: 1px solid #b0b0b0;
142 color: #b0b0b0;
143 font-weight: normal;
144 font-size: 150%;
145 }
146 h3 {
147 margin: .1em 0 .2em .5em;
148 color: #b0b0b0;
149 font-weight: normal;
150 font-size: 120%;
151 }
152 #footer {
153 text-align: center;
154 font-size: 80%;
155 color: #a9a9a9;
156 }
157 #footer a {
158 color: #9999ff;
159 }
161 border: 1px solid #b0b0b0;
162 font-size: 90%;
163 color: #333;
164 margin-left: 20px;
165 }
167 margin-left: 20px;
168 }
170 font-size: 90%;
171 margin-left: .5em;
172 }
173 -->
174 </style>
175</head>
176<body>
177<h2>GeSHi Language File Validation Script</h2>
178<p>To use this script, make sure that <strong>geshi.php</strong> is in the
179parent directory or in your include_path, and that the language files are in a
180subdirectory of GeSHi's directory called <strong>geshi/</strong>.</p>
181<p>Everything else will be done by this script automatically. After the script
182finished you should see messages of what could cause trouble with GeSHi or where
183your language files can be improved. Please be patient, as this might take some time.</p>
184
185<ol>
186<li>Checking where to find GeSHi installation ...<?php
187} else { ?>
188<?php echo colorize(TYPE_NOTICE, "#### GeSHi Language File Validation Script ####") ?>
189
190
191To use this script, make sure that <?php echo colorize(TYPE_NOTICE, "geshi.php"); ?> is in the
192parent directory or in your include_path, and that the language files are in a
193subdirectory of GeSHi's directory called <?php echo colorize(TYPE_NOTICE, "geshi/"); ?>.
194
195Everything else will be done by this script automatically. After the script
196finished you should see messages of what could cause trouble with GeSHi or where
197your language files can be improved. Please be patient, as this might take some time.
198
199
200Checking where to find GeSHi installation ...<?php echo "\t";
201}
202
203// Rudimentary checking of where GeSHi is. In a default install it will be in ../, but
204// it could be in the current directory if the include_path is set. There's nowhere else
205// we can reasonably guess.
206if (is_readable('../geshi.php')) {
207 $path = '../';
208} elseif (is_readable('geshi.php')) {
209 $path = './';
210} else {
211 report_error(TYPE_ERROR, 'Could not find geshi.php - make sure it is in your include path!');
212}
213
214if(!$error_abort) {
215 require $path . 'geshi.php';
216
217 if(!class_exists('GeSHi')) {
218 report_error(TYPE_ERROR, 'The GeSHi class was not found, although it seemed we loaded the correct file!');
219 }
220}
221
222if(!$error_abort) {
223 if(!defined('GESHI_LANG_ROOT')) {
224 report_error(TYPE_ERROR, 'There\'s no information present on where to find the language files!');
225 } elseif(!is_dir(GESHI_LANG_ROOT)) {
226 report_error(TYPE_ERROR, 'The path "'.GESHI_LANG_ROOT.'" given, does not ressemble a directory!');
227 } elseif(!is_readable(GESHI_LANG_ROOT)) {
228 report_error(TYPE_ERROR, 'The path "'.GESHI_LANG_ROOT.'" is not readable to this script!');
229 }
230}
231
233
234if(!$error_abort) {
235 if ( PHP_SAPI == 'cli' ) {
236 echo "Listing available language files ...\t\t";
237 } else {
238 echo "</li>\n<li>Listing available language files ... ";
239 }
240
241 if (!($dir = @opendir(GESHI_LANG_ROOT))) {
242 report_error(TYPE_ERROR, 'Error requesting listing for available language files!');
243 }
244
245 $languages = array();
246
247 if(!$error_abort) {
248 while ($file = readdir($dir)) {
249 if (!$file || $file[0] == '.' || strpos($file, '.php') === false) {
250 continue;
251 }
252 $lang = substr($file, 0, strpos($file, '.'));
253 if(4 != strlen($file) - strlen($lang)) {
254 continue;
255 }
256 $languages[] = $lang;
257 }
258 closedir($dir);
259 }
260
261 $languages = array_unique($languages);
262 sort($languages);
263
264 if(!count($languages)) {
265 report_error(TYPE_WARNING, 'Unable to locate any usable language files in "'.GESHI_LANG_ROOT.'"!');
266 }
267
269}
270
271if ( PHP_SAPI == 'cli' ) {
272 if (isset($_SERVER['argv'][1]) && in_array($_SERVER['argv'][1], $languages)) {
273 $languages = array($_SERVER['argv'][1]);
274 }
275} else {
276 if (isset($_REQUEST['show']) && in_array($_REQUEST['show'], $languages)) {
277 $languages = array($_REQUEST['show']);
278 }
279}
280
281if(!$error_abort) {
282 foreach ($languages as $lang) {
283
284 if ( PHP_SAPI == 'cli' ) {
285 echo "Validating language file for '$lang' ...\t\t";
286 } else {
287 echo "</li>\n<li>Validating language file for '$lang' ... ";
288 }
289
290 $langfile = GESHI_LANG_ROOT . $lang . '.php';
291
292 $language_data = array();
293
294 if(!is_file($langfile)) {
295 report_error(TYPE_ERROR, 'The path "' .$langfile. '" does not ressemble a regular file!');
296 } elseif(!is_readable($langfile)) {
297 report_error(TYPE_ERROR, 'Cannot read file "' .$langfile. '"!');
298 } else {
299 $langfile_content = file_get_contents($langfile);
300 if(preg_match("/\?>(?:\r?\n|\r(?!\n)){2,}\Z/", $langfile_content)) {
301 report_error(TYPE_ERROR, 'Language file contains trailing empty lines at EOF!');
302 }
303 if(preg_match("/\?>(?:\r?\n|\r(?!\n))?\Z/", $langfile_content)) {
304 report_error(TYPE_ERROR, 'Language file contains an PHP end marker at EOF!');
305 }
306 if(!preg_match("/(?:\r?\n|\r(?!\n))\Z/", $langfile_content)) {
307 report_error(TYPE_ERROR, 'Language file contains no newline at EOF!');
308 }
309 if(preg_match("/(\r?\n|\r(?!\n))\\1\Z/", $langfile_content)) {
310 report_error(TYPE_ERROR, 'Language file contains trailing empty line before EOF!');
311 }
312 if(preg_match("/[\x20\t]$/m", $langfile_content)) {
313 report_error(TYPE_ERROR, 'Language file contains trailing whitespace at EOL!');
314 }
315 if(preg_match("/\t/", $langfile_content)) {
316 report_error(TYPE_NOTICE, 'Language file contains unescaped tabulator chars (probably for indentation)!');
317 }
318 if(preg_match('/^(?: )*(?! )(?! \*) /m', $langfile_content)) {
319 report_error(TYPE_NOTICE, 'Language file contains irregular indentation (other than 4 spaces per indentation level)!');
320 }
321
322 if(!preg_match("/\/\*\*((?!\*\/).)*?Author:((?!\*\/).)*?\*\//s", $langfile_content)) {
323 report_error(TYPE_WARNING, 'Language file does not contain a specification of an author!');
324 }
325 if(!preg_match("/\/\*\*((?!\*\/).)*?Copyright:((?!\*\/).)*?\*\//s", $langfile_content)) {
326 report_error(TYPE_WARNING, 'Language file does not contain a specification of the copyright!');
327 }
328 if(!preg_match("/\/\*\*((?!\*\/).)*?Release Version:((?!\*\/).)*?\*\//s", $langfile_content)) {
329 report_error(TYPE_WARNING, 'Language file does not contain a specification of the release version!');
330 }
331 if(!preg_match("/\/\*\*((?!\*\/).)*?Date Started:((?!\*\/).)*?\*\//s", $langfile_content)) {
332 report_error(TYPE_WARNING, 'Language file does not contain a specification of the date it was started!');
333 }
334 if(!preg_match("/\/\*\*((?!\*\/).)*?This file is part of GeSHi\.((?!\*\/).)*?\*\//s", $langfile_content)) {
335 report_error(TYPE_WARNING, 'Language file does not state that it belongs to GeSHi!');
336 }
337 if(!preg_match("/\/\*\*((?!\*\/).)*?language file for GeSHi\.((?!\*\/).)*?\*\//s", $langfile_content)) {
338 report_error(TYPE_WARNING, 'Language file does not state that it is a language file for GeSHi!');
339 }
340 if(!preg_match("/\/\*\*((?!\*\/).)*?GNU General Public License((?!\*\/).)*?\*\//s", $langfile_content)) {
341 report_error(TYPE_WARNING, 'Language file does not state that it is provided under the terms of the GNU GPL!');
342 }
343
344 unset($langfile_content);
345
346 include $langfile;
347
348 if(!isset($language_data)) {
349 report_error(TYPE_ERROR, 'Language file does not contain a $language_data structure to check!');
350 } elseif (!is_array($language_data)) {
351 report_error(TYPE_ERROR, 'Language file contains a $language_data structure which is not an array!');
352 }
353 }
354
355 if(!$error_abort) {
356 if(!isset($language_data['LANG_NAME'])) {
357 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'LANG_NAME\'] specification!');
358 } elseif (!is_string($language_data['LANG_NAME'])) {
359 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'LANG_NAME\'] specification which is not a string!');
360 }
361
362 if(!isset($language_data['COMMENT_SINGLE'])) {
363 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'COMMENT_SIGNLE\'] structure to check!');
364 } elseif (!is_array($language_data['COMMENT_SINGLE'])) {
365 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_SINGLE\'] structure which is not an array!');
366 }
367
368 if(!isset($language_data['COMMENT_MULTI'])) {
369 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'COMMENT_MULTI\'] structure to check!');
370 } elseif (!is_array($language_data['COMMENT_MULTI'])) {
371 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_MULTI\'] structure which is not an array!');
372 }
373
374 if(isset($language_data['COMMENT_REGEXP'])) {
375 if (!is_array($language_data['COMMENT_REGEXP'])) {
376 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_REGEXP\'] structure which is not an array!');
377 }
378 }
379
380 if(!isset($language_data['QUOTEMARKS'])) {
381 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'QUOTEMARKS\'] structure to check!');
382 } elseif (!is_array($language_data['QUOTEMARKS'])) {
383 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'QUOTEMARKS\'] structure which is not an array!');
384 }
385
386 if(isset($language_data['HARDQUOTE'])) {
387 if (!is_array($language_data['HARDQUOTE'])) {
388 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'HARDQUOTE\'] structure which is not an array!');
389 }
390 }
391
392 if(!isset($language_data['ESCAPE_CHAR'])) {
393 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'ESCAPE_CHAR\'] specification to check!');
394 } elseif (!is_string($language_data['ESCAPE_CHAR'])) {
395 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'ESCAPE_CHAR\'] specification which is not a string!');
396 } elseif (1 < strlen($language_data['ESCAPE_CHAR'])) {
397 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'ESCAPE_CHAR\'] specification is not empty or exactly one char!');
398 }
399
400 if(!isset($language_data['CASE_KEYWORDS'])) {
401 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'CASE_KEYWORDS\'] specification!');
402 } elseif (!is_int($language_data['CASE_KEYWORDS'])) {
403 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_KEYWORDS\'] specification which is not an integer!');
404 } elseif (GESHI_CAPS_NO_CHANGE != $language_data['CASE_KEYWORDS'] &&
405 GESHI_CAPS_LOWER != $language_data['CASE_KEYWORDS'] &&
406 GESHI_CAPS_UPPER != $language_data['CASE_KEYWORDS']) {
407 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_KEYWORDS\'] specification which is neither of GESHI_CAPS_NO_CHANGE, GESHI_CAPS_LOWER nor GESHI_CAPS_UPPER!');
408 }
409
410 if(!isset($language_data['KEYWORDS'])) {
411 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'KEYWORDS\'] structure to check!');
412 } elseif (!is_array($language_data['KEYWORDS'])) {
413 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'KEYWORDS\'] structure which is not an array!');
414 } else {
415 foreach($language_data['KEYWORDS'] as $kw_key => $kw_value) {
416 if(!is_integer($kw_key)) {
417 report_error(TYPE_WARNING, "Language file contains an key '$kw_key' in \$language_data['KEYWORDS'] that is not integer!");
418 } elseif (!is_array($kw_value)) {
419 report_error(TYPE_ERROR, "Language file contains a \$language_data['KEYWORDS']['$kw_value'] structure which is not an array!");
420 }
421 }
422 }
423
424 if(!isset($language_data['SYMBOLS'])) {
425 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'SYMBOLS\'] structure to check!');
426 } elseif (!is_array($language_data['SYMBOLS'])) {
427 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'SYMBOLS\'] structure which is not an array!');
428 }
429
430 if(!isset($language_data['CASE_SENSITIVE'])) {
431 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'CASE_SENSITIVE\'] structure to check!');
432 } elseif (!is_array($language_data['CASE_SENSITIVE'])) {
433 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_SENSITIVE\'] structure which is not an array!');
434 } else {
435 foreach($language_data['CASE_SENSITIVE'] as $cs_key => $cs_value) {
436 if(!is_integer($cs_key)) {
437 report_error(TYPE_WARNING, "Language file contains an key '$cs_key' in \$language_data['CASE_SENSITIVE'] that is not integer!");
438 } elseif (!is_bool($cs_value)) {
439 report_error(TYPE_ERROR, "Language file contains a Case Sensitivity specification for \$language_data['CASE_SENSITIVE']['$cs_value'] which is not a boolean!");
440 }
441 }
442 }
443
444 if(!isset($language_data['URLS'])) {
445 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'URLS\'] structure to check!');
446 } elseif (!is_array($language_data['URLS'])) {
447 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'URLS\'] structure which is not an array!');
448 } else {
449 foreach($language_data['URLS'] as $url_key => $url_value) {
450 if(!is_integer($url_key)) {
451 report_error(TYPE_WARNING, "Language file contains an key '$url_key' in \$language_data['URLS'] that is not integer!");
452 } elseif (!is_string($url_value)) {
453 report_error(TYPE_ERROR, "Language file contains a Documentation URL specification for \$language_data['URLS']['$url_value'] which is not a string!");
454 } elseif (preg_match('#&([^;]*(=|$))#U', $url_value)) {
455 report_error(TYPE_ERROR, "Language file contains unescaped ampersands (&amp;) in \$language_data['URLS']!");
456 }
457 }
458 }
459
460 if(!isset($language_data['OOLANG'])) {
461 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'OOLANG\'] specification!');
462 } elseif (!is_int($language_data['OOLANG']) && !is_bool($language_data['OOLANG'])) {
463 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OOLANG\'] specification which is neither boolean nor integer!');
464 } elseif (false !== $language_data['OOLANG'] &&
465 true !== $language_data['OOLANG'] &&
466 2 !== $language_data['OOLANG']) {
467 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OOLANG\'] specification which is neither of false, true or 2!');
468 }
469
470 if(!isset($language_data['OBJECT_SPLITTERS'])) {
471 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'OBJECT_SPLITTERS\'] structure to check!');
472 } elseif (!is_array($language_data['OBJECT_SPLITTERS'])) {
473 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OBJECT_SPLITTERS\'] structure which is not an array!');
474 }
475
476 if(!isset($language_data['REGEXPS'])) {
477 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'REGEXPS\'] structure to check!');
478 } elseif (!is_array($language_data['REGEXPS'])) {
479 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'REGEXPS\'] structure which is not an array!');
480 }
481
482 if(!isset($language_data['STRICT_MODE_APPLIES'])) {
483 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'STRICT_MODE_APPLIES\'] specification!');
484 } elseif (!is_int($language_data['STRICT_MODE_APPLIES'])) {
485 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STRICT_MODE_APPLIES\'] specification which is not an integer!');
486 } elseif (GESHI_MAYBE != $language_data['STRICT_MODE_APPLIES'] &&
487 GESHI_ALWAYS != $language_data['STRICT_MODE_APPLIES'] &&
488 GESHI_NEVER != $language_data['STRICT_MODE_APPLIES']) {
489 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STRICT_MODE_APPLIES\'] specification which is neither of GESHI_MAYBE, GESHI_ALWAYS nor GESHI_NEVER!');
490 }
491
492 if(!isset($language_data['SCRIPT_DELIMITERS'])) {
493 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'SCRIPT_DELIMITERS\'] structure to check!');
494 } elseif (!is_array($language_data['SCRIPT_DELIMITERS'])) {
495 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'SCRIPT_DELIMITERS\'] structure which is not an array!');
496 }
497
498 if(!isset($language_data['HIGHLIGHT_STRICT_BLOCK'])) {
499 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'HIGHLIGHT_STRICT_BLOCK\'] structure to check!');
500 } elseif (!is_array($language_data['HIGHLIGHT_STRICT_BLOCK'])) {
501 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'HIGHLIGHT_STRICT_BLOCK\'] structure which is not an array!');
502 }
503
504 if(isset($language_data['TAB_WIDTH'])) {
505 if (!is_int($language_data['TAB_WIDTH'])) {
506 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'TAB_WIDTH\'] specification which is not an integer!');
507 } elseif (1 > $language_data['TAB_WIDTH']) {
508 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'TAB_WIDTH\'] specification which is less than 1!');
509 }
510 }
511
512 if(isset($language_data['PARSER_CONTROL'])) {
513 if (!is_array($language_data['PARSER_CONTROL'])) {
514 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'PARSER_CONTROL\'] structure which is not an array!');
515 }
516 }
517
518 if(!isset($language_data['STYLES'])) {
519 report_error(TYPE_ERROR, 'Language file contains no $language_data[\'STYLES\'] structure to check!');
520 } elseif (!is_array($language_data['STYLES'])) {
521 report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STYLES\'] structure which is not an array!');
522 } else {
523 $style_arrays = array('KEYWORDS', 'COMMENTS', 'ESCAPE_CHAR',
524 'BRACKETS', 'STRINGS', 'NUMBERS', 'METHODS', 'SYMBOLS',
525 'REGEXPS', 'SCRIPT');
526 foreach($style_arrays as $style_kind) {
527 if(!isset($language_data['STYLES'][$style_kind])) {
528 report_error(TYPE_ERROR, "Language file contains no \$language_data['STYLES']['$style_kind'] structure to check!");
529 } elseif (!is_array($language_data['STYLES'][$style_kind])) {
530 report_error(TYPE_ERROR, "Language file contains a \$language_data['STYLES\']['$style_kind'] structure which is not an array!");
531 } else {
532 foreach($language_data['STYLES'][$style_kind] as $sk_key => $sk_value) {
533 if(!is_int($sk_key) && ('COMMENTS' != $style_kind && 'MULTI' != $sk_key)
534 && !(('STRINGS' == $style_kind || 'ESCAPE_CHAR' == $style_kind) && 'HARD' == $sk_key)) {
535 report_error(TYPE_WARNING, "Language file contains an key '$sk_key' in \$language_data['STYLES']['$style_kind'] that is not integer!");
536 } elseif (!is_string($sk_value)) {
537 report_error(TYPE_WARNING, "Language file contains a CSS specification for \$language_data['STYLES']['$style_kind'][$key] which is not a string!");
538 }
539 }
540 }
541 }
542
543 unset($style_arrays);
544 }
545 }
546
547 if(!$error_abort) {
548 //Initial sanity checks survived? --> Let's dig deeper!
549 foreach($language_data['KEYWORDS'] as $key => $keywords) {
550 if(!isset($language_data['CASE_SENSITIVE'][$key])) {
551 report_error(TYPE_ERROR, "Language file contains no \$language_data['CASE_SENSITIVE'] specification for keyword group $key!");
552 }
553 if(!isset($language_data['URLS'][$key])) {
554 report_error(TYPE_ERROR, "Language file contains no \$language_data['URLS'] specification for keyword group $key!");
555 }
556 if(empty($keywords)) {
557 report_error(TYPE_WARNING, "Language file contains an empty keyword list in \$language_data['KEYWORDS'] for group $key!");
558 }
559 foreach($keywords as $id => $kw) {
560 if(!is_string($kw)) {
561 report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['KEYWORDS'][$key][$id]!");
562 } elseif (!strlen($kw)) {
563 report_error(TYPE_ERROR, "Language file contains an empty string entry at \$language_data['KEYWORDS'][$key][$id]!");
564 } elseif (preg_match('/^([\‍(\‍)\{\}\[\]\^=.,:;\-+\*\/%\$\"\'\?]|&[\w#]\w*;)+$/i', $kw)) {
565 report_error(TYPE_NOTICE, "Language file contains an keyword ('$kw') at \$language_data['KEYWORDS'][$key][$id] which seems to be better suited for the symbols section!");
566 }
567 }
568 if(isset($language_data['CASE_SENSITIVE'][$key]) && !$language_data['CASE_SENSITIVE'][$key]) {
569 array_walk($keywords, 'dupfind_strtolower');
570 }
571 if(count($keywords) != count(array_unique($keywords))) {
572 $kw_diffs = array_count_values($keywords);
573 foreach($kw_diffs as $kw => $kw_count) {
574 if($kw_count > 1) {
575 report_error(TYPE_WARNING, "Language file contains per-group duplicate keyword '$kw' in \$language_data['KEYWORDS'][$key]!");
576 }
577 }
578 }
579 }
580
581 $disallowed_before = "(?<![a-zA-Z0-9\$_\|\#;>|^&";
582 $disallowed_after = "(?![a-zA-Z0-9_\|%\\-&;";
583
584 foreach($language_data['KEYWORDS'] as $key => $keywords) {
585 foreach($language_data['KEYWORDS'] as $key2 => $keywords2) {
586 if($key2 <= $key) {
587 continue;
588 }
589 $kw_diffs = array_intersect($keywords, $keywords2);
590 foreach($kw_diffs as $kw) {
591 if(isset($language_data['PARSER_CONTROL']['KEYWORDS'])) {
592 //Check the precondition\post-cindition for the involved keyword groups
593 $g1_pre = $disallowed_before;
594 $g2_pre = $disallowed_before;
595 $g1_post = $disallowed_after;
596 $g2_post = $disallowed_after;
597 if(isset($language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'])) {
598 $g1_pre = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
599 $g2_pre = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
600 }
601 if(isset($language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'])) {
602 $g1_post = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
603 $g2_post = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
604 }
605
606 if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_BEFORE'])) {
607 $g1_pre = $language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_BEFORE'];
608 }
609 if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_AFTER'])) {
610 $g1_post = $language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_AFTER'];
611 }
612
613 if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_BEFORE'])) {
614 $g2_pre = $language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_BEFORE'];
615 }
616 if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_AFTER'])) {
617 $g2_post = $language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_AFTER'];
618 }
619
620 if($g1_pre != $g2_pre || $g1_post != $g2_post) {
621 continue;
622 }
623 }
624 report_error(TYPE_WARNING, "Language file contains cross-group duplicate keyword '$kw' in \$language_data['KEYWORDS'][$key] and \$language_data['KEYWORDS'][$key2]!");
625 }
626 }
627 }
628 foreach($language_data['CASE_SENSITIVE'] as $key => $keywords) {
629 if(!isset($language_data['KEYWORDS'][$key]) && $key != GESHI_COMMENTS) {
630 report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['CASE_SENSITIVE'] specification for non-existing keyword group $key!");
631 }
632 }
633 foreach($language_data['URLS'] as $key => $keywords) {
634 if(!isset($language_data['KEYWORDS'][$key])) {
635 report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['URLS'] specification for non-existing keyword group $key!");
636 }
637 }
638 foreach($language_data['STYLES']['KEYWORDS'] as $key => $keywords) {
639 if(!isset($language_data['KEYWORDS'][$key])) {
640 report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['STYLES']['KEYWORDS'] specification for non-existing keyword group $key!");
641 }
642 }
643
644 foreach($language_data['COMMENT_SINGLE'] as $ck => $cv) {
645 if(!is_int($ck)) {
646 report_error(TYPE_WARNING, "Language file contains an key '$ck' in \$language_data['COMMENT_SINGLE'] that is not integer!");
647 }
648 if(!is_string($cv)) {
649 report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['COMMENT_SINGLE'][$ck]!");
650 }
651 if(!isset($language_data['STYLES']['COMMENTS'][$ck])) {
652 report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['COMMENTS'] specification for comment group $ck!");
653 }
654 }
655 if(isset($language_data['COMMENT_REGEXP'])) {
656 foreach($language_data['COMMENT_REGEXP'] as $ck => $cv) {
657 if(!is_int($ck)) {
658 report_error(TYPE_WARNING, "Language file contains an key '$ck' in \$language_data['COMMENT_REGEXP'] that is not integer!");
659 }
660 if(!is_string($cv)) {
661 report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['COMMENT_REGEXP'][$ck]!");
662 }
663 if(!isset($language_data['STYLES']['COMMENTS'][$ck])) {
664 report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['COMMENTS'] specification for comment group $ck!");
665 }
666 }
667 }
668 foreach($language_data['STYLES']['COMMENTS'] as $ck => $cv) {
669 if($ck != 'MULTI' && !isset($language_data['COMMENT_SINGLE'][$ck]) &&
670 !isset($language_data['COMMENT_REGEXP'][$ck])) {
671 report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['COMMENTS'] specification for Single Line or Regular-Expression Comment key $ck!");
672 }
673 }
674 if (isset($language_data['STYLES']['STRINGS']['HARD'])) {
675 if (empty($language_data['HARDQUOTE'])) {
676 report_error(TYPE_NOTICE, "Language file contains superfluous \$language_data['STYLES']['STRINGS'] specification for key 'HARD', but no 'HARDQUOTE's are defined!");
677 }
678 unset($language_data['STYLES']['STRINGS']['HARD']);
679 }
680 foreach($language_data['STYLES']['STRINGS'] as $sk => $sv) {
681 if($sk && !isset($language_data['QUOTEMARKS'][$sk])) {
682 report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['STRINGS'] specification for non-existing quotemark key $sk!");
683 }
684 }
685
686 foreach($language_data['REGEXPS'] as $rk => $rv) {
687 if(!is_int($rk)) {
688 report_error(TYPE_WARNING, "Language file contains an key '$rk' in \$language_data['REGEXPS'] that is not integer!");
689 }
690 if(is_string($rv)) {
691 //Check for unmasked / in regular expressions ...
692 if(empty($rv)) {
693 report_error(TYPE_WARNING, "Language file contains an empty regular expression at \$language_data['REGEXPS'][$rk]!");
694 } else {
695 if(preg_match("/(?<!\\\\)\//s", $rv)) {
696 report_error(TYPE_WARNING, "Language file contains a regular expression with an unmasked / character at \$language_data['REGEXPS'][$rk]!");
697 } elseif (preg_match("/(?<!<)(\\\\\\\\)*\\\\\|(?!>)/s", $rv)) {
698 report_error(TYPE_WARNING, "Language file contains a regular expression with an unescaped match for a pipe character '|' which needs escaping as '&lt;PIPE&gt;' instead at \$language_data['REGEXPS'][$rk]!");
699 }
700 }
701 } elseif(is_array($rv)) {
702 if(!isset($rv[GESHI_SEARCH])) {
703 report_error(TYPE_ERROR, "Language file contains no GESHI_SEARCH entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
704 } elseif(!is_string($rv[GESHI_SEARCH])) {
705 report_error(TYPE_ERROR, "Language file contains a GESHI_SEARCH entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
706 } else {
707 if(preg_match("/(?<!\\\\)\//s", $rv[GESHI_SEARCH])) {
708 report_error(TYPE_WARNING, "Language file contains a regular expression with an unmasked / character at \$language_data['REGEXPS'][$rk]!");
709 } elseif (preg_match("/(?<!<)(\\\\\\\\)*\\\\\|(?!>)/s", $rv[GESHI_SEARCH])) {
710 report_error(TYPE_WARNING, "Language file contains a regular expression with an unescaped match for a pipe character '|' which needs escaping as '&lt;PIPE&gt;' instead at \$language_data['REGEXPS'][$rk]!");
711 }
712 }
713 if(!isset($rv[GESHI_REPLACE])) {
714 report_error(TYPE_WARNING, "Language file contains no GESHI_REPLACE entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
715 } elseif(!is_string($rv[GESHI_REPLACE])) {
716 report_error(TYPE_ERROR, "Language file contains a GESHI_REPLACE entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
717 }
718 if(!isset($rv[GESHI_MODIFIERS])) {
719 report_error(TYPE_WARNING, "Language file contains no GESHI_MODIFIERS entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
720 } elseif(!is_string($rv[GESHI_MODIFIERS])) {
721 report_error(TYPE_ERROR, "Language file contains a GESHI_MODIFIERS entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
722 }
723 if(!isset($rv[GESHI_BEFORE])) {
724 report_error(TYPE_WARNING, "Language file contains no GESHI_BEFORE entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
725 } elseif(!is_string($rv[GESHI_BEFORE])) {
726 report_error(TYPE_ERROR, "Language file contains a GESHI_BEFORE entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
727 }
728 if(!isset($rv[GESHI_AFTER])) {
729 report_error(TYPE_WARNING, "Language file contains no GESHI_AFTER entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
730 } elseif(!is_string($rv[GESHI_AFTER])) {
731 report_error(TYPE_ERROR, "Language file contains a GESHI_AFTER entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
732 }
733 } else {
734 report_error(TYPE_WARNING, "Language file contains an non-string and non-array entry at \$language_data['REGEXPS'][$rk]!");
735 }
736 if(!isset($language_data['STYLES']['REGEXPS'][$rk])) {
737 report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['REGEXPS'] specification for regexp group $rk!");
738 }
739 }
740 foreach($language_data['STYLES']['REGEXPS'] as $rk => $rv) {
741 if(!isset($language_data['REGEXPS'][$rk])) {
742 report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['REGEXPS'] specification for regexp key $rk!");
743 }
744 }
745
746
747 }
748
750
751 flush();
752
753 if($error_abort) {
754 break;
755 }
756 }
757}
758
759$time_end = explode(' ', microtime());
761
762if ( PHP_SAPI != 'cli' ) {
763?></li>
764</ol>
765
766<p>Validation process completed in <?php printf("%.2f", $time_diff); ?> seconds.</p>
767
768<div id="footer">GeSHi &copy; 2004-2007 Nigel McNie, 2007-2008 Benny Baumann, released under the GNU GPL</div>
769</body>
770</html>
771
772<?php } else { ?>
773
774Validation process completed in <?php printf("%.2f", $time_diff); ?> seconds.
775
776GeSHi &copy; 2004-2007 Nigel McNie, 2007-2014 Benny Baumann, released under the GNU GPL
777
778<?php } ?>
$language_data
Definition: 4cs.php:40
html()
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
Definition: geshi.php:226
$key
Definition: croninfo.php:18
$languages
Definition: cssgen2.php:34
if(!array_key_exists('StateId', $_REQUEST)) $id
const GESHI_MAYBE
Strict mode might apply, and can be enabled or disabled by GeSHi->enable_strict_mode().
Definition: geshi.php:126
const GESHI_CAPS_NO_CHANGE
Lowercase keywords found.
Definition: geshi.php:94
const GESHI_BEFORE
The key of the regex array defining what bracket group in a matched search to put before the replacem...
Definition: geshi.php:140
const GESHI_SEARCH
The key of the regex array defining what to search for.
Definition: geshi.php:132
const GESHI_LANG_ROOT(!defined('GESHI_ROOT'))
The language file directory for GeSHi @access private.
Definition: geshi.php:52
const GESHI_AFTER
The key of the regex array defining what bracket group in a matched search to put after the replaceme...
Definition: geshi.php:143
const GESHI_ALWAYS
Strict mode always applies.
Definition: geshi.php:128
const GESHI_REPLACE
The key of the regex array defining what bracket group in a matched search to use as a replacement.
Definition: geshi.php:135
const GESHI_CAPS_LOWER
Leave keywords found as the case that they are.
Definition: geshi.php:98
const GESHI_COMMENTS
Used in language files to mark comments.
Definition: geshi.php:149
const GESHI_NEVER
#+ @access private
Definition: geshi.php:123
const GESHI_MODIFIERS
The key of the regex array defining any modifiers to the regular expression.
Definition: geshi.php:137
const GESHI_CAPS_UPPER
Uppercase keywords found.
Definition: geshi.php:96
dupfind_strtolower(&$value)
Definition: langcheck.php:116
margin left
Definition: langcheck.php:164
$time_diff
Definition: langcheck.php:760
const TYPE_ERROR
Definition: langcheck.php:50
output_error_cache()
Definition: langcheck.php:55
$time_start
Definition: langcheck.php:17
const TYPE_OK
Definition: langcheck.php:51
if(PHP_SAPI !='cli') color
Definition: langcheck.php:120
input
Definition: langcheck.php:166
colorize($level, $string)
Definition: langcheck.php:19
textarea
Definition: langcheck.php:160
$error_cache
Definition: langcheck.php:54
$error_abort
Definition: langcheck.php:53
const TYPE_WARNING
Definition: langcheck.php:49
select
Definition: langcheck.php:166
font size
Definition: langcheck.php:162
report_error($type, $message)
Definition: langcheck.php:107
const TYPE_NOTICE
Definition: langcheck.php:48
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
$time_end
Definition: langwiz.php:818
catch(Exception $e) $message
A simple script which outputs the CSS classes for all languages supported by GeSHi.
$type
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']