squellete2
[aidenligne_francais_universite.git] / ecrire / public / debug.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2007 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13
14 if (!defined("_ECRIRE_INC_VERSION")) return;
15
16 // http://doc.spip.org/@afficher_debug_contexte
17 function afficher_debug_contexte($env) {
18 static $n;
19 $n++;
20
21 if (is_array($env_tab = @unserialize($env)))
22 $env = $env_tab;
23
24 $env_texte="";
25 if (count($env)>0) {
26 $env_texte="<div class='spip-env'>"
27 . "<fieldset><legend>#ENV</legend>\n"
28 . "<div><table>\n";
29 foreach ($env as $nom => $valeur) {
30 $env_texte .= "\n<tr><td><strong>".nl2br(entites_html($nom))
31 . "</strong></td>";
32 if (is_array($valeur))
33 $valeur = '(' . count($valeur) .' items) [' . join(',', $valeur) . ']';
34 $env_texte .= "<td>:&nbsp;".nl2br(entites_html($valeur))
35 . "</td></tr>\n";
36 }
37 $env_texte .= "\n</table></div>\n";
38 $env_texte .= "</fieldset></div>\n";
39 }
40 return $env_texte;
41 }
42
43 // Si le code php produit des erreurs, on les affiche en surimpression
44 // sauf pour un visiteur non admin (lui ne voit rien de special)
45 // et en mode validation (fausse erreur "double occurrence insert_head")
46 // ajouter &var_mode=debug pour voir les erreurs et en parler sur spip@rezo.net
47 // http://doc.spip.org/@affiche_erreurs_page
48 function affiche_erreurs_page($tableau_des_erreurs) {
49
50 if ($GLOBALS['exec']=='valider_xml') return '';
51 $GLOBALS['bouton_admin_debug'] = true;
52 $res = '';
53 foreach ($tableau_des_erreurs as $err) {
54 $res .= "<li>" .$err[0] . ", <small>".$err[1]."</small><br /></li>\n";
55 }
56 return "\n<div id='spip-debug' style='"
57 . "position: absolute; top: 20px; left: 20px; z-index: 1000;"
58 . "filter:alpha(opacity=60); -moz-opacity:0.6; opacity: 0.6;"
59 . "'><ul><li>"
60 . _T('zbug_erreur_squelette')
61 ## aide locale courte a ecrire, avec lien vers une grosse page de documentation
62 # aide('erreur_compilation'),
63 . "<br /></li>"
64 . "<ul>"
65 . $res
66 . "</ul></ul></div>";
67 }
68
69 //
70 // Si une boucle cree des soucis, on peut afficher la requete fautive
71 // avec son code d'erreur
72 //
73 // http://doc.spip.org/@erreur_requete_boucle
74 function erreur_requete_boucle($query, $id_boucle, $type, $errno, $erreur) {
75
76 $GLOBALS['bouton_admin_debug'] = true;
77
78 if (eregi('err(no|code):?[[:space:]]*([0-9]+)', $erreur, $regs))
79 $errno = $regs[2];
80 else if (($errno == 1030 OR $errno <= 1026)
81 AND ereg('[^[:alnum:]]([0-9]+)[^[:alnum:]]', $erreur, $regs))
82 $errno = $regs[1];
83
84 // Erreur systeme
85 if ($errno > 0 AND $errno < 200) {
86 $retour .= "<tt><br /><br /><blink>"
87 . _T('info_erreur_systeme', array('errsys'=>$errno))
88 . "</blink><br />\n<b>"
89 . _T('info_erreur_systeme2',
90 array('script' => generer_url_ecrire('admin_repair')))
91 . '</b><br />';
92 spip_log("Erreur systeme $errno");
93 }
94 // Requete erronee
95 else {
96 $retour .= "<tt><blink>&lt;BOUCLE".$id_boucle."&gt;("
97 . $type . ")</blink><br />\n"
98 . "<b>"._T('avis_erreur_mysql')."</b><br />\n"
99 . htmlspecialchars($query)
100 . "\n<br /><span style='color: red'><b>".htmlspecialchars($erreur)
101 . "</b></span><br />"
102 . "<blink>&lt;/BOUCLE".$id_boucle."&gt;</blink></tt>\n";
103
104 include_spip('inc/minipres');
105 $retour .= aide('erreur_mysql');
106 spip_log("Erreur requete $id_boucle (".$GLOBALS['fond'].".html)");
107 }
108
109 erreur_squelette($retour);
110 }
111
112
113 //
114 // Erreur de syntaxe des squelettes : memoriser le code fautif
115 //
116 // http://doc.spip.org/@erreur_squelette
117 function erreur_squelette($message='', $lieu='') {
118 global $tableau_des_erreurs;
119 global $auteur_session;
120 static $runs;
121
122 if (is_array($message)) list($message, $lieu) = $message;
123
124 spip_log("Erreur squelette: $message | $lieu ("
125 . $GLOBALS['fond'].".html)");
126 $GLOBALS['bouton_admin_debug'] = true;
127 $tableau_des_erreurs[] = array($message, $lieu);
128 // Eviter les boucles infernales
129 if (++$runs > 4) {
130 if ($_COOKIE['spip_admin'] OR
131 ($auteur_session['statut'] == '0minirezo') OR
132 ($GLOBALS['var_mode'] == 'debug')) {
133 include_spip('inc/minipres');
134
135 $titre = 'Spip '
136 . $GLOBALS['spip_version_affichee']
137 . ' '
138 . _T('admin_debug')
139 . ' '
140 . supprimer_tags(extraire_multi($GLOBALS['meta']['nom_site']));
141 echo minipres($titre, affiche_erreurs_page($tableau_des_erreurs));
142 exit;
143 }
144 }
145 }
146
147 //
148 // Le debusqueur version 3
149 //
150
151 // appelee a chaque sortie de boucle (cf compiler.php) et a chaque requete
152 // dans ce derniers cas on n'a pas le nom du squelette
153
154 // http://doc.spip.org/@boucle_debug_resultat
155 function boucle_debug_resultat ($id, $type, $resultat) {
156 global $debug_objets;
157
158 $nom = $debug_objets['courant'];
159
160 if ($type == 'requete') {
161 $debug_objets['requete']["$nom$id"] = $resultat;
162 }
163 else {
164 // ne pas memoriser plus de 3 tours d'une meme boucle
165 if (count($debug_objets['resultat']["$nom$id"]) < 3)
166 $debug_objets['resultat']["$nom$id"][] = $resultat;
167 }
168 }
169
170 // appelee a chaque sortie de sequence (compilo.php)
171 // http://doc.spip.org/@debug_sequence
172 function debug_sequence($id, $nom, $niv, $sequence) {
173 global $debug_objets;
174
175 if (!$niv)
176 {
177 $debug_objets['sequence'][$nom.$id] = $sequence;
178 }
179 $res = "";
180 foreach($sequence as $v) if (is_array($v)) $res .= $v[2];
181 return $res;
182 }
183
184 // appelee a chaque compilation de boucle (compilo.php)
185 // http://doc.spip.org/@boucle_debug_compile
186 function boucle_debug_compile ($id, $nom, $code) {
187 global $debug_objets;
188
189 $debug_objets['code'][$nom.$id] = $code;
190 }
191
192 // appelee a chaque compilation de squelette (compilo.php)
193 // http://doc.spip.org/@squelette_debug_compile
194 function squelette_debug_compile($nom, $sourcefile, $code, $squelette) {
195 global $debug_objets;
196
197 $debug_objets['squelette'][$nom] = $squelette;
198 $debug_objets['sourcefile'][$nom] = $sourcefile;
199
200 if (is_array($GLOBALS['contexte_inclus']))
201 $debug_objets['contexte'][$nom] = $GLOBALS['contexte_inclus'];
202 else {
203 $debug_objets['contexte'][$nom] = calculer_contexte();
204 if (!isset($debug_objets['principal']))
205 $debug_objets['principal'] = $nom;
206 }
207 }
208
209 // appelee a chaque analyse syntaxique de squelette
210 // http://doc.spip.org/@boucle_debug
211 function boucle_debug ($nom, $id_parent, $id, $type, $crit, $avant, $milieu, $apres, $altern) {
212 global $debug_objets;
213 $debug_objets['courant'] = $nom;
214 $debug_objets['parent'][$nom.$id] = $id_parent;
215 $debug_objets['pretty'][$nom.$id] =
216 "BOUCLE$id($type)" . htmlspecialchars(
217 preg_replace(",[\r\n],", "\\n", $crit));
218 // on synthetise avec la syntaxe standard, mais "<//" pose pb
219 $debug_objets['boucle'][$nom.$id] =
220 (!$avant ? "" : "<B$id>$avant") .
221 "<BOUCLE$id($type)$crit>" .
222 $milieu .
223 "</BOUCLE$id>" .
224 (!$apres ? "" : "$apres</B$id>") .
225 (!$altern ? "" : "$altern<//B$id>");
226 }
227
228 // http://doc.spip.org/@trouve_boucle_debug
229 function trouve_boucle_debug($n, $nom, $debut=0, $boucle = "")
230 {
231 global $debug_objets;
232
233 $id = $nom . $boucle;
234 if (is_array($debug_objets['sequence'][$id])) {
235 foreach($debug_objets['sequence'][$id] as $v) {
236
237 if (!preg_match('/^(.*)(<\?.*\?>)(.*)$/s', $v[2],$r))
238 $y = substr_count($v[2], "\n");
239 else {
240 if ($v[1][0] == '#')
241 // balise dynamique
242 $incl = $debug_objets['resultat'][$v[0]];
243 else
244 // inclusion
245 $incl = $debug_objets['squelette'][trouve_squelette_inclus($v[2])];
246 $y = substr_count($incl, "\n")
247 + substr_count($r[1], "\n")
248 + substr_count($r[3], "\n");
249 }
250 if ($n <= ($y + $debut)) {
251 if ($v[1][0] == '?')
252 return trouve_boucle_debug($n, $nom, $debut, substr($v[1],1));
253 elseif ($v[1][0] == '!') {
254 if ($incl = trouve_squelette_inclus($v[1]))
255 return trouve_boucle_debug($n, $incl, $debut);
256 }
257 return array($nom, $boucle, $v[0] -1 + $n - $debut );
258 }
259 $debut += $y;
260 }
261 }
262 return array($nom, $boucle, $n-$debut);
263 }
264
265 // http://doc.spip.org/@trouve_squelette_inclus
266 function trouve_squelette_inclus($script)
267 {
268 global $debug_objets;
269 preg_match('/include\(.(.*).php3?.\);/', $script, $reg);
270 // si le script X.php n'est pas ecrire/public.php
271 // on suppose qu'il prend le squelette X.html (pas sur, mais y a pas mieux)
272 if ($reg[1] == 'ecrire/public')
273 // si c'est bien ecrire/public on cherche le param 'fond'
274 if (!preg_match("/'fond' => '([^']*)'/", $script, $reg))
275 // a defaut on cherche le param 'page'
276 if (!preg_match("/'param' => '([^']*)'/", $script, $reg))
277 $reg[1] = "inconnu";
278 $incl = $reg[1] . '.html$';
279
280 foreach($debug_objets['sourcefile'] as $k => $v) {
281 if (ereg($incl,$v)) return $k;
282 }
283 return "";
284 }
285
286 // http://doc.spip.org/@reference_boucle_debug
287 function reference_boucle_debug($n, $nom, $self)
288 {
289 list($skel, $boucle, $ligne) = trouve_boucle_debug($n, $nom);
290
291 if (!$boucle)
292 return !$ligne ? "" :
293 (" (" .
294 (($nom != $skel) ? _T('squelette_inclus_ligne') :
295 _T('squelette_ligne')) .
296 " <a href='$self&amp;var_mode_objet=$skel&amp;var_mode_affiche=squelette&amp;var_mode_ligne=$ligne#L$ligne'>$ligne</a>)");
297 else {
298 $self .= "&amp;var_mode_objet=$skel$boucle&amp;var_mode_affiche=boucle";
299
300 return !$ligne ? " (boucle\n<a href='$self#$skel$boucle'>$boucle</a>)" :
301 " (boucle $boucle ligne\n<a href='$self&amp;var_mode_ligne=$ligne#L$ligne'>$ligne</a>)";
302 }
303 }
304
305 // affiche un texte avec numero de ligne et ancre.
306
307 // http://doc.spip.org/@ancre_texte
308 function ancre_texte($texte, $fautifs=array())
309 {
310 global $var_mode_ligne;
311 if ($var_mode_ligne) $fautifs[]= array($var_mode_ligne);
312 $res ='';
313
314 $s = highlight_string(str_replace('</script>','</@@@@@>',$texte),true);
315
316 $s = str_replace('/@@@@@','/script', // bug de highlight_string
317 str_replace('</font>','</span>',
318 str_replace('<font color="','<span style="color: ', $s)));
319 if (substr($s,0,6) == '<code>') { $s=substr($s,6); $res = '<code>';}
320
321 $s = preg_replace(',<(\w[^<>]*)>([^<]*)<br />([^<]*)</\1>,',
322 '<\1>\2</\1><br />' . "\n" . '<\1>\3</\1>',
323 $s);
324
325 $tableau = explode("<br />", $s);
326
327 $ancre = md5($texte);
328 $n = strlen(count($tableau));
329 $format = "<a href='#T%s' title=\"%s\"><span id='L%d' style='text-align: right;color: black;%s'>%0"
330 . strval($n)
331 . "d&nbsp;&nbsp;</span></a>\n";
332
333 $format10=str_replace('black','pink',$format);
334 $formaterr="background-color: pink;";
335 $i=1;
336
337 $flignes = array();
338
339 $loc = array(0,0);
340 foreach ($fautifs as $lc)
341 if (is_array($lc)) {
342 $l = array_shift($lc);
343 $flignes[$l] = $lc;
344 } else $flignes[$lc] = $loc;
345
346 foreach ($tableau as $ligne) {
347 if (isset($flignes[$i])) {
348 $ligne = str_replace('&nbsp;',' ', $ligne);
349 $indexmesg = $flignes[$i][1];
350 $err = textebrut($flignes[$i][2]);
351 // tentative de pointer sur la colonne fautive;
352 // marche pas car highlight_string rajoute des entites. A revoir.
353 // $m = $flignes[$i][0];
354 // $ligne = substr($ligne, 0, $m-1) .
355 // sprintf($formaterr, substr($ligne,$m));
356 $bg = $formaterr;
357 } else {$indexmesg = $ancre; $err= $bg='';}
358 $res .= "<br />\n"
359 . sprintf((($i%10) ? $format :$format10), $indexmesg, $err, $i, $bg, $i)
360 . $ligne;
361 $i++;
362 }
363 return "<div id='T$ancre'>$res</div>";
364 }
365
366 // l'environnement graphique du debuggueur
367 // http://doc.spip.org/@debug_dumpfile
368 function debug_dumpfile ($texte, $fonc, $type) {
369 global $debug_objets, $var_mode_objet, $var_mode_affiche;
370
371 $debug_objets[$type][$fonc . 'tout'] = $texte;
372 if (!$debug_objets['sourcefile']) return;
373 if ($texte && ($var_mode_objet != $fonc || $var_mode_affiche != $type))
374 return;
375 if (!$fonc) $fonc = $debug_objets['principal'];
376
377 // en cas de squelette inclus, virer le code de l'incluant:
378 // - il contient souvent une Div restreignant la largeur a 3 fois rien
379 // - ca fait 2 headers !
380 ob_end_clean();
381 $self = str_replace("\\'", '&#39;', self());
382 $self = parametre_url($self,'var_mode', 'debug');
383
384 echo debug_debut($fonc);
385 if ($var_mode_affiche !== 'validation') {
386 $self = parametre_url($self,'var_mode', 'debug');
387 foreach ($debug_objets['sourcefile'] as $nom_skel => $sourcefile) {
388 echo "<fieldset><legend>",$sourcefile,"&nbsp;: ";
389 echo "\n<a href='$self&amp;var_mode_objet=$nom_skel&amp;var_mode_affiche=squelette#$nom_skel'>"._T('squelette')."</a>";
390 echo "\n<a href='$self&amp;var_mode_objet=$nom_skel&amp;var_mode_affiche=resultat#$nom_skel'>"._T('zbug_resultat')."</a>";
391 echo "\n<a href='$self&amp;var_mode_objet=$nom_skel&amp;var_mode_affiche=code#$nom_skel'>"._T('zbug_code')."</a></legend>";
392
393 if (is_array($contexte = $debug_objets['contexte'][$nom_skel]))
394 echo afficher_debug_contexte($contexte);
395
396 $i = 0;
397 $colors = array('#e0e0f0', '#f8f8ff');
398 $res = "";
399 if (is_array($debug_objets['pretty']))
400 foreach ($debug_objets['pretty'] as $nom => $pretty)
401 if (substr($nom, 0, strlen($nom_skel)) == $nom_skel) {
402 $i++;
403 $aff = "&lt;".$pretty."&gt;";
404 if ($var_mode_objet == $nom)
405 $aff = "<b>$aff</b>";
406 $res .= "\n<tr style='background-color: " .
407 $colors[$i%2] .
408 "'><td align='right'>$i</td><td>\n" .
409 "<a class='debug_link_boucle' href='" .
410 $self .
411 "&amp;var_mode_objet=" .
412 $nom .
413 "&amp;var_mode_affiche=boucle#$nom_skel'>" .
414 _T('zbug_boucle') .
415 "</a></td><td>\n<a class='debug_link_boucle' href='" .
416 $self .
417 "&amp;var_mode_objet=" .
418 $nom .
419 "&amp;var_mode_affiche=resultat#$nom_skel'>" .
420 _T('zbug_resultat') .
421 "</a></td><td>\n<a class='debug_link_resultat' href='" .
422 $self .
423 "&amp;var_mode_objet=" .
424 $nom .
425 "&amp;var_mode_affiche=code#$nom_skel'>" .
426 _T('zbug_code') .
427 "</a></td><td>\n" .
428 $aff .
429 "</td></tr>";
430 }
431 if ($res) echo "<table width='100%'>\n$res</table>\n";
432 echo "</fieldset>\n";
433 }
434 echo "</div>\n<a id='$fonc'></a>\n";
435 if ($var_mode_objet && ($res = $debug_objets[$var_mode_affiche][$var_mode_objet])) {
436 echo "<div id=\"debug_boucle\"><fieldset>";
437 if ($var_mode_affiche == 'resultat') {
438 echo "<legend>",$debug_objets['pretty'][$var_mode_objet],"</legend>";
439 echo ancre_texte(traite_query($debug_objets['requete'][$var_mode_objet]));
440 foreach ($res as $view)
441 if ($view) echo "\n<br /><fieldset>",interdire_scripts($view),"</fieldset>";
442
443 } else if ($var_mode_affiche == 'code') {
444 echo "<legend>",$debug_objets['pretty'][$var_mode_objet],"</legend>";
445 echo ancre_texte("<"."?php\n".$res."\n?".">");
446 } else if ($var_mode_affiche == 'boucle') {
447 echo "<legend>",$debug_objets['pretty'][$var_mode_objet],"</legend>";
448 echo ancre_texte($res);
449 } else if ($var_mode_affiche == 'squelette') {
450 echo "<legend>",$debug_objets['sourcefile'][$var_mode_objet],"</legend>";
451 echo ancre_texte($debug_objets['squelette'][$var_mode_objet]);
452 }
453 echo "</fieldset></div>";
454 }
455 }
456
457 if ($texte) {
458
459 $err = "";
460 $titre = $GLOBALS['var_mode_affiche'];
461 if ($titre != 'validation') {
462 $titre = 'zbug_' . $titre;
463 $texte = ancre_texte($texte, array('',''));
464 } else {
465 $sax = charger_fonction('valider_xml', 'inc');
466 $res = $sax($texte);
467 list($texte, $err) = emboite_texte($res, $fonc, $self);
468 if ($err === false)
469 $err = _T('impossible');
470 elseif ($err === true)
471 $err = _T('correcte');
472 else $err = ": $err";
473 }
474
475 echo "<div id=\"debug_boucle\"><fieldset><legend>",
476 _T($titre),
477 ' ',
478 $err,
479 "</legend>";
480 echo $texte;
481 echo "</fieldset></div>";
482 }
483 debug_fin();
484 exit;
485 }
486
487 // http://doc.spip.org/@debug_debut
488 function debug_debut($titre)
489 {
490 global $auteur_session;
491 include_spip('inc/headers');
492 include_spip('inc/filtres');
493 http_no_cache();
494 lang_select($auteur_session['lang']);
495 return _DOCTYPE_ECRIRE .
496 html_lang_attributes() .
497 "<head>\n<title>" .
498 ('Spip ' . $GLOBALS['spip_version_affichee'] . ' ' .
499 _T('admin_debug') . ' ' . $titre . ' (' .
500 supprimer_tags(extraire_multi($GLOBALS['meta']['nom_site']))) .
501 ")</title>\n" .
502 "<meta http-equiv='Content-Type' content='text/html" .
503 (($c = $GLOBALS['meta']['charset']) ? "; charset=$c" : '') .
504 "' />\n" .
505 "<link rel='stylesheet' href='".url_absolue(find_in_path('spip_admin.css'))
506 . "' type='text/css' />" .
507 "</head>\n<body style='margin:0 10px;'>" .
508 "\n<div id='spip-debug' style='position: absolute; top: 22px; z-index: 1000;height:97%;left:10px;right:10px;'><div id='spip-boucles'>\n";
509 }
510
511 // http://doc.spip.org/@debug_fin
512 function debug_fin()
513 {
514 global $debug_objets;
515
516 echo "\n</div>";
517 include_spip('balise/formulaire_admin');
518 echo inclure_balise_dynamique(
519 balise_FORMULAIRE_ADMIN_dyn('spip-admin-float', $debug_objets)
520 );
521 echo '</body></html>';
522 }
523
524 // http://doc.spip.org/@emboite_texte
525 function emboite_texte($texte, $fonc='',$self='')
526 {
527
528 if (!$texte)
529 return array(ancre_texte($texte, array('','')), false);
530 elseif (!ereg("^[[:space:]]*([^<][^0-9]*)([0-9]*)(.*[^0-9])([0-9]*)$",
531 $GLOBALS['xhtml_error'],
532 $eregs))
533
534 return array(ancre_texte($texte, array('', '')), true);
535 if (!isset($GLOBALS['debug_objets'])) {
536 preg_match_all(",(.*?)(\d+)(\D+(\d+)<br />),",
537 $GLOBALS['xhtml_error'],
538 $regs,
539 PREG_SET_ORDER);
540
541 $err = '<tr><th>'
542 . _T('numero')
543 . "</th><th>"
544 . _T('occurrence')
545 . "</th><th>"
546 . _T('ligne')
547 . "</th><th>"
548 . _T('colonne')
549 . "</th><th>"
550 . _T('erreur')
551 . "</th></tr>";
552
553 $fautifs = array();
554 $i = 0;
555 $encore = array();
556 foreach($regs as $r) {
557 if (isset($encore[$r[1]]))
558 $encore[$r[1]]++;
559 else $encore[$r[1]] = 1;
560 }
561 $encore2 = array();
562 $colors = array('#e0e0f0', '#f8f8ff');
563
564 foreach($regs as $r) {
565 $i++;
566 list(,$msg, $ligne, $fin, $col) = $r;
567 if (isset($encore2[$msg]))
568 $ref = ++$encore2[$msg];
569 else {$encore2[$msg] = $ref = 1;}
570 $err .= "<tr style='background-color: "
571 . $colors[$i%2]
572 . "'><td style='text-align: right'><a href='#debut_err'>"
573 . $i
574 . "</a></td><td style='text-align: right'>"
575 . "$ref/$encore[$msg]</td>"
576 . "<td style='text-align: right'><a href='#L"
577 . $ligne
578 . "' id='T$i'>"
579 . $ligne
580 . "</a></td><td style='text-align: right'>"
581 . $fin
582 . "</td><td>$msg</td></tr>\n";
583 $fautifs[]= array($ligne, $col, $i, $msg);
584 }
585 $err = "<h2 style='text-align: center'>"
586 . $i
587 . "<a href='#fin_err'>"
588 . " "._T('erreur_texte')
589 . "</a></h2><table id='debut_err' style='width: 100%'>"
590 . $err
591 . " </table><a id='fin_err'></a>";
592 return array(ancre_texte($texte, $fautifs), $err);
593 } else {
594 $fermant = $eregs[2];
595 $ouvrant = $eregs[4];
596 $rf = reference_boucle_debug($fermant, $fonc, $self);
597 $ro = reference_boucle_debug($ouvrant, $fonc, $self);
598 $err = $eregs[1] .
599 "<a href='#L" . $eregs[2] . "'>$eregs[2]</a>$rf" .
600 $eregs[3] ."<a href='#L" . $eregs[4] . "'>$eregs[4]</a>$ro";
601 return array(ancre_texte($texte, array(array($ouvrant), array($fermant))), $err);
602 }
603 }
604 ?>