From 931afbfe3b5c0fb88e925aac9a79e6495c4445ed Mon Sep 17 00:00:00 2001
From: "Committo,Ergo:sum" <esj@rezo.net>
Date: Fri, 1 Jul 2005 16:12:31 +0000
Subject: [PATCH] =?UTF-8?q?meilleur=20param=C3=A9trage=20des=20entites=20l?=
 =?UTF-8?q?exicales=20du=20phraseur?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ecrire/inc_debug_sql.php3 |  16 ++++-
 inc-html-squel.php3       | 136 ++++++++++++++++++++++----------------
 2 files changed, 91 insertions(+), 61 deletions(-)

diff --git a/ecrire/inc_debug_sql.php3 b/ecrire/inc_debug_sql.php3
index e65ad6792a..91ea0c02ec 100644
--- a/ecrire/inc_debug_sql.php3
+++ b/ecrire/inc_debug_sql.php3
@@ -194,12 +194,20 @@ function squelette_debug_compile($nom, $sourcefile, $code, $squelette) {
 }
 
 // appelee a chaque analyse syntaxique de squelette (inc-parser)
-function boucle_debug ($id, $nom, $boucle, $id_parent) {
+function boucle_debug ($nom, $id_parent, $id, $type, $crit, $avant, $milieu, $apres, $altern) {
 	global $debug_objets;
 
 	$debug_objets['courant'] = $nom;
-	$debug_objets['boucle'][$nom.$id] = $boucle;
 	$debug_objets['parent'][$nom.$id] = $id_parent;
+	// on synthetise avec la syntaxe standard, mais "<//" pose pb 
+	$debug_objets['boucle'][$nom.$id] = 
+	  "<B$id>" .
+	  $avant . "<BOUCLE$id($type)" . $crit .
+	  '>' .
+	  $milieu .
+	  "</BOUCLE$id>" .
+	  $apres . "</B$id>" .
+	  $altern . '<//B' . $id . ">";
 }
 
 function trouve_boucle_debug($n, $nom, $debut=0, $boucle = "")
@@ -317,7 +325,9 @@ function debug_dumpfile ($texte, $fonc, $type) {
 	ob_end_clean();
 
 	@header('Content-Type: text/html; charset='.lire_meta('charset'));
-	echo debut_entete('Spip ' . _T('admin_debug')), 
+	echo debut_entete('Spip ' . $GLOBALS['spip_version_affichee'] . ' ' .
+			  _T('admin_debug') . ' ' .
+			  _T('info_mon_site_spip')), 
 	  "<link rel='stylesheet' href='spip_admin.css' type='text/css'>",
 	  "</head>\n<body style='margin:0 10px;'>",
 	  "\n<div id='spip-debug' style='position: absolute; top: 22px; z-index: 1000;height:97%;left:10px;right:10px;'><div id='spip-boucles'>\n"; 
diff --git a/inc-html-squel.php3 b/inc-html-squel.php3
index d017dc2685..0dd84265a2 100644
--- a/inc-html-squel.php3
+++ b/inc-html-squel.php3
@@ -20,21 +20,20 @@ define("_INC_HTML_SQUEL", "1");
 # il est charge par un include calcule dans inc-calcul-squel
 # pour permettre differentes syntaxes en entree
 
+define('BALISE_BOUCLE', '<BOUCLE');
+define('BALISE_FIN_BOUCLE', '</BOUCLE');
+define('BALISE_PRE_BOUCLE', '<B');
+define('BALISE_POST_BOUCLE', '</B');
+define('BALISE_ALT_BOUCLE', '<//B');
+
+define('TYPE_RECURSIF', 'boucle');
+define('SPEC_BOUCLE','[[:space:]]*\(([^)]*)\)');
 define('NOM_DE_BOUCLE', "[0-9]+|[-_][-_.a-zA-Z0-9]*");
 # ecriture alambiquee pour rester compatible avec les hexadecimaux des vieux squelettes
 define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*?)");
 define('CHAMP_ETENDU', '\[([^]\[]*)\(' . NOM_DE_CHAMP . '([^[)]*\)[^]\[]*)\]');
-define('PARAM_DE_BOUCLE','[[:space:]]*[{][[:space:]]*([^{}]*([{][^[}]]*[}][^[}]]*)*)[[:space:]]*[}]');
-define('TYPE_DE_BOUCLE', "[^)]*");
-define('BALISE_DE_BOUCLE',
-	"^<BOUCLE(" .
-	NOM_DE_BOUCLE .
-	')[[:space:]]*\((' .
-	TYPE_DE_BOUCLE .
-	')\)');
-define('PARAM_INCLURE','^[[:space:]]*[{][[:space:]]*([_0-9a-zA-Z]+)[[:space:]]*(=)?');
+
 define('BALISE_INCLURE','<INCLU[DR]E[[:space:]]*\(([^)]*)\)');
-define('DEBUT_DE_BOUCLE','/<B('.NOM_DE_BOUCLE.')>.*?<BOUCLE\1[^-_.a-zA-Z0-9]|<BOUCLE('.NOM_DE_BOUCLE.')/ms');	# preg
 
 function phraser_inclure($texte, $ligne, $result) {
 
@@ -412,9 +411,10 @@ function phraser_criteres($params, &$result) {
 			    $crit->not = $m[1];
 			    $crit->cond = $m[3];
 			  }
-			  else 
+			  else {spip_log("pb $param");
 			    erreur_squelette(_T('zbug_critere_inconnu',
 						array('critere' => $param)));
+			  }
 			  $args[] = $crit;
 			}
 		  }
@@ -442,85 +442,94 @@ function phraser($texte, $id_parent, &$boucles, $nom, $ligne=1) {
 
 	$all_res = array();
 
-	while (preg_match(DEBUT_DE_BOUCLE, $texte, $regs)) {
-		$nom_boucle = $regs[1].$regs[2];
-		$p = strpos($texte, '<BOUCLE'.$nom_boucle);
+	while (($p = strpos($texte, BALISE_BOUCLE)) !== false) {
 
-		// envoyer la boucle au debugueur
-		if ($GLOBALS['var_mode']== 'debug') {
-			$preg = "@<B($nom_boucle|OUCLE${nom_boucle}[^-_.a-zA-Z0-9][^>]*)>"
-				. ".*</(BOUCLE|/?B)$nom_boucle>@ms";
-			preg_match($preg, $texte, $match);
-			boucle_debug ($nom_boucle, $nom, $match[0], $id_parent);
-		}
-
-		//
-		// Recuperer la partie principale de la boucle
-		//
-		$debut = substr($texte, 0, $p);
-		$milieu = substr($texte, $p);
-		if (!ereg(BALISE_DE_BOUCLE, $milieu, $match)) {
-			erreur_squelette((_T('zbug_erreur_boucle_syntaxe')), $milieu);
-		}
-		$milieu = substr($milieu, strlen($match[0]));
-		$id_boucle = $match[1];
 		$result = new Boucle;
 		$result->id_parent = $id_parent;
+
+# attention: reperer la premiere des 2 balises: pre_boucle ou boucle
+# $n == $p possible car <B est un prefixe de <BOUCLE
+		$n = strpos($texte, BALISE_PRE_BOUCLE);
+
+		if ($n === false || ($n >= $p)) {
+		  $debut = substr($texte, 0, $p);
+		  $milieu = substr($texte, $p);
+		  $k = strpos($milieu, '(');
+		  $id_boucle = substr($milieu,
+				       strlen(BALISE_BOUCLE),
+				       $k - strlen(BALISE_BOUCLE));
+		  $milieu = substr($milieu, $k);
+
+		  /* a adapter: si $n pointe sur $id_boucle ...
+		if (strpos($milieu, $s)) {
+			erreur_squelette(_T('zbug_erreur_boucle_syntaxe'),
+				$id_boucle . 
+				_T('zbug_balise_b_aval'));
+		}
+		  */
+		} else {
+		  $debut = substr($texte, 0, $n);
+		  $milieu = substr($texte, $n);
+		  $k = strpos($milieu, '>');
+		  $id_boucle = substr($milieu,
+				       strlen(BALISE_PRE_BOUCLE),
+				       $k - strlen(BALISE_PRE_BOUCLE));
+
+		  if (!($p = strpos($milieu, BALISE_BOUCLE . $id_boucle . "(")))
+		    erreur_squelette((_T('zbug_erreur_boucle_syntaxe')), $id_boucle);
+		  $result->avant = substr($milieu, $k+1, $p-$k-1);
+		  $milieu = substr($milieu, $p+strlen($id_boucle)+strlen(BALISE_BOUCLE));
+		}
 		$result->id_boucle = $id_boucle;
-		$type = $match[2];
+
+		ereg(SPEC_BOUCLE, $milieu, $match);
+                $milieu = substr($milieu, strlen($match[0]));
+		$type = $match[1];
+
 		if ($p = strpos($type, ':'))
 		  {
 		    $result->sql_serveur = substr($type,0,$p);
-		    $type = substr($type,$p+1);
+		    $soustype = strtolower(substr($type,$p+1));
 		  }
-		$type = strtolower($type);
-		if ($type == 'sites') $type = 'syndication'; # alias
+		else
+		  $soustype = strtolower($type);
 
+		if ($soustype == 'sites') $soustype = 'syndication' ; # alias
+		      
 		//
-		// Recuperer les criteres de la boucle (sauf boucle recursive)
+		// analyser les criteres et distinguer la boucle recursive
 		//
-		if (substr($type, 0, 6) == 'boucle') {
-			$result->type_requete = 'boucle';
-			$result->param[0] = substr($match[2], 6);
+		if (substr($soustype, 0, 6) == TYPE_RECURSIF) {
+			$result->type_requete = TYPE_RECURSIF;
+			$result->param[0] = substr($soustype, strlen(TYPE_RECURSIF));
 			$milieu = substr($milieu, strpos($milieu, '>'));
+			$params = "";
 		} else {
-			$result->type_requete = $type;
+			$result->type_requete = $soustype;
 			phraser_args($milieu,">","",$all_res,$result);
+			$params = substr($milieu,0,strpos($milieu,$result->apres));
 			$milieu = substr($result->apres,1);
 			$result->apres = "";
 			phraser_criteres($result->param, $result);
 		}
-		//
-		// Recuperer la partie conditionnelle avant
-		//
-		$s = "<B$id_boucle>";
-		$p = strpos($debut, $s);
-		if ($p !== false) {
-			$result->avant = substr($debut, $p + strlen($s));
-			$debut = substr($debut, 0, $p);
-		}
-		if (strpos($milieu, $s)) {
-			erreur_squelette(_T('zbug_erreur_boucle_syntaxe'),
-				$id_boucle . 
-				_T('zbug_balise_b_aval'));
-		}
 
 		//
 		// Recuperer la fin :
 		//
-		$s = "</BOUCLE$id_boucle>";
+		$s = BALISE_FIN_BOUCLE . $id_boucle . ">";
 		$p = strpos($milieu, $s);
 		if ($p === false) {
 			erreur_squelette(_T('zbug_erreur_boucle_syntaxe'),
 					 _T('zbug_erreur_boucle_fermant',
 						array('id'=>$id_boucle)));
 		}
+
 		$suite = substr($milieu, $p + strlen($s));
 		$milieu = substr($milieu, 0, $p);
 		//
 		// 1. Recuperer la partie conditionnelle apres
 		//
-		$s = "</B$id_boucle>";
+		$s = BALISE_POST_BOUCLE . $id_boucle . ">";
 		$p = strpos($suite, $s);
 		if ($p !== false) {
 			$result->apres = substr($suite, 0, $p);
@@ -530,7 +539,7 @@ function phraser($texte, $id_parent, &$boucles, $nom, $ligne=1) {
 		//
 		// 2. Recuperer la partie alternative
 		//
-		$s = "<//B$id_boucle>";
+		$s = BALISE_ALT_BOUCLE . $id_boucle . ">";
 		$p = strpos($suite, $s);
 		if ($p !== false) {
 			$result->altern = substr($suite, 0, $p);
@@ -541,6 +550,17 @@ function phraser($texte, $id_parent, &$boucles, $nom, $ligne=1) {
 		$b = substr_count($result->avant, "\n");
 		$a = substr_count($result->apres, "\n");
 
+		// envoyer la boucle au debugueur
+		if ($GLOBALS['var_mode']== 'debug') {
+		  boucle_debug ($nom, $id_parent, $id_boucle, 
+				$type,
+				$params,
+				$result->avant,
+				$milieu,
+				$result->apres,
+				$result->altern);
+		}
+
 		$result->avant = phraser($result->avant, $id_parent,$boucles, $nom, $result->ligne);
 		$result->apres = phraser($result->apres, $id_parent,$boucles, $nom, $result->ligne+$b+$m);
 		$result->altern = phraser($result->altern,$id_parent,$boucles, $nom, $result->ligne+$a+$m+$b);
-- 
GitLab