1 /*
2  * Copyright (c) 1998, 1999, 2000, 2004, 2006, 2010, 2015
3  *	Tama Communications Corporation
4  *
5  * This file is part of GNU GLOBAL.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #ifdef STDC_HEADERS
25 #include <stdlib.h>
26 #endif
27 
28 #include "strbuf.h"
29 #include "strmake.h"
30 
31 /**
32  * strmake: make string from original string with limit character.
33  *
34  *	@param[in]	p	original string.
35  *	@param[in]	lim	limitter
36  *	@return		result string
37  *
38  * Usage:
39  *	strmake("aaa:bbb", ":/=")	=> "aaa"
40  *
41  * [Note] The result string area is function local. So, following call
42  *	 to this function may destroy the area.
43  */
44 const char *
strmake(const char * p,const char * lim)45 strmake(const char *p, const char *lim)
46 {
47 	STATIC_STRBUF(sb);
48 	const char *c;
49 
50 	strbuf_clear(sb);
51 	for (; *p; p++) {
52 		for (c = lim; *c; c++)
53 			if (*p == *c)
54 				goto end;
55 		strbuf_putc(sb,*p);
56 	}
57 end:
58 	return strbuf_value(sb);
59 }
60 
61 /**
62  * strtrim: make string from original string with deleting blanks.
63  *
64  *	@param[in]	p	original string.
65  *	@param[in]	flag	TRIM_HEAD:	from only head,
66  *			TRIM_TAIL:	from only tail,
67  *			TRIM_BOTH:	from head and tail,
68  *			TRIM_ALL:	from all
69  *	@param[out]	len	length of result string,
70  *			if len == NULL then nothing returned.
71  *	@return		result string
72  *
73  * Usage:
74  *	strtrim(" # define ", TRIM_HEAD, NULL)	=> "# define "
75  *	strtrim(" # define ", TRIM_TAIL, NULL)	=> " # define"
76  *	strtrim(" # define ", TRIM_BOTH, NULL)	=> "# define"
77  *	strtrim(" # define ", TRIM_ALL, NULL)	=> "#define"
78  *
79  * [Note] The result string area is function local. So, following call
80  *	 to this function may destroy the area.
81  */
82 const char *
strtrim(const char * p,int flag,int * len)83 strtrim(const char *p, int flag, int *len)
84 {
85 	STATIC_STRBUF(sb);
86 	int cut_off = -1;
87 
88 	strbuf_clear(sb);
89 	/*
90 	 * Delete blanks of the head.
91 	 */
92 	if (flag != TRIM_TAIL)
93 		SKIP_BLANKS(p);
94 	/*
95 	 * Copy string.
96 	 */
97 	for (; *p; p++) {
98 		if (isspace(*p)) {
99 			if (flag != TRIM_ALL) {
100 				if (cut_off == -1 && flag != TRIM_HEAD)
101 					cut_off = strbuf_getlen(sb);
102 				strbuf_putc(sb,*p);
103 			}
104 		} else {
105 			strbuf_putc(sb,*p);
106 			cut_off = -1;
107 		}
108 	}
109 	/*
110 	 * Delete blanks of the tail.
111 	 */
112 	if (cut_off != -1)
113 		strbuf_setlen(sb, cut_off);
114 	if (len)
115 		*len = strbuf_getlen(sb);
116 	return strbuf_value(sb);
117 }
118 /**
119  * strcmp with terminate character.
120  *
121  *	@param[in]	s1	string1
122  *	@param[in]	s2	string2
123  *	@param[in]	term	terminate character
124  *	@return		==0: equal, !=0: not equal
125  *
126  * Usage:
127  *	strcmp_withterm("aaa", "aaa", ':')		=> 0
128  *	strcmp_withterm("aaa:bbb", "aaa", ':')		=> 0
129  *	strcmp_withterm("aaa:bbb", "aaa:ccc", ':')	=> 0
130  *	strcmp_withterm("aaa/bbb", "aaa/ccc", ':')	=> -1
131  */
132 int
strcmp_withterm(const char * s1,const char * s2,int term)133 strcmp_withterm(const char *s1, const char *s2, int term)
134 {
135 	unsigned int c1, c2;
136 
137 	do {
138 		c1 = *s1++;
139 		c2 = *s2++;
140 		/* replace terminate character with NULL */
141 		if (c1 == term)
142 			c1 = '\0';
143 		if (c2 == term)
144 			c2 = '\0';
145 	} while (c1 == c2 && c1 != '\0');
146 
147 	return c1 - c2;
148 }
149 /**
150  * strcpy with terminate character.
151  *
152  *	@param[in]	b	buffer
153  *	@param[in]	s	string
154  *	@param[in]	size	buffer size
155  *	@param[in]	term	terminate character
156  *	@return		terminator's position
157  */
158 const char *
strcpy_withterm(char * b,const char * s,int size,int term)159 strcpy_withterm(char *b, const char *s, int size, int term)
160 {
161 	char *endp = b + size - 1;
162 
163 	while (*s && *s != term)
164 		if (b < endp)
165 			*b++ = *s++;
166 	*b = '\0';
167 
168 	return s;
169 }
170 /**
171  * remove character c in the string s.
172  *
173  *	@param[in]	s	string
174  *	@param[in]	c	should be removed
175  */
176 void
strremovechar(char * s,int c)177 strremovechar(char *s, int c)
178 {
179 	STATIC_STRBUF(sb);
180 	char *p;
181 
182 	strbuf_clear(sb);
183 	for (p = s; *p; p++)
184 		if (*p != c)
185 			strbuf_putc(sb, *p);
186 	strcpy(s, strbuf_value(sb));
187 }
188