Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Wed, 03 Jul 2013 17:26:23 UTC Commit: 9b1890b6054b0083860569fb3a066dbf2648b7fa https://github.com/geany/geany/commit/9b1890b6054b0083860569fb3a066dbf2648b7...
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).