[geany/geany] 9b1890: PHP: add support for "<script language=php>" open and close tags

Colomban Wendling git-noreply at xxxxx
Wed Jul 3 17:26:23 UTC 2013


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Wed, 03 Jul 2013 17:26:23 UTC
Commit:      9b1890b6054b0083860569fb3a066dbf2648b7fa
             https://github.com/geany/geany/commit/9b1890b6054b0083860569fb3a066dbf2648b7fa

Log Message:
-----------
PHP: add support for "<script language=php>" open and close tags

http://www.php.net/manual/en/language.basic-syntax.phptags.php


Modified Paths:
--------------
    tagmanager/ctags/php.c
    tests/ctags/mode.php
    tests/ctags/mode.php.tags

Modified: tagmanager/ctags/php.c
113 files changed, 100 insertions(+), 13 deletions(-)
===================================================================
@@ -668,19 +668,87 @@ static keywordId analyzeToken (vString *const name, langType language)
 	return result;
 }
 
+static int skipWhitespaces (int c)
+{
+	while (c == '\t' || c == ' ' || c == '\n' || c == '\r')
+		c = fileGetc ();
+	return c;
+}
+
+/* <script[:white:]+language[:white:]*=[:white:]*(php|'php'|"php")[:white:]*>
+ * 
+ * This is ugly, but the whole "<script language=php>" tag is and we can't
+ * really do better without adding a lot of code only for this */
+static boolean isOpenScriptLanguagePhp (int c)
+{
+	int quote = 0;
+
+	/* <script[:white:]+language[:white:]*= */
+	if (c                                   != '<' ||
+		tolower ((c = fileGetc ()))         != 's' ||
+		tolower ((c = fileGetc ()))         != 'c' ||
+		tolower ((c = fileGetc ()))         != 'r' ||
+		tolower ((c = fileGetc ()))         != 'i' ||
+		tolower ((c = fileGetc ()))         != 'p' ||
+		tolower ((c = fileGetc ()))         != 't' ||
+		((c = fileGetc ()) != '\t' &&
+		  c                != ' '  &&
+		  c                != '\n' &&
+		  c                != '\r')                ||
+		tolower ((c = skipWhitespaces (c))) != 'l' ||
+		tolower ((c = fileGetc ()))         != 'a' ||
+		tolower ((c = fileGetc ()))         != 'n' ||
+		tolower ((c = fileGetc ()))         != 'g' ||
+		tolower ((c = fileGetc ()))         != 'u' ||
+		tolower ((c = fileGetc ()))         != 'a' ||
+		tolower ((c = fileGetc ()))         != 'g' ||
+		tolower ((c = fileGetc ()))         != 'e' ||
+		(c = skipWhitespaces (fileGetc ())) != '=')
+		return FALSE;
+
+	/* (php|'php'|"php")> */
+	c = skipWhitespaces (fileGetc ());
+	if (c == '"' || c == '\'')
+	{
+		quote = c;
+		c = fileGetc ();
+	}
+	if (tolower (c)                         != 'p' ||
+		tolower ((c = fileGetc ()))         != 'h' ||
+		tolower ((c = fileGetc ()))         != 'p' ||
+		(quote != 0 && (c = fileGetc ()) != quote) ||
+		(c = skipWhitespaces (fileGetc ())) != '>')
+		return FALSE;
+
+	return TRUE;
+}
+
 static int findPhpStart (void)
 {
 	int c;
 	do
 	{
-		if ((c = fileGetc ()) == '<' &&
-			(c = fileGetc ()) == '?' &&
-			/* don't enter PHP mode on "<?xml", yet still support short open tags (<?) */
-			(tolower ((c = fileGetc ())) != 'x' ||
-			 tolower ((c = fileGetc ())) != 'm' ||
-			 tolower ((c = fileGetc ())) != 'l'))
+		if ((c = fileGetc ()) == '<')
 		{
-			break;
+			c = fileGetc ();
+			/* <? and <?php, but not <?xml */
+			if (c == '?')
+			{
+				/* don't enter PHP mode on "<?xml", yet still support short open tags (<?) */
+				if (tolower ((c = fileGetc ())) != 'x' ||
+					tolower ((c = fileGetc ())) != 'm' ||
+					tolower ((c = fileGetc ())) != 'l')
+				{
+					break;
+				}
+			}
+			/* <script language="php"> */
+			else
+			{
+				fileUngetc (c);
+				if (isOpenScriptLanguagePhp ('<'))
+					break;
+			}
 		}
 	}
 	while (c != EOF);
@@ -780,18 +848,37 @@ static void readToken (tokenInfo *const token)
 
 		case '<':
 		{
-			int d;
-			if ((d = fileGetc ()) != '<' ||
-				(d = fileGetc ()) != '<')
+			int d = fileGetc ();
+			if (d == '/')
 			{
-				fileUngetc (d);
-				token->type = TOKEN_UNDEFINED;
+				/* </script[:white:]*> */
+				if (tolower ((d = fileGetc ())) == 's' &&
+					tolower ((d = fileGetc ())) == 'c' &&
+					tolower ((d = fileGetc ())) == 'r' &&
+					tolower ((d = fileGetc ())) == 'i' &&
+					tolower ((d = fileGetc ())) == 'p' &&
+					tolower ((d = fileGetc ())) == 't' &&
+					(d = skipWhitespaces (fileGetc ())) == '>')
+				{
+					InPhp = FALSE;
+					goto getNextChar;
+				}
+				else
+				{
+					fileUngetc (d);
+					token->type = TOKEN_UNDEFINED;
+				}
 			}
-			else
+			else if (d == '<' && (d = fileGetc ()) == '<')
 			{
 				token->type = TOKEN_STRING;
 				parseHeredoc (token->string);
 			}
+			else
+			{
+				fileUngetc (d);
+				token->type = TOKEN_UNDEFINED;
+			}
 			break;
 		}
 


Modified: tests/ctags/mode.php
73 files changed, 73 insertions(+), 0 deletions(-)
===================================================================
@@ -7,6 +7,12 @@ functions:
 	b
 	c
 	d
+	e
+	f
+	g
+	h
+	i
+	j
 
 
 function bug0() {
@@ -50,3 +56,70 @@ function bug5() {
 	}
 	<?php // back to PHP mode, still inside function d()
 }
+
+// any open tag matches any close tag, so this is valid
+</script> // leaves PHP mode
+
+function bug4() {}
+
+?> <!-- just in case -->
+
+<script language="php"> // enetered PHP mode
+
+function e() {
+	return 42;
+}
+
+?> // left PHP mode
+
+function bug5() {}
+
+// some valid long tag opening with inner whitespaces
+
+<script
+	language
+	=
+	php
+> // entered
+function f() {}
+</script
+	> // left
+
+function bug6() {}
+
+<script	language=	'php'	> // enter
+function g() {}
+</script > // leave
+
+function bug7() {}
+
+<?php
+// this WONT leave PHP mode, it's in a comment  </script>
+function h() {}
+?>
+
+function bug8() {}
+
+<?php
+
+function i() {}
+// any open tag matches any close tag, so this is valid
+</script         	  	 
+ 	  	        >
+
+function bug9() {}
+
+// this won't enter PHP, no spaces are allowed between the "<" and "script"
+< script language = php >
+
+function bug10() {}
+
+// does nothing, just resets mode for some tools not aware of the "script" thing
+?>
+
+<!-- <script> is OK anywhere, even in XML strings -->
+<p attr="<script language=php>
+function j() {}
+</script>">
+
+</p>


Modified: tests/ctags/mode.php.tags
6 files changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -3,3 +3,9 @@ a
 b�16�()�0
 c�16�()�0
 d�16�()�0
+e�16�()�0
+f�16�()�0
+g�16�()�0
+h�16�()�0
+i�16�()�0
+j�16�()�0



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list