xref: /dflybsd-src/contrib/grep/lib/trim.c (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
195b7b453SJohn Marino /* Removes leading and/or trailing whitespaces
2*09d4459fSDaniel Fojt    Copyright (C) 2006-2020 Free Software Foundation, Inc.
395b7b453SJohn Marino 
495b7b453SJohn Marino    This program is free software: you can redistribute it and/or modify
595b7b453SJohn Marino    it under the terms of the GNU General Public License as published by
695b7b453SJohn Marino    the Free Software Foundation; either version 3 of the License, or
795b7b453SJohn Marino    (at your option) any later version.
895b7b453SJohn Marino 
995b7b453SJohn Marino    This program is distributed in the hope that it will be useful,
1095b7b453SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
1195b7b453SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1295b7b453SJohn Marino    GNU General Public License for more details.
1395b7b453SJohn Marino 
1495b7b453SJohn Marino    You should have received a copy of the GNU General Public License
15*09d4459fSDaniel Fojt    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
1695b7b453SJohn Marino 
1795b7b453SJohn Marino /* Written by Davide Angelocola <davide.angelocola@gmail.com> */
1895b7b453SJohn Marino 
1995b7b453SJohn Marino #include <config.h>
2095b7b453SJohn Marino 
2195b7b453SJohn Marino /* Specification.  */
2295b7b453SJohn Marino #include "trim.h"
2395b7b453SJohn Marino 
2495b7b453SJohn Marino #include <ctype.h>
2595b7b453SJohn Marino #include <string.h>
2695b7b453SJohn Marino #include <stddef.h>
2795b7b453SJohn Marino #include <stdlib.h>
2895b7b453SJohn Marino 
2995b7b453SJohn Marino #include "mbchar.h"
3095b7b453SJohn Marino #include "mbiter.h"
3195b7b453SJohn Marino #include "xalloc.h"
3295b7b453SJohn Marino 
33cf28ed85SJohn Marino /* Use this to suppress gcc's "...may be used before initialized" warnings. */
34*09d4459fSDaniel Fojt #if defined GCC_LINT || defined lint
3595b7b453SJohn Marino # define IF_LINT(Code) Code
3695b7b453SJohn Marino #else
3795b7b453SJohn Marino # define IF_LINT(Code) /* empty */
3895b7b453SJohn Marino #endif
3995b7b453SJohn Marino 
4095b7b453SJohn Marino char *
trim2(const char * s,int how)4195b7b453SJohn Marino trim2 (const char *s, int how)
4295b7b453SJohn Marino {
4395b7b453SJohn Marino   char *d;
4495b7b453SJohn Marino 
4595b7b453SJohn Marino   d = strdup (s);
4695b7b453SJohn Marino 
4795b7b453SJohn Marino   if (!d)
4895b7b453SJohn Marino     xalloc_die ();
4995b7b453SJohn Marino 
5095b7b453SJohn Marino   if (MB_CUR_MAX > 1)
5195b7b453SJohn Marino     {
5295b7b453SJohn Marino       mbi_iterator_t i;
5395b7b453SJohn Marino 
5495b7b453SJohn Marino       /* Trim leading whitespaces. */
5595b7b453SJohn Marino       if (how != TRIM_TRAILING)
5695b7b453SJohn Marino         {
5795b7b453SJohn Marino           mbi_init (i, d, strlen (d));
5895b7b453SJohn Marino 
5995b7b453SJohn Marino           for (; mbi_avail (i) && mb_isspace (mbi_cur (i)); mbi_advance (i))
6095b7b453SJohn Marino             ;
6195b7b453SJohn Marino 
6295b7b453SJohn Marino           memmove (d, mbi_cur_ptr (i), strlen (mbi_cur_ptr (i)) + 1);
6395b7b453SJohn Marino         }
6495b7b453SJohn Marino 
6595b7b453SJohn Marino       /* Trim trailing whitespaces. */
6695b7b453SJohn Marino       if (how != TRIM_LEADING)
6795b7b453SJohn Marino         {
68200fbe8dSJohn Marino           unsigned int state = 0;
6995b7b453SJohn Marino           char *r IF_LINT (= NULL); /* used only while state = 2 */
7095b7b453SJohn Marino 
7195b7b453SJohn Marino           mbi_init (i, d, strlen (d));
7295b7b453SJohn Marino 
7395b7b453SJohn Marino           for (; mbi_avail (i); mbi_advance (i))
7495b7b453SJohn Marino             {
7595b7b453SJohn Marino               if (state == 0 && mb_isspace (mbi_cur (i)))
7695b7b453SJohn Marino                 continue;
7795b7b453SJohn Marino 
7895b7b453SJohn Marino               if (state == 0 && !mb_isspace (mbi_cur (i)))
7995b7b453SJohn Marino                 {
8095b7b453SJohn Marino                   state = 1;
8195b7b453SJohn Marino                   continue;
8295b7b453SJohn Marino                 }
8395b7b453SJohn Marino 
8495b7b453SJohn Marino               if (state == 1 && !mb_isspace (mbi_cur (i)))
8595b7b453SJohn Marino                 continue;
8695b7b453SJohn Marino 
8795b7b453SJohn Marino               if (state == 1 && mb_isspace (mbi_cur (i)))
8895b7b453SJohn Marino                 {
8995b7b453SJohn Marino                   state = 2;
9095b7b453SJohn Marino                   r = (char *) mbi_cur_ptr (i);
9195b7b453SJohn Marino                 }
9295b7b453SJohn Marino               else if (state == 2 && mb_isspace (mbi_cur (i)))
9395b7b453SJohn Marino                 {
94200fbe8dSJohn Marino                   /* empty */
9595b7b453SJohn Marino                 }
9695b7b453SJohn Marino               else
9795b7b453SJohn Marino                 {
9895b7b453SJohn Marino                   state = 1;
9995b7b453SJohn Marino                 }
10095b7b453SJohn Marino             }
10195b7b453SJohn Marino 
10295b7b453SJohn Marino           if (state == 2)
10395b7b453SJohn Marino             *r = '\0';
10495b7b453SJohn Marino         }
10595b7b453SJohn Marino     }
10695b7b453SJohn Marino   else
10795b7b453SJohn Marino     {
10895b7b453SJohn Marino       char *p;
10995b7b453SJohn Marino 
11095b7b453SJohn Marino       /* Trim leading whitespaces. */
111200fbe8dSJohn Marino       if (how != TRIM_TRAILING)
112200fbe8dSJohn Marino         {
11395b7b453SJohn Marino           for (p = d; *p && isspace ((unsigned char) *p); p++)
11495b7b453SJohn Marino             ;
11595b7b453SJohn Marino 
11695b7b453SJohn Marino           memmove (d, p, strlen (p) + 1);
11795b7b453SJohn Marino         }
11895b7b453SJohn Marino 
11995b7b453SJohn Marino       /* Trim trailing whitespaces. */
120200fbe8dSJohn Marino       if (how != TRIM_LEADING)
121200fbe8dSJohn Marino         {
122200fbe8dSJohn Marino           for (p = d + strlen (d) - 1;
123200fbe8dSJohn Marino                p >= d && isspace ((unsigned char) *p); p--)
12495b7b453SJohn Marino             *p = '\0';
12595b7b453SJohn Marino         }
12695b7b453SJohn Marino     }
12795b7b453SJohn Marino 
12895b7b453SJohn Marino   return d;
12995b7b453SJohn Marino }
130