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