1 /* $Id$
2  *  Provide extra set of functions to operate with strings.
3  *
4  * HUSKYLIB: common defines, types and functions for HUSKY
5  *
6  * This is part of The HUSKY Fidonet Software project:
7  * see http://husky.sourceforge.net for details
8  *
9  *
10  * HUSKYLIB is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * HUSKYLIB is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; see file COPYING. If not, write to the
22  * Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  * See also http://www.gnu.org, license may be found here.
25  */
26 
27 #ifndef HUSKY_STREXT_H__
28 #define HUSKY_STREXT_H__
29 
30 /* huskylib: compiler.h */
31 #include "compiler.h"
32 
33 /* huskylib headers */
34 #include "huskyext.h"  /* compiler see directory of this .h file */
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 /* Replace last char with '\0' if last char is strip-char
41  */
42 HUSKYEXT char *_fast Strip_Trailing(char *str, char strip);
43 
44 /* Add add-char to end of string (size of the str is not checked!!!)
45  */
46 HUSKYEXT char *_fast Add_Trailing(char *str, char add);
47 
48 /* Copy src to dst; return src
49  */
50 HUSKYEXT char *_fast strocpy(char *dst, const char *src);
51 
52 /* Return pointer to 1st char of specified word in string (by word number)
53  */
54 HUSKYEXT char* _fast firstchar(const char *strng, const char *delim, int findword);
55 
56 
57 HUSKYEXT char *strrstr(const char *HAYSTACK, const char *NEEDLE);
58 
59 /*DOC
60   Input:  two constant null-terminated strings
61   Output: NULL or the point to a null-terminated string
62   FZ:     finds the LAST occurence of NEEDLE in HAYSTACK
63           (same as strstr but last occurence
64 */
65 
66 HUSKYEXT char *fc_stristr(const char *str, const char *find);
67 /*
68  * Find the first occurrence of find in s ignoring case
69  */
70 
71 HUSKYEXT char   *stripLeadingChars(char *str, const char *chr);
72 /*DOC
73   Input:  str is a \0-terminated string
74           chr contains a list of characters.
75   Output: stripLeadingChars returns a pointer to a string
76   FZ:     all leading characters which are in chr are deleted.
77           str is changed and returned.
78 */
79 
80 
81 /*DOC
82   Input:  str is a \0-terminated string
83           chr contains a list of characters.
84   Output: stripTrailingChars returns a pointer to a string
85   FZ:     all trailing characters which are in chr are deleted.
86           str is changed and returned (not reallocated, simply shorted).
87 */
88 HUSKYEXT char *stripTrailingChars(char *str, const char *chr);
89 
90 
91 #define stripRoundingChars(str,chrs) (stripTrailingChars(stripLeadingChars((str),(chrs)),(chrs)))
92 
93 
94 HUSKYEXT char   *strUpper(char *str);
95 /*DOC
96   Input:  str is a \0 terminated string
97   Output: str
98   FZ:     strUpper converts the string from lower case to upper case.
99   */
100 
101 HUSKYEXT char   *strLower(char *str);
102 /*DOC
103   Input:  str is a \0 terminated string
104   Output: str
105   FZ:     strLower converts the string from upper case to lower case.
106 */
107 
108 HUSKYEXT char *sstrdup(const char *src);
109 
110 /* safe strdup for line part */
111 #define sstrndup(src,len) strncpy(smalloc(len),src,len)
112 
113 /* safe strlen: if src==NULL return 0 */
114 #define sstrlen(src) ( src ? strlen(src) : 0 )
115 
116 /* safe strcpy: if src==NULL or dst==NULL don't copy and return NULL */
117 #define sstrcpy(dst,src) ( (src)&&(dst) ? strcpy(dst,src) : NULL )
118 
119 /* safe strncpy: if src==NULL or dst==NULL don't copy and return NULL */
120 #define sstrncpy(dst,src,len) ( (src)&&(dst) ? strncpy(dst,src,len) : NULL )
121 
122 /* Copyes not more than len chars from src into dst, but, unlike strncpy(),
123  * it appends '\0' even if src is longer than len.
124  * Return dst
125  * Prevent memory faults:
126  *  - if dst is NULL doing nothing and return NULL
127  *  - if src is NULL and dst not NULL store '\0' into dst[0] and return it.
128  */
129 HUSKYEXT char *strnzcpy (char *dst, const char *src, size_t len);
130 
131 /* Concantenates not more than len chars from src into dst, but, unlike
132  * strncat(), it appends '\0' even if src is longer than len.
133  * Return dst
134  * Prevent memory faults:
135  *  - if dst is NULL doing nothing and return NULL
136  *  - if src is NULL doing nothing and return dst.
137  */
138 HUSKYEXT char *strnzcat (char *dst, const char *src, size_t len);
139 
140 /* safe strstr: if str==NULL or find==NULL return NULL */
141 #define sstrstr(str,find) ( (str)&&(find) ? strstr(str,find) : NULL )
142 
143 /* safe stristr: if str==NULL or find==NULL return NULL */
144 #define sstristr(str,find) ( (str)&&(find) ? fc_stristr(str,find) : NULL )
145 
146 /* safe strcmp */
147 HUSKYEXT int sstrcmp(const char *str1, const char *str2);
148 
149 /* safe strncmp */
150 HUSKYEXT int sstrncmp(const char *str1, const char *str2, size_t length);
151 
152 /* safe stricmp (case-insencitive) */
153 HUSKYEXT int sstricmp(const char *str1, const char *str2);
154 
155 /* safety strnicmp (case-insencitive) */
156 HUSKYEXT int sstrnicmp(const char *str1, const char *str2, size_t length);
157 
158 /* safety string envelope (use this in functions calls) */
159 #define sstr(ss) ( ss ? ss : "" )
160 
161 
162 HUSKYEXT char *strseparate(register char **stringp, register const char *delim);
163 
164 /* Extract contents from CVS/RCS keyvords (like $Revision$)
165  * Return malloc'ed string
166  */
167 HUSKYEXT char *extract_CVS_keyword(char *str);
168 
169 /* Convert char to integer with range checking
170  */
171 HUSKYEXT int ctoi(const char *s);
172 
173 /* Copy string from str to (*pmem), allocating memory as needed
174    NOTE! *pmem must be NULL, if not NULL, it will be free().
175  */
176 HUSKYEXT int copyString(char *str, char **pmem);
177 
178 /* Copy chars from str to (*dest) until one of the chars in seps appears
179  * memory is allocated as needed
180  * *dest will be freed if non-NULL
181  * returns number of chars copied
182  */
183 HUSKYEXT int copyStringUntilSep(char *str, char *seps, char **dest);
184 
185 /* Structures for compact storage of array of NUL-terminated strings of
186  * various length.
187  * s_str_array is just one memory allocation and contains no pointers,
188  * so it can be freed by single free() and copied with memcpy()
189  * Use for nonmutable collections of (short) strings.
190  */
191 typedef union str_mess {
192 	int offsets[1];   /* offsets in bytes from start of union, used as index for strings[] */
193 	char strings[1];  /* NUL-terminated strings */
194 } u_str_mess;
195 
196 typedef struct str_array {
197 	int count;        /* Number of entries in data.offset array */
198 	u_str_mess data;
199 } s_str_array;
200 
201 /* Get an address of n-th string in s_str_array *a */
202 #define STR_N(a,n) &((a)->data.strings[(a)->data.offsets[n]])
203 
204 /* Offset of a byte just after last allocated byte (after last '\0') */
205 #define STR_A_OFFSET_END(a) (a->data.offsets[a->count-1] + \
206                           strlen(STR_N(a, a->count-1)) + 1)
207 
208 /* Calculate used memory size for s_str_array *a */
209 #define STR_A_SIZE(a) (offsetof(s_str_array, data) + \
210                       STR_A_OFFSET_END(a))
211 
212 /* Calculate memory size used for strings in s_str_array->data.strings[] */
213 #define STR_A_SSIZE(a) (STR_A_OFFSET_END(a) - \
214 		               a->data.offsets[0])
215 
216 /* Get an index of 'find' in ss
217  * Case insensitive full match is used
218  * -1 if no match */
219 HUSKYEXT int findInStrArray(s_str_array const *ss, char const *find);
220 
221 HUSKYEXT s_str_array *copyStrArray(s_str_array *ss);
222 
223 /* Parse strings like "token1, token2,token3 token4" into s_str_array */
224 HUSKYEXT s_str_array *makeStrArray(char *token);
225 
226 HUSKYEXT char *StrArray2String(s_str_array *ss);
227 
228 #ifdef __cplusplus
229 }
230 #endif
231 
232 #endif
233