lists.geany.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
List overview
Commits
December 2014
----- 2025 -----
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
commits@lists.geany.org
1 participants
26 discussions
Start a n
N
ew thread
[geany/geany] 018408: Fix an assertion failure when trying to scope-complete in a 2-characters C++ file
by Colomban Wendling
04 Dec '14
04 Dec '14
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Thu, 04 Dec 2014 13:38:57 UTC Commit: 0184083a7e1216169d0879d66b67799e9bf638c9
https://github.com/geany/geany/commit/0184083a7e1216169d0879d66b67799e9bf63…
Log Message: ----------- Fix an assertion failure when trying to scope-complete in a 2-characters C++ file Modified Paths: -------------- src/editor.c Modified: src/editor.c 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -709,9 +709,9 @@ static void autocomplete_scope(GeanyEditor *editor) if (ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP) { - if (match_last_chars(sci, pos, "->") || match_last_chars(sci, pos, "::")) + if (pos >= 2 && (match_last_chars(sci, pos, "->") || match_last_chars(sci, pos, "::"))) pos--; - else if (ft->id == GEANY_FILETYPES_CPP && match_last_chars(sci, pos, "->*")) + else if (ft->id == GEANY_FILETYPES_CPP && pos >= 3 && match_last_chars(sci, pos, "->*")) pos-=2; else if (typed != '.') return; -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] f08af8: Merge branch 'js-update'
by Colomban Wendling
02 Dec '14
02 Dec '14
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 02 Dec 2014 14:03:20 UTC Commit: f08af8046f8cbbd7d48fc767155d1fe805c1c45d
https://github.com/geany/geany/commit/f08af8046f8cbbd7d48fc767155d1fe805c1c…
Log Message: ----------- Merge branch 'js-update' Import back JavaScript parser changes from fishman/ctags. Modified Paths: -------------- tagmanager/ctags/js.c tests/ctags/Makefile.am tests/ctags/js-broken-strings.js tests/ctags/js-broken-strings.js.tags tests/ctags/js-string-continuation.js tests/ctags/js-string-continuation.js.tags Modified: tagmanager/ctags/js.c 102 lines changed, 51 insertions(+), 51 deletions(-) =================================================================== @@ -19,7 +19,6 @@ #include "general.h" /* must always come first */ #include <ctype.h> /* to define isalpha () */ #include <string.h> -#include <setjmp.h> #include <mio/mio.h> #ifdef DEBUG #include <stdio.h> @@ -41,8 +40,6 @@ * DATA DECLARATIONS */ -typedef enum eException { ExceptionNone, ExceptionEOF } exception_t; - /* * Tracks class and function names already created */ @@ -85,6 +82,7 @@ typedef struct sKeywordDesc { typedef enum eTokenType { TOKEN_UNDEFINED, + TOKEN_EOF, TOKEN_CHARACTER, TOKEN_CLOSE_PAREN, TOKEN_SEMICOLON, @@ -126,8 +124,6 @@ static tokenType LastTokenType; static langType Lang_js; -static jmp_buf Exception; - typedef enum { JSTAG_FUNCTION, JSTAG_CLASS, @@ -364,11 +360,32 @@ static void parseString (vString *const string, const int delimiter) end = TRUE; else if (c == '\\') { - c = fileGetc(); /* This maybe a ' or ". */ - vStringPut(string, c); + /* Eat the escape sequence (\", \', etc). We properly handle + * <LineContinuation> by eating a whole \<CR><LF> not to see <LF> + * as an unescaped character, which is invalid and handled below. + * Also, handle the fact that <LineContinuation> produces an empty + * sequence. + * See ECMA-262 7.8.4 */ + c = fileGetc(); + if (c != '\r' && c != '\n') + vStringPut(string, c); + else if (c == '\r') + { + c = fileGetc(); + if (c != '\n') + fileUngetc (c); + } } else if (c == delimiter) end = TRUE; + else if (c == '\r' || c == '\n') + { + /* those are invalid when not escaped */ + end = TRUE; + /* we don't want to eat the newline itself to let the automatic + * semicolon insertion code kick in */ + fileUngetc (c); + } else vStringPut (string, c); } @@ -458,7 +475,7 @@ static void readTokenFull (tokenInfo *const token, boolean include_newlines, vSt switch (c) { - case EOF: longjmp (Exception, (int)ExceptionEOF); break; + case EOF: token->type = TOKEN_EOF; break; case '(': token->type = TOKEN_OPEN_PAREN; break; case ')': token->type = TOKEN_CLOSE_PAREN; break; case ';': token->type = TOKEN_SEMICOLON; break; @@ -669,32 +686,18 @@ static void skipArgumentList (tokenInfo *const token, boolean include_newlines, { int nest_level = 0; - /* - * Other databases can have arguments with fully declared - * datatypes: - * ( name varchar(30), text binary(10) ) - * So we must check for nested open and closing parantheses - */ - if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */ { nest_level++; if (repr) vStringPut (repr, '('); - while (! (isType (token, TOKEN_CLOSE_PAREN) && (nest_level == 0))) + while (nest_level > 0 && ! isType (token, TOKEN_EOF)) { readTokenFull (token, FALSE, repr); if (isType (token, TOKEN_OPEN_PAREN)) - { nest_level++; - } - if (isType (token, TOKEN_CLOSE_PAREN)) - { - if (nest_level > 0) - { - nest_level--; - } - } + else if (isType (token, TOKEN_CLOSE_PAREN)) + nest_level--; } readTokenFull (token, include_newlines, NULL); } @@ -713,20 +716,13 @@ static void skipArrayList (tokenInfo *const token, boolean include_newlines) if (isType (token, TOKEN_OPEN_SQUARE)) /* arguments? */ { nest_level++; - while (! (isType (token, TOKEN_CLOSE_SQUARE) && (nest_level == 0))) + while (nest_level > 0 && ! isType (token, TOKEN_EOF)) { readToken (token); if (isType (token, TOKEN_OPEN_SQUARE)) - { nest_level++; - } - if (isType (token, TOKEN_CLOSE_SQUARE)) - { - if (nest_level > 0) - { - nest_level--; - } - } + else if (isType (token, TOKEN_CLOSE_SQUARE)) + nest_level--; } readTokenFull (token, include_newlines, NULL); } @@ -762,8 +758,9 @@ static boolean findCmdTerm (tokenInfo *const token, boolean include_newlines) * Read until we find either a semicolon or closing brace. * Any nested braces will be handled within. */ - while (! ( isType (token, TOKEN_SEMICOLON) || - isType (token, TOKEN_CLOSE_CURLY) ) ) + while (! isType (token, TOKEN_SEMICOLON) && + ! isType (token, TOKEN_CLOSE_CURLY) && + ! isType (token, TOKEN_EOF)) { /* Handle nested blocks */ if ( isType (token, TOKEN_OPEN_CURLY)) @@ -1132,7 +1129,8 @@ static boolean parseBlock (tokenInfo *const token, tokenInfo *const orig_parent) * If we find a statement without a terminator consider the * block finished, otherwise the stack will be off by one. */ - } while (! isType (token, TOKEN_CLOSE_CURLY) && read_next_token ); + } while (! isType (token, TOKEN_EOF) && + ! isType (token, TOKEN_CLOSE_CURLY) && read_next_token); } deleteToken (parent); @@ -1209,7 +1207,8 @@ static boolean parseMethods (tokenInfo *const token, tokenInfo *const class) /* skip whatever is the value */ while (! isType (token, TOKEN_COMMA) && - ! isType (token, TOKEN_CLOSE_CURLY)) + ! isType (token, TOKEN_CLOSE_CURLY) && + ! isType (token, TOKEN_EOF)) { if (isType (token, TOKEN_OPEN_CURLY)) { @@ -1329,7 +1328,8 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent, while (! isType (token, TOKEN_CLOSE_CURLY) && ! isType (token, TOKEN_SEMICOLON) && - ! isType (token, TOKEN_EQUAL_SIGN) ) + ! isType (token, TOKEN_EQUAL_SIGN) && + ! isType (token, TOKEN_EOF)) { if (isType (token, TOKEN_OPEN_CURLY)) parseBlock (token, parent); @@ -1403,9 +1403,10 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent, readToken (method_body_token); vStringCopy (method_body_token->scope, token->scope); - while (! ( isType (method_body_token, TOKEN_SEMICOLON) || - isType (method_body_token, TOKEN_CLOSE_CURLY) || - isType (method_body_token, TOKEN_OPEN_CURLY)) ) + while (! isType (method_body_token, TOKEN_SEMICOLON) && + ! isType (method_body_token, TOKEN_CLOSE_CURLY) && + ! isType (method_body_token, TOKEN_OPEN_CURLY) && + ! isType (method_body_token, TOKEN_EOF)) { if ( isType (method_body_token, TOKEN_OPEN_PAREN) ) skipArgumentList(method_body_token, FALSE, @@ -1728,7 +1729,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent, if (parenDepth > 0) { - while (parenDepth > 0) + while (parenDepth > 0 && ! isType (token, TOKEN_EOF)) { if (isType (token, TOKEN_OPEN_PAREN)) parenDepth++; @@ -1795,7 +1796,8 @@ static void parseUI5 (tokenInfo *const token) if (isType (token, TOKEN_PERIOD)) { readToken (token); - while (! isType (token, TOKEN_OPEN_PAREN) ) + while (! isType (token, TOKEN_OPEN_PAREN) && + ! isType (token, TOKEN_EOF)) { readToken (token); } @@ -1813,7 +1815,8 @@ static void parseUI5 (tokenInfo *const token) do { parseMethods (token, name); - } while (! isType (token, TOKEN_CLOSE_CURLY) ); + } while (! isType (token, TOKEN_CLOSE_CURLY) && + ! isType (token, TOKEN_EOF)); } deleteToken (name); @@ -1884,7 +1887,7 @@ static void parseJsFile (tokenInfo *const token) parseUI5 (token); else parseLine (token, token, FALSE); - } while (TRUE); + } while (! isType (token, TOKEN_EOF)); } static void initialize (const langType language) @@ -1897,15 +1900,12 @@ static void initialize (const langType language) static void findJsTags (void) { tokenInfo *const token = newToken (); - exception_t exception; ClassNames = stringListNew (); FunctionNames = stringListNew (); LastTokenType = TOKEN_UNDEFINED; - exception = (exception_t) (setjmp (Exception)); - while (exception == ExceptionNone) - parseJsFile (token); + parseJsFile (token); stringListDelete (ClassNames); stringListDelete (FunctionNames); Modified: tests/ctags/Makefile.am 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -159,12 +159,14 @@ test_sources = \ intro.tex \ invalid_name.f90 \ java_enum.java \ + js-broken-strings.js \ js-class-related-unterminated.js \ js-const.js \ js-implicit-semicolons.js \ js-let.js \ js-scope.js \ js-signature.js \ + js-string-continuation.js \ js-sub-block-scope.js \ js-unknown-construct-nesting.js \ jsFunc_tutorial.js \ Modified: tests/ctags/js-broken-strings.js 10 lines changed, 10 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,10 @@ +// this file willfully uses CR-LF line endings to check their handling + +var s1 = "I'm invalid because not terminated + +var s2 = "I'm valid, I have a line continuation:\ +; function bug1(){}"; + +var s3 = "I'm invalid because I'm not terminated either \ +var bug2 = 'this is inside the s3 string' +var s4 = 'this is a separate, valid string' Modified: tests/ctags/js-broken-strings.js.tags 5 lines changed, 5 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,5 @@ +# format=tagmanager +s1�16384�0 +s2�16384�0 +s3�16384�0 +s4�16384�0 Modified: tests/ctags/js-string-continuation.js 19 lines changed, 19 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,19 @@ + +var o = { + "first": function(){}, + "sec\ +ond": function(){}, + "\ +t\ +h\ +i\ +r\ +d\ +": function(){}, + "fourth": function(){}, +}; + +o.first(); +o.second(); +o.third(); +o.fourth(); Modified: tests/ctags/js-string-continuation.js.tags 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,6 @@ +# format=tagmanager +first�128�()�o�0 +fourth�128�()�o�0 +o�16384�0 +second�128�()�o�0 +third�128�()�o�0 -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 02bc3b: javascript: Improve string literals handling
by Colomban Wendling
02 Dec '14
02 Dec '14
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 02 Dec 2014 14:02:39 UTC Commit: 02bc3b36387671061ed61dba4cdd31f843c44ed3
https://github.com/geany/geany/commit/02bc3b36387671061ed61dba4cdd31f843c44…
Log Message: ----------- javascript: Improve string literals handling 1. Don't include the newline itself in a line continuation construct. This fixes generation of e.g. properties with embedded line continuations. 2. Don't continue parsing strings past an unescaped newline (as naked newlines are invalid inside strings). This avoids parsing the whole remaining file as a string in case of broken input. It is both useful to better support partly written files and to avoid loading a whole malformed file in memory while reading it as a string. See section 7.8.4 "String Literals" of ECMA-262:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
Modified Paths: -------------- tagmanager/ctags/js.c tests/ctags/Makefile.am tests/ctags/js-broken-strings.js tests/ctags/js-broken-strings.js.tags tests/ctags/js-string-continuation.js tests/ctags/js-string-continuation.js.tags Modified: tagmanager/ctags/js.c 25 lines changed, 23 insertions(+), 2 deletions(-) =================================================================== @@ -360,11 +360,32 @@ static void parseString (vString *const string, const int delimiter) end = TRUE; else if (c == '\\') { - c = fileGetc(); /* This maybe a ' or ". */ - vStringPut(string, c); + /* Eat the escape sequence (\", \', etc). We properly handle + * <LineContinuation> by eating a whole \<CR><LF> not to see <LF> + * as an unescaped character, which is invalid and handled below. + * Also, handle the fact that <LineContinuation> produces an empty + * sequence. + * See ECMA-262 7.8.4 */ + c = fileGetc(); + if (c != '\r' && c != '\n') + vStringPut(string, c); + else if (c == '\r') + { + c = fileGetc(); + if (c != '\n') + fileUngetc (c); + } } else if (c == delimiter) end = TRUE; + else if (c == '\r' || c == '\n') + { + /* those are invalid when not escaped */ + end = TRUE; + /* we don't want to eat the newline itself to let the automatic + * semicolon insertion code kick in */ + fileUngetc (c); + } else vStringPut (string, c); } Modified: tests/ctags/Makefile.am 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -159,12 +159,14 @@ test_sources = \ intro.tex \ invalid_name.f90 \ java_enum.java \ + js-broken-strings.js \ js-class-related-unterminated.js \ js-const.js \ js-implicit-semicolons.js \ js-let.js \ js-scope.js \ js-signature.js \ + js-string-continuation.js \ js-sub-block-scope.js \ js-unknown-construct-nesting.js \ jsFunc_tutorial.js \ Modified: tests/ctags/js-broken-strings.js 10 lines changed, 10 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,10 @@ +// this file willfully uses CR-LF line endings to check their handling + +var s1 = "I'm invalid because not terminated + +var s2 = "I'm valid, I have a line continuation:\ +; function bug1(){}"; + +var s3 = "I'm invalid because I'm not terminated either \ +var bug2 = 'this is inside the s3 string' +var s4 = 'this is a separate, valid string' Modified: tests/ctags/js-broken-strings.js.tags 5 lines changed, 5 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,5 @@ +# format=tagmanager +s1�16384�0 +s2�16384�0 +s3�16384�0 +s4�16384�0 Modified: tests/ctags/js-string-continuation.js 19 lines changed, 19 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,19 @@ + +var o = { + "first": function(){}, + "sec\ +ond": function(){}, + "\ +t\ +h\ +i\ +r\ +d\ +": function(){}, + "fourth": function(){}, +}; + +o.first(); +o.second(); +o.third(); +o.fourth(); Modified: tests/ctags/js-string-continuation.js.tags 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,6 @@ +# format=tagmanager +first�128�()�o�0 +fourth�128�()�o�0 +o�16384�0 +second�128�()�o�0 +third�128�()�o�0 -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 69a15c: javascript: Stop using longjmp() and friends
by Colomban Wendling
02 Dec '14
02 Dec '14
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 02 Dec 2014 14:02:13 UTC Commit: 69a15cf2c1c8def91ffd7bc51ca8a1bfd2df563d
https://github.com/geany/geany/commit/69a15cf2c1c8def91ffd7bc51ca8a1bfd2df5…
Log Message: ----------- javascript: Stop using longjmp() and friends Fixes some memory leaks with malformed or partial files. Modified Paths: -------------- tagmanager/ctags/js.c Modified: tagmanager/ctags/js.c 77 lines changed, 28 insertions(+), 49 deletions(-) =================================================================== @@ -19,7 +19,6 @@ #include "general.h" /* must always come first */ #include <ctype.h> /* to define isalpha () */ #include <string.h> -#include <setjmp.h> #include <mio/mio.h> #ifdef DEBUG #include <stdio.h> @@ -41,8 +40,6 @@ * DATA DECLARATIONS */ -typedef enum eException { ExceptionNone, ExceptionEOF } exception_t; - /* * Tracks class and function names already created */ @@ -85,6 +82,7 @@ typedef struct sKeywordDesc { typedef enum eTokenType { TOKEN_UNDEFINED, + TOKEN_EOF, TOKEN_CHARACTER, TOKEN_CLOSE_PAREN, TOKEN_SEMICOLON, @@ -126,8 +124,6 @@ static tokenType LastTokenType; static langType Lang_js; -static jmp_buf Exception; - typedef enum { JSTAG_FUNCTION, JSTAG_CLASS, @@ -458,7 +454,7 @@ static void readTokenFull (tokenInfo *const token, boolean include_newlines, vSt switch (c) { - case EOF: longjmp (Exception, (int)ExceptionEOF); break; + case EOF: token->type = TOKEN_EOF; break; case '(': token->type = TOKEN_OPEN_PAREN; break; case ')': token->type = TOKEN_CLOSE_PAREN; break; case ';': token->type = TOKEN_SEMICOLON; break; @@ -669,32 +665,18 @@ static void skipArgumentList (tokenInfo *const token, boolean include_newlines, { int nest_level = 0; - /* - * Other databases can have arguments with fully declared - * datatypes: - * ( name varchar(30), text binary(10) ) - * So we must check for nested open and closing parantheses - */ - if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */ { nest_level++; if (repr) vStringPut (repr, '('); - while (! (isType (token, TOKEN_CLOSE_PAREN) && (nest_level == 0))) + while (nest_level > 0 && ! isType (token, TOKEN_EOF)) { readTokenFull (token, FALSE, repr); if (isType (token, TOKEN_OPEN_PAREN)) - { nest_level++; - } - if (isType (token, TOKEN_CLOSE_PAREN)) - { - if (nest_level > 0) - { - nest_level--; - } - } + else if (isType (token, TOKEN_CLOSE_PAREN)) + nest_level--; } readTokenFull (token, include_newlines, NULL); } @@ -713,20 +695,13 @@ static void skipArrayList (tokenInfo *const token, boolean include_newlines) if (isType (token, TOKEN_OPEN_SQUARE)) /* arguments? */ { nest_level++; - while (! (isType (token, TOKEN_CLOSE_SQUARE) && (nest_level == 0))) + while (nest_level > 0 && ! isType (token, TOKEN_EOF)) { readToken (token); if (isType (token, TOKEN_OPEN_SQUARE)) - { nest_level++; - } - if (isType (token, TOKEN_CLOSE_SQUARE)) - { - if (nest_level > 0) - { - nest_level--; - } - } + else if (isType (token, TOKEN_CLOSE_SQUARE)) + nest_level--; } readTokenFull (token, include_newlines, NULL); } @@ -762,8 +737,9 @@ static boolean findCmdTerm (tokenInfo *const token, boolean include_newlines) * Read until we find either a semicolon or closing brace. * Any nested braces will be handled within. */ - while (! ( isType (token, TOKEN_SEMICOLON) || - isType (token, TOKEN_CLOSE_CURLY) ) ) + while (! isType (token, TOKEN_SEMICOLON) && + ! isType (token, TOKEN_CLOSE_CURLY) && + ! isType (token, TOKEN_EOF)) { /* Handle nested blocks */ if ( isType (token, TOKEN_OPEN_CURLY)) @@ -1132,7 +1108,8 @@ static boolean parseBlock (tokenInfo *const token, tokenInfo *const orig_parent) * If we find a statement without a terminator consider the * block finished, otherwise the stack will be off by one. */ - } while (! isType (token, TOKEN_CLOSE_CURLY) && read_next_token ); + } while (! isType (token, TOKEN_EOF) && + ! isType (token, TOKEN_CLOSE_CURLY) && read_next_token); } deleteToken (parent); @@ -1209,7 +1186,8 @@ static boolean parseMethods (tokenInfo *const token, tokenInfo *const class) /* skip whatever is the value */ while (! isType (token, TOKEN_COMMA) && - ! isType (token, TOKEN_CLOSE_CURLY)) + ! isType (token, TOKEN_CLOSE_CURLY) && + ! isType (token, TOKEN_EOF)) { if (isType (token, TOKEN_OPEN_CURLY)) { @@ -1329,7 +1307,8 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent, while (! isType (token, TOKEN_CLOSE_CURLY) && ! isType (token, TOKEN_SEMICOLON) && - ! isType (token, TOKEN_EQUAL_SIGN) ) + ! isType (token, TOKEN_EQUAL_SIGN) && + ! isType (token, TOKEN_EOF)) { if (isType (token, TOKEN_OPEN_CURLY)) parseBlock (token, parent); @@ -1403,9 +1382,10 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent, readToken (method_body_token); vStringCopy (method_body_token->scope, token->scope); - while (! ( isType (method_body_token, TOKEN_SEMICOLON) || - isType (method_body_token, TOKEN_CLOSE_CURLY) || - isType (method_body_token, TOKEN_OPEN_CURLY)) ) + while (! isType (method_body_token, TOKEN_SEMICOLON) && + ! isType (method_body_token, TOKEN_CLOSE_CURLY) && + ! isType (method_body_token, TOKEN_OPEN_CURLY) && + ! isType (method_body_token, TOKEN_EOF)) { if ( isType (method_body_token, TOKEN_OPEN_PAREN) ) skipArgumentList(method_body_token, FALSE, @@ -1728,7 +1708,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent, if (parenDepth > 0) { - while (parenDepth > 0) + while (parenDepth > 0 && ! isType (token, TOKEN_EOF)) { if (isType (token, TOKEN_OPEN_PAREN)) parenDepth++; @@ -1795,7 +1775,8 @@ static void parseUI5 (tokenInfo *const token) if (isType (token, TOKEN_PERIOD)) { readToken (token); - while (! isType (token, TOKEN_OPEN_PAREN) ) + while (! isType (token, TOKEN_OPEN_PAREN) && + ! isType (token, TOKEN_EOF)) { readToken (token); } @@ -1813,7 +1794,8 @@ static void parseUI5 (tokenInfo *const token) do { parseMethods (token, name); - } while (! isType (token, TOKEN_CLOSE_CURLY) ); + } while (! isType (token, TOKEN_CLOSE_CURLY) && + ! isType (token, TOKEN_EOF)); } deleteToken (name); @@ -1884,7 +1866,7 @@ static void parseJsFile (tokenInfo *const token) parseUI5 (token); else parseLine (token, token, FALSE); - } while (TRUE); + } while (! isType (token, TOKEN_EOF)); } static void initialize (const langType language) @@ -1897,15 +1879,12 @@ static void initialize (const langType language) static void findJsTags (void) { tokenInfo *const token = newToken (); - exception_t exception; ClassNames = stringListNew (); FunctionNames = stringListNew (); LastTokenType = TOKEN_UNDEFINED; - exception = (exception_t) (setjmp (Exception)); - while (exception == ExceptionNone) - parseJsFile (token); + parseJsFile (token); stringListDelete (ClassNames); stringListDelete (FunctionNames); -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 0a58f5: Update Scintilla to version 3.5.2
by Colomban Wendling
02 Dec '14
02 Dec '14
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 02 Dec 2014 12:51:18 UTC Commit: 0a58f5012ba8e379f92c2f6751b16b9bea363db6
https://github.com/geany/geany/commit/0a58f5012ba8e379f92c2f6751b16b9bea363…
Log Message: ----------- Update Scintilla to version 3.5.2 Modified Paths: -------------- scintilla/gtk/PlatGTK.cxx scintilla/gtk/ScintillaGTK.cxx scintilla/include/Scintilla.h scintilla/include/Scintilla.iface scintilla/lexers/LexCoffeeScript.cxx scintilla/lexers/LexVHDL.cxx scintilla/src/Catalogue.cxx scintilla/src/CellBuffer.cxx scintilla/src/Decoration.cxx scintilla/src/Document.cxx scintilla/src/Document.h scintilla/src/EditModel.cxx scintilla/src/EditView.cxx scintilla/src/EditView.h scintilla/src/Editor.cxx scintilla/src/Editor.h scintilla/src/LineMarker.cxx scintilla/src/LineMarker.h scintilla/src/MarginView.cxx scintilla/src/MarginView.h scintilla/src/PositionCache.cxx scintilla/src/RESearch.h scintilla/src/ScintillaBase.cxx scintilla/src/UniConversion.cxx scintilla/src/UniConversion.h scintilla/version.txt Modified: scintilla/gtk/PlatGTK.cxx 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -708,7 +708,7 @@ void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfacePattern); - bool canDraw = surfi.psurf; + bool canDraw = surfi.psurf != NULL; if (canDraw) { PLATFORM_ASSERT(context); // Tile pattern over rectangle @@ -842,7 +842,7 @@ void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfaceSource); - bool canDraw = surfi.psurf; + bool canDraw = surfi.psurf != NULL; if (canDraw) { PLATFORM_ASSERT(context); cairo_set_source_surface(context, surfi.psurf, Modified: scintilla/gtk/ScintillaGTK.cxx 37 lines changed, 24 insertions(+), 13 deletions(-) =================================================================== @@ -10,6 +10,7 @@ #include <assert.h> #include <ctype.h> +#include <stdexcept> #include <new> #include <string> #include <vector> @@ -424,6 +425,7 @@ ScintillaGTK::~ScintillaGTK() { gdk_event_free(reinterpret_cast<GdkEvent *>(evbtn)); evbtn = 0; } + wPreedit.Destroy(); } static void UnRefCursor(GdkCursor *cursor) { @@ -482,20 +484,8 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { gdk_window_show(widget->window); UnRefCursor(cursor); #endif - wPreedit = gtk_window_new(GTK_WINDOW_POPUP); - wPreeditDraw = gtk_drawing_area_new(); - GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro -#if GTK_CHECK_VERSION(3,0,0) - g_signal_connect(G_OBJECT(predrw), "draw", - G_CALLBACK(DrawPreedit), this); -#else - g_signal_connect(G_OBJECT(predrw), "expose_event", - G_CALLBACK(ExposePreedit), this); -#endif - gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw); gtk_widget_realize(PWidget(wPreedit)); - gtk_widget_realize(predrw); - gtk_widget_show(predrw); + gtk_widget_realize(PWidget(wPreeditDraw)); im_context = gtk_im_multicontext_new(); g_signal_connect(G_OBJECT(im_context), "commit", @@ -843,6 +833,20 @@ void ScintillaGTK::Initialise() { GTK_DEST_DEFAULT_ALL, clipboardPasteTargets, nClipboardPasteTargets, static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE)); + /* create pre-edit window */ + wPreedit = gtk_window_new(GTK_WINDOW_POPUP); + wPreeditDraw = gtk_drawing_area_new(); + GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(predrw), "draw", + G_CALLBACK(DrawPreedit), this); +#else + g_signal_connect(G_OBJECT(predrw), "expose_event", + G_CALLBACK(ExposePreedit), this); +#endif + gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw); + gtk_widget_show(predrw); + // Set caret period based on GTK settings gboolean blinkOn = false; if (g_object_class_find_property(G_OBJECT_GET_CLASS( @@ -1563,6 +1567,13 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio len--; // Forget the extra '\0' #endif +#if PLAT_GTK_WIN32 + // Win32 includes an ending '\0' byte in 'len' for clipboard text from + // external applications; ignore it. + if ((len > 0) && (data[len - 1] == '\0')) + len--; +#endif + std::string dest(data, len); if (selectionTypeData == GDK_TARGET_STRING) { if (IsUnicodeMode()) { Modified: scintilla/include/Scintilla.h 9 lines changed, 8 insertions(+), 1 deletions(-) =================================================================== @@ -274,7 +274,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define INDIC_DOTBOX 12 #define INDIC_SQUIGGLEPIXMAP 13 #define INDIC_COMPOSITIONTHICK 14 -#define INDIC_MAX 31 +#define INDIC_IME 32 +#define INDIC_IME_MAX 35 +#define INDIC_MAX 35 #define INDIC_CONTAINER 8 #define INDIC0_MASK 0x20 #define INDIC1_MASK 0x40 @@ -372,6 +374,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCFIND_WORDSTART 0x00100000 #define SCFIND_REGEXP 0x00200000 #define SCFIND_POSIX 0x00400000 +#define SCFIND_CXX11REGEX 0x00800000 #define SCI_FINDTEXT 2150 #define SCI_FORMATRANGE 2151 #define SCI_GETFIRSTVISIBLELINE 2152 @@ -643,6 +646,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_STATUS_OK 0 #define SC_STATUS_FAILURE 1 #define SC_STATUS_BADALLOC 2 +#define SC_STATUS_WARN_START 1000 +#define SC_STATUS_WARN_REGEX 1001 #define SCI_SETSTATUS 2382 #define SCI_GETSTATUS 2383 #define SCI_SETMOUSEDOWNCAPTURES 2384 @@ -813,6 +818,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define ANNOTATION_HIDDEN 0 #define ANNOTATION_STANDARD 1 #define ANNOTATION_BOXED 2 +#define ANNOTATION_INDENTED 3 #define SCI_ANNOTATIONSETVISIBLE 2548 #define SCI_ANNOTATIONGETVISIBLE 2549 #define SCI_ANNOTATIONSETSTYLEOFFSET 2550 @@ -893,6 +899,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_TECHNOLOGY_DEFAULT 0 #define SC_TECHNOLOGY_DIRECTWRITE 1 #define SC_TECHNOLOGY_DIRECTWRITERETAIN 2 +#define SC_TECHNOLOGY_DIRECTWRITEDC 3 #define SCI_SETTECHNOLOGY 2630 #define SCI_GETTECHNOLOGY 2631 #define SCI_CREATELOADER 2632 Modified: scintilla/include/Scintilla.iface 9 lines changed, 8 insertions(+), 1 deletions(-) =================================================================== @@ -605,7 +605,9 @@ val INDIC_SQUIGGLELOW=11 val INDIC_DOTBOX=12 val INDIC_SQUIGGLEPIXMAP=13 val INDIC_COMPOSITIONTHICK=14 -val INDIC_MAX=31 +val INDIC_IME=32 +val INDIC_IME_MAX=35 +val INDIC_MAX=35 val INDIC_CONTAINER=8 val INDIC0_MASK=0x20 val INDIC1_MASK=0x40 @@ -884,6 +886,7 @@ val SCFIND_MATCHCASE=0x4 val SCFIND_WORDSTART=0x00100000 val SCFIND_REGEXP=0x00200000 val SCFIND_POSIX=0x00400000 +val SCFIND_CXX11REGEX=0x00800000 # Find some text in the document. fun position FindText=2150(int flags, findtext ft) @@ -1661,6 +1664,8 @@ enu Status=SC_STATUS_ val SC_STATUS_OK=0 val SC_STATUS_FAILURE=1 val SC_STATUS_BADALLOC=2 +val SC_STATUS_WARN_START=1000 +val SC_STATUS_WARN_REGEX=1001 # Change error status - 0 = OK. set void SetStatus=2382(int statusCode,) @@ -2152,6 +2157,7 @@ enu AnnotationVisible=ANNOTATION_ val ANNOTATION_HIDDEN=0 val ANNOTATION_STANDARD=1 val ANNOTATION_BOXED=2 +val ANNOTATION_INDENTED=3 # Set the visibility for the annotations for a view set void AnnotationSetVisible=2548(int visible,) @@ -2360,6 +2366,7 @@ fun void ScrollToEnd=2629(,) val SC_TECHNOLOGY_DEFAULT=0 val SC_TECHNOLOGY_DIRECTWRITE=1 val SC_TECHNOLOGY_DIRECTWRITERETAIN=2 +val SC_TECHNOLOGY_DIRECTWRITEDC=3 # Set the technology used. set void SetTechnology=2630(int technology,) Modified: scintilla/lexers/LexCoffeeScript.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -407,7 +407,7 @@ static void FoldCoffeeScriptDoc(unsigned int startPos, int length, int, static const char *const csWordLists[] = { "Keywords", "Secondary keywords", - "Unused" + "Unused", "Global classes", 0, }; Modified: scintilla/lexers/LexVHDL.cxx 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -207,7 +207,7 @@ static void FoldNoBoxVHDLDoc( // Decided it would be smarter to have the lexer have all keywords included. Therefore I // don't check if the style for the keywords that I use to adjust the levels. char words[] = - "architecture begin case component else elsif end entity generate loop package process record then " + "architecture begin block case component else elsif end entity generate loop package process record then " "procedure function when"; WordList keywords; keywords.Set(words); @@ -369,6 +369,7 @@ static void FoldNoBoxVHDLDoc( strcmp(s, "architecture") == 0 || strcmp(s, "case") == 0 || strcmp(s, "generate") == 0 || + strcmp(s, "block") == 0 || strcmp(s, "loop") == 0 || strcmp(s, "package") ==0 || strcmp(s, "process") == 0 || Modified: scintilla/src/Catalogue.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -84,8 +84,8 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmCaml); LINK_LEXER(lmCmake); LINK_LEXER(lmCOBOL); - LINK_LEXER(lmCPP); LINK_LEXER(lmCoffeeScript); + LINK_LEXER(lmCPP); LINK_LEXER(lmCss); LINK_LEXER(lmD); LINK_LEXER(lmDiff); Modified: scintilla/src/CellBuffer.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -378,7 +378,7 @@ char CellBuffer::CharAt(int position) const { } void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const { - if (lengthRetrieve < 0) + if (lengthRetrieve <= 0) return; if (position < 0) return; Modified: scintilla/src/Decoration.cxx 4 lines changed, 3 insertions(+), 1 deletions(-) =================================================================== @@ -163,7 +163,9 @@ int DecorationList::AllOnFor(int position) const { int mask = 0; for (Decoration *deco=root; deco; deco = deco->next) { if (deco->rs.ValueAt(position)) { - mask |= 1 << deco->indicator; + if (deco->indicator < INDIC_IME) { + mask |= 1 << deco->indicator; + } } } return mask; Modified: scintilla/src/Document.cxx 504 lines changed, 464 insertions(+), 40 deletions(-) =================================================================== @@ -11,10 +11,15 @@ #include <assert.h> #include <ctype.h> +#include <stdexcept> #include <string> #include <vector> #include <algorithm> +#ifdef CXX11_REGEX +#include <regex> +#endif + #include "Platform.h" #include "ILexer.h" @@ -335,6 +340,10 @@ int SCI_METHOD Document::LineStart(int line) const { return cb.LineStart(line); } +bool Document::IsLineStartPosition(int position) const { + return LineStart(LineFromPosition(position)) == position; +} + int SCI_METHOD Document::LineEnd(int line) const { if (line >= LinesTotal() - 1) { return LineStart(line + 1); @@ -601,7 +610,7 @@ bool Document::InGoodUTF8(int pos, int &start, int &end) const { // When lines are terminated with \r\n pairs which should be treated as one character. // When displaying DBCS text such as Japanese. // If moving, move the position in the indicated direction. -int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { +int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) const { //Platform::DebugPrintf("NoCRLF %d %d\n", pos, moveDir); // If out of range, just return minimum/maximum value. if (pos <= 0) @@ -1297,7 +1306,7 @@ int Document::GetColumn(int pos) { return column; } -int Document::CountCharacters(int startPos, int endPos) { +int Document::CountCharacters(int startPos, int endPos) const { startPos = MovePositionOutsideChar(startPos, 1, false); endPos = MovePositionOutsideChar(endPos, -1, false); int count = 0; @@ -1586,6 +1595,25 @@ void Document::SetCaseFolder(CaseFolder *pcf_) { pcf = pcf_; } +Document::CharacterExtracted Document::ExtractCharacter(int position) const { + const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(position)); + if (UTF8IsAscii(leadByte)) { + // Common case: ASCII character + return CharacterExtracted(leadByte, 1); + } + const int widthCharBytes = UTF8BytesOfLead[leadByte]; + unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; + for (int b=1; b<widthCharBytes; b++) + charBytes[b] = static_cast<unsigned char>(cb.CharAt(position + b)); + int utf8status = UTF8Classify(charBytes, widthCharBytes); + if (utf8status & UTF8MaskInvalid) { + // Treat as invalid and use up just one byte + return CharacterExtracted(unicodeReplacementChar, 1); + } else { + return CharacterExtracted(UnicodeFromBytes(charBytes), utf8status & UTF8MaskWidth); + } +} + /** * Find text in document, supporting both forward and backward * searches (just pass minPos > maxPos to do a backward search) @@ -2177,6 +2205,61 @@ class BuiltinRegex : public RegexSearchBase { std::string substituted; }; +namespace { + +/** +* RESearchRange keeps track of search range. +*/ +class RESearchRange { +public: + const Document *doc; + int increment; + int startPos; + int endPos; + int lineRangeStart; + int lineRangeEnd; + int lineRangeBreak; + RESearchRange(const Document *doc_, int minPos, int maxPos) : doc(doc_) { + increment = (minPos <= maxPos) ? 1 : -1; + + // Range endpoints should not be inside DBCS characters, but just in case, move them. + startPos = doc->MovePositionOutsideChar(minPos, 1, false); + endPos = doc->MovePositionOutsideChar(maxPos, 1, false); + + lineRangeStart = doc->LineFromPosition(startPos); + lineRangeEnd = doc->LineFromPosition(endPos); + if ((increment == 1) && + (startPos >= doc->LineEnd(lineRangeStart)) && + (lineRangeStart < lineRangeEnd)) { + // the start position is at end of line or between line end characters. + lineRangeStart++; + startPos = doc->LineStart(lineRangeStart); + } else if ((increment == -1) && + (startPos <= doc->LineStart(lineRangeStart)) && + (lineRangeStart > lineRangeEnd)) { + // the start position is at beginning of line. + lineRangeStart--; + startPos = doc->LineEnd(lineRangeStart); + } + lineRangeBreak = lineRangeEnd + increment; + } + Range LineRange(int line) const { + Range range(doc->LineStart(line), doc->LineEnd(line)); + if (increment == 1) { + if (line == lineRangeStart) + range.start = startPos; + if (line == lineRangeEnd) + range.end = endPos; + } else { + if (line == lineRangeEnd) + range.start = endPos; + if (line == lineRangeStart) + range.end = startPos; + } + return range; + } +}; + // Define a way for the Regular Expression code to access the document class DocumentIndexer : public CharacterIndexer { Document *pdoc; @@ -2197,18 +2280,375 @@ class DocumentIndexer : public CharacterIndexer { } }; +#ifdef CXX11_REGEX + +class ByteIterator : public std::iterator<std::bidirectional_iterator_tag, char> { +public: + const Document *doc; + Position position; + ByteIterator(const Document *doc_ = 0, Position position_ = 0) : doc(doc_), position(position_) { + } + ByteIterator(const ByteIterator &other) { + doc = other.doc; + position = other.position; + } + ByteIterator &operator=(const ByteIterator &other) { + if (this != &other) { + doc = other.doc; + position = other.position; + } + return *this; + } + char operator*() const { + return doc->CharAt(position); + } + ByteIterator &operator++() { + position++; + return *this; + } + ByteIterator operator++(int) { + ByteIterator retVal(*this); + position++; + return retVal; + } + ByteIterator &operator--() { + position--; + return *this; + } + bool operator==(const ByteIterator &other) const { + return doc == other.doc && position == other.position; + } + bool operator!=(const ByteIterator &other) const { + return doc != other.doc || position != other.position; + } + int Pos() const { + return position; + } + int PosRoundUp() const { + return position; + } +}; + +// On Windows, wchar_t is 16 bits wide and on Unix it is 32 bits wide. +// Would be better to use sizeof(wchar_t) or similar to differentiate +// but easier for now to hard-code platforms. +// C++11 has char16_t and char32_t but neither Clang nor Visual C++ +// appear to allow specializing basic_regex over these. + +#ifdef _WIN32 +#define WCHAR_T_IS_16 1 +#else +#define WCHAR_T_IS_16 0 +#endif + +#if WCHAR_T_IS_16 + +// On Windows, report non-BMP characters as 2 separate surrogates as that +// matches wregex since it is based on wchar_t. +class UTF8Iterator : public std::iterator<std::bidirectional_iterator_tag, wchar_t> { + // These 3 fields determine the iterator position and are used for comparisons + const Document *doc; + Position position; + size_t characterIndex; + // Remaining fields are derived from the determining fields so are excluded in comparisons + unsigned int lenBytes; + size_t lenCharacters; + wchar_t buffered[2]; +public: + UTF8Iterator(const Document *doc_ = 0, Position position_ = 0) : + doc(doc_), position(position_), characterIndex(0), lenBytes(0), lenCharacters(0) { + buffered[0] = 0; + buffered[1] = 0; + } + UTF8Iterator(const UTF8Iterator &other) { + doc = other.doc; + position = other.position; + characterIndex = other.characterIndex; + lenBytes = other.lenBytes; + lenCharacters = other.lenCharacters; + buffered[0] = other.buffered[0]; + buffered[1] = other.buffered[1]; + } + UTF8Iterator &operator=(const UTF8Iterator &other) { + if (this != &other) { + doc = other.doc; + position = other.position; + characterIndex = other.characterIndex; + lenBytes = other.lenBytes; + lenCharacters = other.lenCharacters; + buffered[0] = other.buffered[0]; + buffered[1] = other.buffered[1]; + } + return *this; + } + wchar_t operator*() { + if (lenCharacters == 0) { + ReadCharacter(); + } + return buffered[characterIndex]; + } + UTF8Iterator &operator++() { + if ((characterIndex + 1) < (lenCharacters)) { + characterIndex++; + } else { + position += lenBytes; + ReadCharacter(); + characterIndex = 0; + } + return *this; + } + UTF8Iterator operator++(int) { + UTF8Iterator retVal(*this); + if ((characterIndex + 1) < (lenCharacters)) { + characterIndex++; + } else { + position += lenBytes; + ReadCharacter(); + characterIndex = 0; + } + return retVal; + } + UTF8Iterator &operator--() { + if (characterIndex) { + characterIndex--; + } else { + position = doc->NextPosition(position, -1); + ReadCharacter(); + characterIndex = lenCharacters - 1; + } + return *this; + } + bool operator==(const UTF8Iterator &other) const { + // Only test the determining fields, not the character widths and values derived from this + return doc == other.doc && + position == other.position && + characterIndex == other.characterIndex; + } + bool operator!=(const UTF8Iterator &other) const { + // Only test the determining fields, not the character widths and values derived from this + return doc != other.doc || + position != other.position || + characterIndex != other.characterIndex; + } + int Pos() const { + return position; + } + int PosRoundUp() const { + if (characterIndex) + return position + lenBytes; // Force to end of character + else + return position; + } +private: + void ReadCharacter() { + Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); + lenBytes = charExtracted.widthBytes; + if (charExtracted.character == unicodeReplacementChar) { + lenCharacters = 1; + buffered[0] = static_cast<wchar_t>(charExtracted.character); + } else { + lenCharacters = UTF16FromUTF32Character(charExtracted.character, buffered); + } + } +}; + +#else + +// On Unix, report non-BMP characters as single characters + +class UTF8Iterator : public std::iterator<std::bidirectional_iterator_tag, wchar_t> { + const Document *doc; + Position position; +public: + UTF8Iterator(const Document *doc_=0, Position position_=0) : doc(doc_), position(position_) { + } + UTF8Iterator(const UTF8Iterator &other) { + doc = other.doc; + position = other.position; + } + UTF8Iterator &operator=(const UTF8Iterator &other) { + if (this != &other) { + doc = other.doc; + position = other.position; + } + return *this; + } + wchar_t operator*() const { + Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); + return charExtracted.character; + } + UTF8Iterator &operator++() { + position = doc->NextPosition(position, 1); + return *this; + } + UTF8Iterator operator++(int) { + UTF8Iterator retVal(*this); + position = doc->NextPosition(position, 1); + return retVal; + } + UTF8Iterator &operator--() { + position = doc->NextPosition(position, -1); + return *this; + } + bool operator==(const UTF8Iterator &other) const { + return doc == other.doc && position == other.position; + } + bool operator!=(const UTF8Iterator &other) const { + return doc != other.doc || position != other.position; + } + int Pos() const { + return position; + } + int PosRoundUp() const { + return position; + } +}; + +#endif + +std::regex_constants::match_flag_type MatchFlags(const Document *doc, int startPos, int endPos) { + std::regex_constants::match_flag_type flagsMatch = std::regex_constants::match_default; + if (!doc->IsLineStartPosition(startPos)) + flagsMatch |= std::regex_constants::match_not_bol; + if (!doc->IsLineEndPosition(endPos)) + flagsMatch |= std::regex_constants::match_not_eol; + return flagsMatch; +} + +template<typename Iterator, typename Regex> +bool MatchOnLines(const Document *doc, const Regex ®exp, const RESearchRange &resr, RESearch &search) { + bool matched = false; + std::match_results<Iterator> match; + + // MSVC and libc++ have problems with ^ and $ matching line ends inside a range + // If they didn't then the line by line iteration could be removed for the forwards + // case and replaced with the following 4 lines: + // Iterator uiStart(doc, startPos); + // Iterator uiEnd(doc, endPos); + // flagsMatch = MatchFlags(doc, startPos, endPos); + // matched = std::regex_search(uiStart, uiEnd, match, regexp, flagsMatch); + + // Line by line. + for (int line = resr.lineRangeStart; line != resr.lineRangeBreak; line += resr.increment) { + const Range lineRange = resr.LineRange(line); + Iterator itStart(doc, lineRange.start); + Iterator itEnd(doc, lineRange.end); + std::regex_constants::match_flag_type flagsMatch = MatchFlags(doc, lineRange.start, lineRange.end); + matched = std::regex_search(itStart, itEnd, match, regexp, flagsMatch); + // Check for the last match on this line. + if (matched) { + if (resr.increment == -1) { + while (matched) { + Iterator itNext(doc, match[0].second.PosRoundUp()); + flagsMatch = MatchFlags(doc, itNext.Pos(), lineRange.end); + std::match_results<Iterator> matchNext; + matched = std::regex_search(itNext, itEnd, matchNext, regexp, flagsMatch); + if (matched) { + if (match[0].first == match[0].second) { + // Empty match means failure so exit + return false; + } + match = matchNext; + } + } + matched = true; + } + break; + } + } + if (matched) { + for (size_t co = 0; co < match.size(); co++) { + search.bopat[co] = match[co].first.Pos(); + search.eopat[co] = match[co].second.PosRoundUp(); + size_t lenMatch = search.eopat[co] - search.bopat[co]; + search.pat[co].resize(lenMatch); + for (size_t iPos = 0; iPos < lenMatch; iPos++) { + search.pat[co][iPos] = doc->CharAt(iPos + search.bopat[co]); + } + } + } + return matched; +} + +long Cxx11RegexFindText(Document *doc, int minPos, int maxPos, const char *s, + bool caseSensitive, int *length, RESearch &search) { + const RESearchRange resr(doc, minPos, maxPos); + try { + //ElapsedTime et; + std::regex::flag_type flagsRe = std::regex::ECMAScript; + // Flags that apper to have no effect: + // | std::regex::collate | std::regex::extended; + if (!caseSensitive) + flagsRe = flagsRe | std::regex::icase; + + // Clear the RESearch so can fill in matches + search.Clear(); + + bool matched = false; + if (SC_CP_UTF8 == doc->dbcsCodePage) { + unsigned int lenS = static_cast<unsigned int>(strlen(s)); + std::vector<wchar_t> ws(lenS + 1); +#if WCHAR_T_IS_16 + size_t outLen = UTF16FromUTF8(s, lenS, &ws[0], lenS); +#else + size_t outLen = UTF32FromUTF8(s, lenS, reinterpret_cast<unsigned int *>(&ws[0]), lenS); +#endif + ws[outLen] = 0; + std::wregex regexp; +#if defined(__APPLE__) + // Using a UTF-8 locale doesn't change to Unicode over a byte buffer so '.' + // is one byte not one character. + // However, on OS X this makes wregex act as Unicode + std::locale localeU("en_US.UTF-8"); + regexp.imbue(localeU); +#endif + regexp.assign(&ws[0], flagsRe); + matched = MatchOnLines<UTF8Iterator>(doc, regexp, resr, search); + + } else { + std::regex regexp; + regexp.assign(s, flagsRe); + matched = MatchOnLines<ByteIterator>(doc, regexp, resr, search); + } + + int posMatch = -1; + if (matched) { + posMatch = search.bopat[0]; + *length = search.eopat[0] - search.bopat[0]; + } + // Example - search in doc/ScintillaHistory.html for + // [[:upper:]]eta[[:space:]] + // On MacBook, normally around 1 second but with locale imbued -> 14 seconds. + //double durSearch = et.Duration(true); + //Platform::DebugPrintf("Search:%9.6g \n", durSearch); + return posMatch; + } catch (std::regex_error &) { + // Failed to create regular expression + throw RegexError(); + } catch (...) { + // Failed in some other way + return -1; + } +} + +#endif + +} + long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s, bool caseSensitive, bool, bool, int flags, int *length) { - const bool posix = (flags & SCFIND_POSIX) != 0; - const int increment = (minPos <= maxPos) ? 1 : -1; - int startPos = minPos; - int endPos = maxPos; +#ifdef CXX11_REGEX + if (flags & SCFIND_CXX11REGEX) { + return Cxx11RegexFindText(doc, minPos, maxPos, s, + caseSensitive, length, search); + } +#endif - // Range endpoints should not be inside DBCS characters, but just in case, move them. - startPos = doc->MovePositionOutsideChar(startPos, 1, false); - endPos = doc->MovePositionOutsideChar(endPos, 1, false); + const RESearchRange resr(doc, minPos, maxPos); + + const bool posix = (flags & SCFIND_POSIX) != 0; const char *errmsg = search.Compile(s, *length, caseSensitive, posix); if (errmsg) { @@ -2218,50 +2658,34 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s // Replace first '.' with '-' in each property file variable reference: // Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\)) // Replace: $(\1-\2) - int lineRangeStart = doc->LineFromPosition(startPos); - const int lineRangeEnd = doc->LineFromPosition(endPos); - if ((increment == 1) && - (startPos >= doc->LineEnd(lineRangeStart)) && - (lineRangeStart < lineRangeEnd)) { - // the start position is at end of line or between line end characters. - lineRangeStart++; - startPos = doc->LineStart(lineRangeStart); - } else if ((increment == -1) && - (startPos <= doc->LineStart(lineRangeStart)) && - (lineRangeStart > lineRangeEnd)) { - // the start position is at beginning of line. - lineRangeStart--; - startPos = doc->LineEnd(lineRangeStart); - } int pos = -1; int lenRet = 0; const char searchEnd = s[*length - 1]; const char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0'; - const int lineRangeBreak = lineRangeEnd + increment; - for (int line = lineRangeStart; line != lineRangeBreak; line += increment) { + for (int line = resr.lineRangeStart; line != resr.lineRangeBreak; line += resr.increment) { int startOfLine = doc->LineStart(line); int endOfLine = doc->LineEnd(line); - if (increment == 1) { - if (line == lineRangeStart) { - if ((startPos != startOfLine) && (s[0] == '^')) + if (resr.increment == 1) { + if (line == resr.lineRangeStart) { + if ((resr.startPos != startOfLine) && (s[0] == '^')) continue; // Can't match start of line if start position after start of line - startOfLine = startPos; + startOfLine = resr.startPos; } - if (line == lineRangeEnd) { - if ((endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) + if (line == resr.lineRangeEnd) { + if ((resr.endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) continue; // Can't match end of line if end position before end of line - endOfLine = endPos; + endOfLine = resr.endPos; } } else { - if (line == lineRangeEnd) { - if ((endPos != startOfLine) && (s[0] == '^')) + if (line == resr.lineRangeEnd) { + if ((resr.endPos != startOfLine) && (s[0] == '^')) continue; // Can't match start of line if end position after start of line - startOfLine = endPos; + startOfLine = resr.endPos; } - if (line == lineRangeStart) { - if ((startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) + if (line == resr.lineRangeStart) { + if ((resr.startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) continue; // Can't match end of line if start position before end of line - endOfLine = startPos; + endOfLine = resr.startPos; } } @@ -2273,7 +2697,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s search.eopat[0] = doc->MovePositionOutsideChar(search.eopat[0], 1, false); lenRet = search.eopat[0] - search.bopat[0]; // There can be only one start of a line, so no need to look for last match in line - if ((increment == -1) && (s[0] != '^')) { + if ((resr.increment == -1) && (s[0] != '^')) { // Check for the last match on this line. int repetitions = 1000; // Break out of infinite loop while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) { Modified: scintilla/src/Document.h 19 lines changed, 17 insertions(+), 2 deletions(-) =================================================================== @@ -188,6 +188,10 @@ class LexInterface { } }; +struct RegexError : public std::runtime_error { + RegexError() : std::runtime_error("regex failure") {} +}; + /** */ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { @@ -271,7 +275,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { bool IsCrLf(int pos) const; int LenChar(int pos); bool InGoodUTF8(int pos, int &start, int &end) const; - int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); + int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const; int NextPosition(int pos, int moveDir) const; bool NextCharacter(int &pos, int moveDir) const; // Returns true if pos changed int SCI_METHOD GetRelativePosition(int positionStart, int characterOffset) const; @@ -317,7 +321,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { int SetLineIndentation(int line, int indent); int GetLineIndentPosition(int line) const; int GetColumn(int position); - int CountCharacters(int startPos, int endPos); + int CountCharacters(int startPos, int endPos) const; int FindColumn(int line, int column); void Indent(bool forwards, int lineBottom, int lineTop); static std::string TransformLineEnds(const char *s, size_t len, int eolModeWanted); @@ -345,6 +349,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void DeleteAllMarks(int markerNum); int LineFromHandle(int markerHandle); int SCI_METHOD LineStart(int line) const; + bool IsLineStartPosition(int position) const; int SCI_METHOD LineEnd(int line) const; int LineEndPosition(int position) const; bool IsLineEndPosition(int position) const; @@ -364,6 +369,16 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { int NextWordEnd(int pos, int delta); int SCI_METHOD Length() const { return cb.Length(); } void Allocate(int newSize) { cb.Allocate(newSize); } + + struct CharacterExtracted { + unsigned int character; + unsigned int widthBytes; + CharacterExtracted(unsigned int character_, unsigned int widthBytes_) : + character(character_), widthBytes(widthBytes_) { + } + }; + CharacterExtracted ExtractCharacter(int position) const; + bool MatchesWordOptions(bool word, bool wordStart, int pos, int length) const; bool HasCaseFolder(void) const; void SetCaseFolder(CaseFolder *pcf_); Modified: scintilla/src/EditModel.cxx 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -12,6 +12,7 @@ #include <assert.h> #include <ctype.h> +#include <stdexcept> #include <string> #include <vector> #include <map> Modified: scintilla/src/EditView.cxx 45 lines changed, 31 insertions(+), 14 deletions(-) =================================================================== @@ -12,6 +12,7 @@ #include <assert.h> #include <ctype.h> +#include <stdexcept> #include <string> #include <vector> #include <map> @@ -185,6 +186,9 @@ EditView::EditView() { pixmapIndentGuideHighlight = 0; llc.SetLevel(LineLayoutCache::llcCaret); posCache.SetSize(0x400); + tabArrowHeight = 4; + customDrawTabArrow = NULL; + customDrawWrapMarker = NULL; } EditView::~EditView() { @@ -927,7 +931,11 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle rcPlace.right = rcLine.right; rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; } - DrawWrapMarker(surface, rcPlace, true, vsDraw.WrapColour()); + if (customDrawWrapMarker == NULL) { + DrawWrapMarker(surface, rcPlace, true, vsDraw.WrapColour()); + } else { + customDrawWrapMarker(surface, rcPlace, true, vsDraw.WrapColour()); + } } } @@ -991,6 +999,10 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS } } +static bool AnnotationBoxedOrIndented(int annotationVisible) { + return annotationVisible == ANNOTATION_BOXED || annotationVisible == ANNOTATION_INDENTED; +} + void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, int line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase) { int indent = static_cast<int>(model.pdoc->GetLineIndentation(line) * vsDraw.spaceWidth); @@ -1002,18 +1014,16 @@ void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const Vi surface->FillRectangle(rcSegment, vsDraw.styles[0].back); } rcSegment.left = static_cast<XYPOSITION>(xStart); - if (model.trackLineWidth || (vsDraw.annotationVisible == ANNOTATION_BOXED)) { - // Only care about calculating width if tracking or need to draw box + if (model.trackLineWidth || AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { + // Only care about calculating width if tracking or need to draw indented box int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation); - if (vsDraw.annotationVisible == ANNOTATION_BOXED) { + if (AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { widthAnnotation += static_cast<int>(vsDraw.spaceWidth * 2); // Margins - } - if (widthAnnotation > lineWidthMaxSeen) - lineWidthMaxSeen = widthAnnotation; - if (vsDraw.annotationVisible == ANNOTATION_BOXED) { rcSegment.left = static_cast<XYPOSITION>(xStart + indent); rcSegment.right = rcSegment.left + widthAnnotation; } + if (widthAnnotation > lineWidthMaxSeen) + lineWidthMaxSeen = widthAnnotation; } const int annotationLines = model.pdoc->AnnotationLines(line); size_t start = 0; @@ -1025,7 +1035,7 @@ void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const Vi lineInAnnotation++; } PRectangle rcText = rcSegment; - if ((phase & drawBack) && (vsDraw.annotationVisible == ANNOTATION_BOXED)) { + if ((phase & drawBack) && AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { surface->FillRectangle(rcText, vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back); rcText.left += vsDraw.spaceWidth; @@ -1201,7 +1211,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, - int xStart, PRectangle rcLine, ColourOptional background) { + int xStart, PRectangle rcLine, ColourOptional background, DrawWrapMarkerFn customDrawWrapMarker) { // default bgnd here.. surface->FillRectangle(rcLine, background.isSet ? background : vsDraw.styles[STYLE_DEFAULT].back); @@ -1219,7 +1229,11 @@ static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, c else rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; - DrawWrapMarker(surface, rcPlace, false, vsDraw.WrapColour()); + if (customDrawWrapMarker == NULL) { + DrawWrapMarker(surface, rcPlace, false, vsDraw.WrapColour()); + } else { + customDrawWrapMarker(surface, rcPlace, false, vsDraw.WrapColour()); + } } } @@ -1463,9 +1477,12 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi if (vsDraw.whitespaceColours.fore.isSet) textFore = vsDraw.whitespaceColours.fore; surface->PenColour(textFore); - PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, + PRectangle rcTab(rcSegment.left + 1, rcSegment.top + tabArrowHeight, rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); - DrawTabArrow(surface, rcTab, static_cast<int>(rcSegment.top + vsDraw.lineHeight / 2)); + if (customDrawTabArrow == NULL) + DrawTabArrow(surface, rcTab, static_cast<int>(rcSegment.top + vsDraw.lineHeight / 2)); + else + customDrawTabArrow(surface, rcTab, static_cast<int>(rcSegment.top + vsDraw.lineHeight / 2)); } } } else { @@ -1632,7 +1649,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl if ((ll->wrapIndent != 0) && (subLine > 0)) { if (phase & drawBack) { - DrawWrapIndentAndMarker(surface, vsDraw, ll, xStart, rcLine, background); + DrawWrapIndentAndMarker(surface, vsDraw, ll, xStart, rcLine, background, customDrawWrapMarker); } xStart += static_cast<int>(ll->wrapIndent); } Modified: scintilla/src/EditView.h 10 lines changed, 10 insertions(+), 0 deletions(-) =================================================================== @@ -42,6 +42,8 @@ void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XY void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRectangle rcText, const StyledText &st, size_t start, size_t length, DrawPhase phase); +typedef void (*DrawTabArrowFn)(Surface *surface, PRectangle rcTab, int ymid); + /** * EditView draws the main text area. */ @@ -78,6 +80,14 @@ class EditView { LineLayoutCache llc; PositionCache posCache; + int tabArrowHeight; // draw arrow heads this many pixels above/below line midpoint + /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native + * DrawTabArrow function for drawing tab characters. Allow those platforms to + * override it instead of creating a new method in the Surface class that + * existing platforms must implement as empty. */ + DrawTabArrowFn customDrawTabArrow; + DrawWrapMarkerFn customDrawWrapMarker; + EditView(); virtual ~EditView(); Modified: scintilla/src/Editor.cxx 105 lines changed, 63 insertions(+), 42 deletions(-) =================================================================== @@ -12,6 +12,7 @@ #include <assert.h> #include <ctype.h> +#include <stdexcept> #include <string> #include <vector> #include <map> @@ -112,6 +113,7 @@ Editor::Editor() { mouseDownCaptures = true; lastClickTime = 0; + doubleClickCloseThreshold = Point(3, 3); dwellDelay = SC_TIME_FOREVER; ticksToDwell = SC_TIME_FOREVER; dwelling = false; @@ -1789,12 +1791,15 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { { UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike); + // Vector elements point into selection in order to change selection. std::vector<SelectionRange *> selPtrs; for (size_t r = 0; r < sel.Count(); r++) { selPtrs.push_back(&sel.Range(r)); } + // Order selections by position in document. std::sort(selPtrs.begin(), selPtrs.end(), cmpSelPtrs); + // Loop in reverse to avoid disturbing positions of selections yet to be processed. for (std::vector<SelectionRange *>::reverse_iterator rit = selPtrs.rbegin(); rit != selPtrs.rend(); ++rit) { SelectionRange *currentSel = *rit; @@ -2105,6 +2110,7 @@ void Editor::Clear() { ClearSelection(); } sel.RemoveDuplicates(); + ShowCaretAtCurrentPosition(); // Avoid blinking } void Editor::SelectAll() { @@ -3638,18 +3644,23 @@ long Editor::FindText( int lengthFound = istrlen(ft->lpstrText); if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); - int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText, - (wParam & SCFIND_MATCHCASE) != 0, - (wParam & SCFIND_WHOLEWORD) != 0, - (wParam & SCFIND_WORDSTART) != 0, - (wParam & SCFIND_REGEXP) != 0, - static_cast<int>(wParam), - &lengthFound); - if (pos != -1) { - ft->chrgText.cpMin = pos; - ft->chrgText.cpMax = pos + lengthFound; + try { + int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText, + (wParam & SCFIND_MATCHCASE) != 0, + (wParam & SCFIND_WHOLEWORD) != 0, + (wParam & SCFIND_WORDSTART) != 0, + (wParam & SCFIND_REGEXP) != 0, + static_cast<int>(wParam), + &lengthFound); + if (pos != -1) { + ft->chrgText.cpMin = pos; + ft->chrgText.cpMax = pos + lengthFound; + } + return pos; + } catch (RegexError &) { + errorStatus = SC_STATUS_WARN_REGEX; + return -1; } - return pos; } /** @@ -3683,22 +3694,27 @@ long Editor::SearchText( int lengthFound = istrlen(txt); if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); - if (iMessage == SCI_SEARCHNEXT) { - pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, - (wParam & SCFIND_MATCHCASE) != 0, - (wParam & SCFIND_WHOLEWORD) != 0, - (wParam & SCFIND_WORDSTART) != 0, - (wParam & SCFIND_REGEXP) != 0, - static_cast<int>(wParam), - &lengthFound); - } else { - pos = pdoc->FindText(searchAnchor, 0, txt, - (wParam & SCFIND_MATCHCASE) != 0, - (wParam & SCFIND_WHOLEWORD) != 0, - (wParam & SCFIND_WORDSTART) != 0, - (wParam & SCFIND_REGEXP) != 0, - static_cast<int>(wParam), - &lengthFound); + try { + if (iMessage == SCI_SEARCHNEXT) { + pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, + (wParam & SCFIND_MATCHCASE) != 0, + (wParam & SCFIND_WHOLEWORD) != 0, + (wParam & SCFIND_WORDSTART) != 0, + (wParam & SCFIND_REGEXP) != 0, + static_cast<int>(wParam), + &lengthFound); + } else { + pos = pdoc->FindText(searchAnchor, 0, txt, + (wParam & SCFIND_MATCHCASE) != 0, + (wParam & SCFIND_WHOLEWORD) != 0, + (wParam & SCFIND_WORDSTART) != 0, + (wParam & SCFIND_REGEXP) != 0, + static_cast<int>(wParam), + &lengthFound); + } + } catch (RegexError &) { + errorStatus = SC_STATUS_WARN_REGEX; + return -1; } if (pos != -1) { SetSelection(pos, pos + lengthFound); @@ -3733,18 +3749,23 @@ long Editor::SearchInTarget(const char *text, int length) { if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); - int pos = pdoc->FindText(targetStart, targetEnd, text, - (searchFlags & SCFIND_MATCHCASE) != 0, - (searchFlags & SCFIND_WHOLEWORD) != 0, - (searchFlags & SCFIND_WORDSTART) != 0, - (searchFlags & SCFIND_REGEXP) != 0, - searchFlags, - &lengthFound); - if (pos != -1) { - targetStart = pos; - targetEnd = pos + lengthFound; + try { + int pos = pdoc->FindText(targetStart, targetEnd, text, + (searchFlags & SCFIND_MATCHCASE) != 0, + (searchFlags & SCFIND_WHOLEWORD) != 0, + (searchFlags & SCFIND_WORDSTART) != 0, + (searchFlags & SCFIND_REGEXP) != 0, + searchFlags, + &lengthFound); + if (pos != -1) { + targetStart = pos; + targetEnd = pos + lengthFound; + } + return pos; + } catch (RegexError &) { + errorStatus = SC_STATUS_WARN_REGEX; + return -1; } - return pos; } void Editor::GoToLine(int lineNo) { @@ -3757,10 +3778,10 @@ void Editor::GoToLine(int lineNo) { EnsureCaretVisible(); } -static bool Close(Point pt1, Point pt2) { - if (abs(pt1.x - pt2.x) > 3) +static bool Close(Point pt1, Point pt2, Point threshold) { + if (abs(pt1.x - pt2.x) > threshold.x) return false; - if (abs(pt1.y - pt2.y) > 3) + if (abs(pt1.y - pt2.y) > threshold.y) return false; return true; } @@ -4116,7 +4137,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie if (shift && !inSelMargin) { SetSelection(newPos); } - if (((curTime - lastClickTime) < Platform::DoubleClickTime()) && Close(pt, lastClick)) { + if (((curTime - lastClickTime) < Platform::DoubleClickTime()) && Close(pt, lastClick, doubleClickCloseThreshold)) { //Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime); SetMouseCapture(true); if (FineTickerAvailable()) { Modified: scintilla/src/Editor.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -203,6 +203,7 @@ class Editor : public EditModel, public DocWatcher { Point lastClick; unsigned int lastClickTime; + Point doubleClickCloseThreshold; int dwellDelay; int ticksToDwell; bool dwelling; Modified: scintilla/src/LineMarker.cxx 5 lines changed, 5 insertions(+), 0 deletions(-) =================================================================== @@ -72,6 +72,11 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C } void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold, int marginStyle) const { + if (customDraw != NULL) { + customDraw(surface, rcWhole, fontForCharacter, tFold, marginStyle, this); + return; + } + ColourDesired colourHead = back; ColourDesired colourBody = back; ColourDesired colourTail = back; Modified: scintilla/src/LineMarker.h 10 lines changed, 10 insertions(+), 0 deletions(-) =================================================================== @@ -12,6 +12,8 @@ namespace Scintilla { #endif +typedef void (*DrawLineMarkerFn)(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, int tFold, int marginStyle, const void *lineMarker); + /** */ class LineMarker { @@ -25,6 +27,11 @@ class LineMarker { int alpha; XPM *pxpm; RGBAImage *image; + /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native + * Draw function for drawing line markers. Allow those platforms to override + * it instead of creating a new method(s) in the Surface class that existing + * platforms must implement as empty. */ + DrawLineMarkerFn customDraw; LineMarker() { markType = SC_MARK_CIRCLE; fore = ColourDesired(0,0,0); @@ -33,6 +40,7 @@ class LineMarker { alpha = SC_ALPHA_NOALPHA; pxpm = NULL; image = NULL; + customDraw = NULL; } LineMarker(const LineMarker &) { // Defined to avoid pxpm being blindly copied, not as a complete copy constructor @@ -43,6 +51,7 @@ class LineMarker { alpha = SC_ALPHA_NOALPHA; pxpm = NULL; image = NULL; + customDraw = NULL; } ~LineMarker() { delete pxpm; @@ -60,6 +69,7 @@ class LineMarker { pxpm = NULL; delete image; image = NULL; + customDraw = NULL; } return *this; } Modified: scintilla/src/MarginView.cxx 11 lines changed, 9 insertions(+), 2 deletions(-) =================================================================== @@ -12,6 +12,7 @@ #include <assert.h> #include <ctype.h> +#include <stdexcept> #include <string> #include <vector> #include <map> @@ -102,6 +103,8 @@ MarginView::MarginView() { pixmapSelMargin = 0; pixmapSelPattern = 0; pixmapSelPatternOffset1 = 0; + wrapMarkerPaddingRight = 3; + customDrawWrapMarker = NULL; } void MarginView::DropGraphics(bool freeObjects) { @@ -391,9 +394,13 @@ void MarginView::PaintMargin(Surface *surface, int topLine, PRectangle rc, PRect rcNumber.top + vs.maxAscent, number, static_cast<int>(strlen(number)), drawAll); } else if (vs.wrapVisualFlags & SC_WRAPVISUALFLAG_MARGIN) { PRectangle rcWrapMarker = rcMarker; - rcWrapMarker.right -= 3; + rcWrapMarker.right -= wrapMarkerPaddingRight; rcWrapMarker.left = rcWrapMarker.right - vs.styles[STYLE_LINENUMBER].aveCharWidth; - DrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); + if (customDrawWrapMarker == NULL) { + DrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); + } else { + customDrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); + } } } else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) { if (firstSubLine) { Modified: scintilla/src/MarginView.h 9 lines changed, 9 insertions(+), 0 deletions(-) =================================================================== @@ -14,6 +14,8 @@ namespace Scintilla { void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); +typedef void (*DrawWrapMarkerFn)(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); + /** * MarginView draws the margins. */ @@ -25,6 +27,13 @@ class MarginView { // Highlight current folding block HighlightDelimiter highlightDelimiter; + int wrapMarkerPaddingRight; // right-most pixel padding of wrap markers + /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native + * DrawWrapMarker function for drawing wrap markers. Allow those platforms to + * override it instead of creating a new method in the Surface class that + * existing platforms must implement as empty. */ + DrawWrapMarkerFn customDrawWrapMarker; + MarginView(); void DropGraphics(bool freeObjects); Modified: scintilla/src/PositionCache.cxx 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -10,6 +10,7 @@ #include <stdio.h> #include <ctype.h> +#include <stdexcept> #include <string> #include <vector> #include <map> Modified: scintilla/src/RESearch.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -33,6 +33,7 @@ class RESearch { public: explicit RESearch(CharClassify *charClassTable); ~RESearch(); + void Clear(); void GrabMatches(CharacterIndexer &ci); const char *Compile(const char *pattern, int length, bool caseSensitive, bool posix); int Execute(CharacterIndexer &ci, int lp, int endp); @@ -46,7 +47,6 @@ class RESearch { std::string pat[MAXTAG]; private: - void Clear(); void ChSet(unsigned char c); void ChSetWithCase(unsigned char c, bool caseSensitive); int GetBackslashExpression(const char *pattern, int &incr); Modified: scintilla/src/ScintillaBase.cxx 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -11,6 +11,7 @@ #include <assert.h> #include <ctype.h> +#include <stdexcept> #include <string> #include <vector> #include <map> Modified: scintilla/src/UniConversion.cxx 46 lines changed, 46 insertions(+), 0 deletions(-) =================================================================== @@ -20,6 +20,7 @@ namespace Scintilla { enum { SURROGATE_LEAD_FIRST = 0xD800 }; enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; enum { SURROGATE_TRAIL_LAST = 0xDFFF }; +enum { SUPPLEMENTAL_PLANE_FIRST = 0x10000 }; unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) { unsigned int len = 0; @@ -138,6 +139,51 @@ unsigned int UTF16FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsig return ui; } +unsigned int UTF32FromUTF8(const char *s, unsigned int len, unsigned int *tbuf, unsigned int tlen) { + unsigned int ui=0; + const unsigned char *us = reinterpret_cast<const unsigned char *>(s); + unsigned int i=0; + while ((i<len) && (ui<tlen)) { + unsigned char ch = us[i++]; + wchar_t value = 0; + if (ch < 0x80) { + value = ch; + } else if (((len-i) >= 1) && (ch < 0x80 + 0x40 + 0x20)) { + value = (ch & 0x1F) << 6; + ch = us[i++]; + value += ch & 0x7F; + } else if (((len-i) >= 2) && (ch < 0x80 + 0x40 + 0x20 + 0x10)) { + value = (ch & 0xF) << 12; + ch = us[i++]; + value += (ch & 0x7F) << 6; + ch = us[i++]; + value += ch & 0x7F; + } else if ((len-i) >= 3) { + value = (ch & 0x7) << 18; + ch = us[i++]; + value += (ch & 0x3F) << 12; + ch = us[i++]; + value += (ch & 0x3F) << 6; + ch = us[i++]; + value += ch & 0x3F; + } + tbuf[ui] = value; + ui++; + } + return ui; +} + +unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf) { + if (val < SUPPLEMENTAL_PLANE_FIRST) { + tbuf[0] = static_cast<wchar_t>(val); + return 1; + } else { + tbuf[0] = static_cast<wchar_t>(((val - SUPPLEMENTAL_PLANE_FIRST) >> 10) + SURROGATE_LEAD_FIRST); + tbuf[1] = static_cast<wchar_t>((val & 0x3ff) + SURROGATE_TRAIL_FIRST); + return 2; + } +} + int UTF8BytesOfLead[256]; static bool initialisedBytesOfLead = false; Modified: scintilla/src/UniConversion.h 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -14,11 +14,15 @@ namespace Scintilla { const int UTF8MaxBytes = 4; +const int unicodeReplacementChar = 0xFFFD; + unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen); void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len); unsigned int UTF8CharLength(unsigned char ch); unsigned int UTF16Length(const char *s, unsigned int len); unsigned int UTF16FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen); +unsigned int UTF32FromUTF8(const char *s, unsigned int len, unsigned int *tbuf, unsigned int tlen); +unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf); extern int UTF8BytesOfLead[256]; void UTF8BytesOfLeadInitialise(); Modified: scintilla/version.txt 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1 +1 @@ -351 +352 -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany] 690962: Update of Portuguese (Brazilian) translation
by Frank Lanitz
01 Dec '14
01 Dec '14
Branch: refs/heads/master Author: Frank Lanitz <frank(a)frank.uvena.de> Committer: Frank Lanitz <frank(a)frank.uvena.de> Date: Mon, 01 Dec 2014 12:05:19 UTC Commit: 69096276414b1532618f354950896db45e0e9256
https://github.com/geany/geany/commit/69096276414b1532618f354950896db45e0e9…
Log Message: ----------- Update of Portuguese (Brazilian) translation Modified Paths: -------------- po/pt_BR.po Modified: po/pt_BR.po 3045 lines changed, 1560 insertions(+), 1485 deletions(-) =================================================================== No diff available, check online -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
← Newer
1
2
3
Older →
Jump to page:
1
2
3
Results per page:
10
25
50
100
200