diff src/evalfunc.c @ 20629:7b8ac5e49451 v8.2.0868

patch 8.2.0868: trim() always trims both ends Commit: https://github.com/vim/vim/commit/2245ae18e3480057f98fc0e5d9f18091f32a5de0 Author: Bram Moolenaar <Bram@vim.org> Date: Sun May 31 22:20:36 2020 +0200 patch 8.2.0868: trim() always trims both ends Problem: trim() always trims both ends. Solution: Add an argument to only trim the beginning or end. (Yegappan Lakshmanan, closes #6126)
author Bram Moolenaar <Bram@vim.org>
date Sun, 31 May 2020 22:30:04 +0200
parents 8eed1e9389bb
children 3e36a51ff152
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -976,7 +976,7 @@ static funcentry_T global_functions[] =
     {"tolower",		1, 1, FEARG_1,	  ret_string,	f_tolower},
     {"toupper",		1, 1, FEARG_1,	  ret_string,	f_toupper},
     {"tr",		3, 3, FEARG_1,	  ret_string,	f_tr},
-    {"trim",		1, 2, FEARG_1,	  ret_string,	f_trim},
+    {"trim",		1, 3, FEARG_1,	  ret_string,	f_trim},
     {"trunc",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_trunc)},
     {"type",		1, 1, FEARG_1,	  ret_number,	f_type},
     {"undofile",	1, 1, FEARG_1,	  ret_string,	f_undofile},
@@ -8637,53 +8637,78 @@ f_trim(typval_T *argvars, typval_T *rett
     char_u	*prev;
     char_u	*p;
     int		c1;
+    int		dir = 0;
 
     rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
     if (head == NULL)
-    {
-	rettv->vval.v_string = NULL;
 	return;
-    }
 
     if (argvars[1].v_type == VAR_STRING)
+    {
 	mask = tv_get_string_buf_chk(&argvars[1], buf2);
 
-    while (*head != NUL)
-    {
-	c1 = PTR2CHAR(head);
-	if (mask == NULL)
+	if (argvars[2].v_type != VAR_UNKNOWN)
 	{
-	    if (c1 > ' ' && c1 != 0xa0)
-		break;
-	}
-	else
-	{
-	    for (p = mask; *p != NUL; MB_PTR_ADV(p))
-		if (c1 == PTR2CHAR(p))
-		    break;
-	    if (*p == NUL)
-		break;
+	    int	error = 0;
+
+	    // leading or trailing characters to trim
+	    dir = (int)tv_get_number_chk(&argvars[2], &error);
+	    if (error)
+		return;
+	    if (dir < 0 || dir > 2)
+	    {
+		semsg(_(e_invarg2), tv_get_string(&argvars[2]));
+		return;
+	    }
 	}
-	MB_PTR_ADV(head);
-    }
-
-    for (tail = head + STRLEN(head); tail > head; tail = prev)
-    {
-	prev = tail;
-	MB_PTR_BACK(head, prev);
-	c1 = PTR2CHAR(prev);
-	if (mask == NULL)
+    }
+
+    if (dir == 0 || dir == 1)
+    {
+	// Trim leading characters
+	while (*head != NUL)
 	{
-	    if (c1 > ' ' && c1 != 0xa0)
-		break;
+	    c1 = PTR2CHAR(head);
+	    if (mask == NULL)
+	    {
+		if (c1 > ' ' && c1 != 0xa0)
+		    break;
+	    }
+	    else
+	    {
+		for (p = mask; *p != NUL; MB_PTR_ADV(p))
+		    if (c1 == PTR2CHAR(p))
+			break;
+		if (*p == NUL)
+		    break;
+	    }
+	    MB_PTR_ADV(head);
 	}
-	else
+    }
+
+    tail = head + STRLEN(head);
+    if (dir == 0 || dir == 2)
+    {
+	// Trim trailing characters
+	for (; tail > head; tail = prev)
 	{
-	    for (p = mask; *p != NUL; MB_PTR_ADV(p))
-		if (c1 == PTR2CHAR(p))
+	    prev = tail;
+	    MB_PTR_BACK(head, prev);
+	    c1 = PTR2CHAR(prev);
+	    if (mask == NULL)
+	    {
+		if (c1 > ' ' && c1 != 0xa0)
 		    break;
-	    if (*p == NUL)
-		break;
+	    }
+	    else
+	    {
+		for (p = mask; *p != NUL; MB_PTR_ADV(p))
+		    if (c1 == PTR2CHAR(p))
+			break;
+		if (*p == NUL)
+		    break;
+	    }
 	}
     }
     rettv->vval.v_string = vim_strnsave(head, (int)(tail - head));