]> granicus.if.org Git - vim/commitdiff
patch 8.2.3938: line comment start is also found in a string v8.2.3938
authorBram Moolenaar <Bram@vim.org>
Wed, 29 Dec 2021 18:09:13 +0000 (18:09 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 29 Dec 2021 18:09:13 +0000 (18:09 +0000)
Problem:    Line comment start is also found in a string.
Solution:   Skip line comments in a string.

src/cindent.c
src/proto/cindent.pro
src/search.c
src/testdir/test_textformat.vim
src/version.c

index 9f1db03c595acd5bcd2865610d49b417d1881003..747b5093e9eb75f954d3d616eacfbca2a06af889 100644 (file)
@@ -66,8 +66,6 @@ cin_is_cinword(char_u *line)
 }
 #endif
 
-#if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL)
-
 /*
  * Skip to the end of a "string" and a 'c' character.
  * If there is no string or character, return argument unmodified.
@@ -137,6 +135,21 @@ skip_string(char_u *p)
     return p;
 }
 
+/*
+ * Return TRUE if "line[col]" is inside a C string.
+ */
+    int
+is_pos_in_string(char_u *line, colnr_T col)
+{
+    char_u *p;
+
+    for (p = line; *p && (colnr_T)(p - line) < col; ++p)
+       p = skip_string(p);
+    return !((colnr_T)(p - line) <= col);
+}
+
+#if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL)
+
 /*
  * Find the start of a comment, not knowing if we are in a comment right now.
  * Search starts at w_cursor.lnum and goes backwards.
@@ -152,8 +165,6 @@ ind_find_start_comment(void)            // XXX
 find_start_comment(int ind_maxcomment) // XXX
 {
     pos_T      *pos;
-    char_u     *line;
-    char_u     *p;
     int                cur_maxcomment = ind_maxcomment;
 
     for (;;)
@@ -164,10 +175,7 @@ find_start_comment(int ind_maxcomment)     // XXX
 
        // Check if the comment start we found is inside a string.
        // If it is then restrict the search to below this line and try again.
-       line = ml_get(pos->lnum);
-       for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
-           p = skip_string(p);
-       if ((colnr_T)(p - line) <= pos->col)
+       if (!is_pos_in_string(ml_get(pos->lnum), pos->col))
            break;
        cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
        if (cur_maxcomment <= 0)
@@ -188,8 +196,6 @@ find_start_comment(int ind_maxcomment)      // XXX
 find_start_rawstring(int ind_maxcomment)       // XXX
 {
     pos_T      *pos;
-    char_u     *line;
-    char_u     *p;
     int                cur_maxcomment = ind_maxcomment;
 
     for (;;)
@@ -200,10 +206,7 @@ find_start_rawstring(int ind_maxcomment)   // XXX
 
        // Check if the raw string start we found is inside a string.
        // If it is then restrict the search to below this line and try again.
-       line = ml_get(pos->lnum);
-       for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
-           p = skip_string(p);
-       if ((colnr_T)(p - line) <= pos->col)
+       if (!is_pos_in_string(ml_get(pos->lnum), pos->col))
            break;
        cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
        if (cur_maxcomment <= 0)
index 7de2ab3e1f98a1df2cfd7d69fcbccd0ef592409f..80a6add55041278e4434061770c7ec1c20603b5d 100644 (file)
@@ -1,5 +1,6 @@
 /* cindent.c */
 int cin_is_cinword(char_u *line);
+int is_pos_in_string(char_u *line, colnr_T col);
 pos_T *find_start_comment(int ind_maxcomment);
 int cindent_on(void);
 void parse_cino(buf_T *buf);
index c5810ed0e7328c49c5e0bfe30d80ff4a4af888dd..5851d52362f5c0349cfd06a9a1613d14c2735ae1 100644 (file)
@@ -2714,7 +2714,6 @@ findmatchlimit(
 /*
  * Check if line[] contains a / / comment.
  * Return MAXCOL if not, otherwise return the column.
- * TODO: skip strings.
  */
     int
 check_linecomment(char_u *line)
@@ -2746,7 +2745,8 @@ check_linecomment(char_u *line)
                        in_str = TRUE;
                }
                else if (!in_str && ((p - line) < 2
-                                   || (*(p - 1) != '\\' && *(p - 2) != '#')))
+                                   || (*(p - 1) != '\\' && *(p - 2) != '#'))
+                              && !is_pos_in_string(line, (colnr_T)(p - line)))
                    break;      // found!
                ++p;
            }
@@ -2758,9 +2758,11 @@ check_linecomment(char_u *line)
 #endif
     while ((p = vim_strchr(p, '/')) != NULL)
     {
-       // accept a double /, unless it's preceded with * and followed by *,
-       // because * / / * is an end and start of a C comment
-       if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*'))
+       // Accept a double /, unless it's preceded with * and followed by *,
+       // because * / / * is an end and start of a C comment.
+       // Only accept the position if it is not inside a string.
+       if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')
+                              && !is_pos_in_string(line, (colnr_T)(p - line)))
            break;
        ++p;
     }
index ccfd36f7538483fe85ce1bd2934164ec45bc6508..640298929728fa0562d30b18da1f353aab3a4106 100644 (file)
@@ -261,6 +261,21 @@ func Test_format_c_comment()
   END
   call assert_equal(expected, getline(1, '$'))
 
+  " Using "o" does not repeat a comment in a string
+  %del
+  let text =<< trim END
+      nop;
+      val = " // This is not a comment";
+  END
+  call setline(1, text)
+  normal 2Gox
+  let expected =<< trim END
+      nop;
+      val = " // This is not a comment";
+      x
+  END
+  call assert_equal(expected, getline(1, '$'))
+
   " Using CTRL-U after "o" fixes the indent
   %del
   let text =<< trim END
index 68ce1c59460b25e5cdc0cf983b43dd471570fa77..15df8606f76a4f460759c58ac044408f51aa50b1 100644 (file)
@@ -749,6 +749,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3938,
 /**/
     3937,
 /**/