1 /* Removes leading and/or trailing whitespaces
2 Copyright (C) 2006-2023 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17 /* Written by Davide Angelocola <davide.angelocola@gmail.com> */
18
19 #include <config.h>
20
21 /* Specification. */
22 #include "trim.h"
23
24 #include <ctype.h>
25 #include <string.h>
26 #include <stddef.h>
27 #include <stdlib.h>
28
29 #include "mbchar.h"
30 #include "mbiter.h"
31 #include "xalloc.h"
32
33 char *
34 trim2 (const char *s, int how)
35 {
36 char *d;
37
38 d = strdup (s);
39
40 if (!d)
41 xalloc_die ();
42
43 if (MB_CUR_MAX > 1)
44 {
45 mbi_iterator_t i;
46
47 /* Trim leading whitespaces. */
48 if (how != TRIM_TRAILING)
49 {
50 mbi_init (i, d, strlen (d));
51
52 for (; mbi_avail (i) && mb_isspace (mbi_cur (i)); mbi_advance (i))
53 ;
54
55 memmove (d, mbi_cur_ptr (i), strlen (mbi_cur_ptr (i)) + 1);
56 }
57
58 /* Trim trailing whitespaces. */
59 if (how != TRIM_LEADING)
60 {
61 char *start_of_spaces = NULL;
62
63 mbi_init (i, d, strlen (d));
64
65 for (; mbi_avail (i); mbi_advance (i))
66 if (mb_isspace (mbi_cur (i)))
67 {
68 if (start_of_spaces == NULL)
69 start_of_spaces = (char *) mbi_cur_ptr (i);
70 }
71 else
72 start_of_spaces = NULL;
73
74 if (start_of_spaces != NULL)
75 *start_of_spaces = '\0';
76 }
77 }
78 else
79 {
80 char *p;
81
82 /* Trim leading whitespaces. */
83 if (how != TRIM_TRAILING)
84 {
85 for (p = d; *p && isspace ((unsigned char) *p); p++)
86 ;
87
88 memmove (d, p, strlen (p) + 1);
89 }
90
91 /* Trim trailing whitespaces. */
92 if (how != TRIM_LEADING)
93 {
94 for (p = d + strlen (d) - 1;
95 p >= d && isspace ((unsigned char) *p); p--)
96 *p = '\0';
97 }
98 }
99
100 return d;
101 }