diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-03-08 22:19:26 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-03-08 22:19:26 +0100 |
commit | 7720ba8599162fbbb8f7fc034f674a2ccd3ca7f1 (patch) | |
tree | d130bb2242a5993528be171cee687af290525a53 /src/misc1.c | |
parent | bb962262eb6b18d93161d7506317d215ae80bfe5 (diff) | |
download | vim-git-7720ba8599162fbbb8f7fc034f674a2ccd3ca7f1.tar.gz |
patch 8.0.0431: 'cinoptions' cannot set indent for extern blockv8.0.0431
Problem: 'cinoptions' cannot set indent for extern block.
Solution: Add the "E" flag in 'cinoptions'. (Hirohito Higashi)
Diffstat (limited to 'src/misc1.c')
-rw-r--r-- | src/misc1.c | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/src/misc1.c b/src/misc1.c index ec92f0375..c6b8d13b7 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -5810,6 +5810,54 @@ cin_is_cpp_namespace(char_u *s) } /* + * Recognize a `extern "C"` or `extern "C++"` linkage specifications. + */ + static int +cin_is_cpp_extern_c(char_u *s) +{ + char_u *p; + int has_string_literal = FALSE; + + s = cin_skipcomment(s); + if (STRNCMP(s, "extern", 6) == 0 && (s[6] == NUL || !vim_iswordc(s[6]))) + { + p = cin_skipcomment(skipwhite(s + 6)); + while (*p != NUL) + { + if (vim_iswhite(*p)) + { + p = cin_skipcomment(skipwhite(p)); + } + else if (*p == '{') + { + break; + } + else if (p[0] == '"' && p[1] == 'C' && p[2] == '"') + { + if (has_string_literal) + return FALSE; + has_string_literal = TRUE; + p += 3; + } + else if (p[0] == '"' && p[1] == 'C' && p[2] == '+' && p[3] == '+' + && p[4] == '"') + { + if (has_string_literal) + return FALSE; + has_string_literal = TRUE; + p += 5; + } + else + { + return FALSE; + } + } + return has_string_literal ? TRUE : FALSE; + } + return FALSE; +} + +/* * Return a pointer to the first non-empty non-comment character after a ':'. * Return NULL if not found. * case 234: a = b; @@ -6652,6 +6700,7 @@ cin_skip2pos(pos_T *trypos) { char_u *line; char_u *p; + char_u *new_p; p = line = ml_get(trypos->lnum); while (*p && (colnr_T)(p - line) < trypos->col) @@ -6660,8 +6709,11 @@ cin_skip2pos(pos_T *trypos) p = cin_skipcomment(p); else { - p = skip_string(p); - ++p; + new_p = skip_string(p); + if (new_p == p) + ++p; + else + p = new_p; } } return (int)(p - line); @@ -6977,6 +7029,9 @@ parse_cino(buf_T *buf) /* indentation for # comments */ buf->b_ind_hash_comment = 0; + /* Handle C++ extern "C" or "C++" */ + buf->b_ind_cpp_extern_c = 0; + for (p = buf->b_p_cino; *p; ) { l = p++; @@ -7051,6 +7106,7 @@ parse_cino(buf_T *buf) case '#': buf->b_ind_hash_comment = n; break; case 'N': buf->b_ind_cpp_namespace = n; break; case 'k': buf->b_ind_if_for_while = n; break; + case 'E': buf->b_ind_cpp_extern_c = n; break; } if (*p == ',') ++p; @@ -7764,6 +7820,8 @@ get_c_indent(void) l = skipwhite(ml_get_curline()); if (cin_is_cpp_namespace(l)) amount += curbuf->b_ind_cpp_namespace; + else if (cin_is_cpp_extern_c(l)) + amount += curbuf->b_ind_cpp_extern_c; } else { @@ -7990,6 +8048,12 @@ get_c_indent(void) - added_to_amount; break; } + else if (cin_is_cpp_extern_c(l)) + { + amount += curbuf->b_ind_cpp_extern_c + - added_to_amount; + break; + } if (cin_nocode(l)) continue; |