Remove mgu_free_list() and mgu_free_dlist()
[claws.git] / src / common / mgutils.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2001-2015 Match Grun and the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /*
20  * Definitions for generic functions.
21  */
22
23 #include <glib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #include "mgutils.h"
29
30 /*
31 * Dump linked list of character strings (for debug).
32 */
33 void mgu_print_list( GSList *list, FILE *stream ) {
34         GSList *node = list;
35         while( node ) {
36                 int r = fprintf( stream, "\t- >%s<\n", (gchar *)node->data );
37                 if (r < 0) {
38                         perror("fprintf");
39                         break;
40                 }
41                 node = g_slist_next( node );
42         }
43 }
44
45 /*
46 * Dump linked list of character strings (for debug).
47 */
48 void mgu_print_dlist( GList *list, FILE *stream ) {
49         GList *node = list;
50         while( node ) {
51                 int r = fprintf( stream, "\t- >%s<\n", (gchar *)node->data );
52                 if (r < 0) {
53                         perror("fprintf");
54                         break;
55                 }
56                 node = g_list_next( node );
57         }
58 }
59
60 /*
61 * Coalesce linked list of characaters into one long string.
62 */
63 gchar *mgu_list_coalesce( GSList *list ) {
64         gchar *str = NULL;
65         gchar *buf = NULL;
66         gchar *start = NULL;
67         GSList *node = NULL;
68         gint len;
69
70         if( ! list ) return NULL;
71
72         /* Calculate maximum length of text */
73         len = 0;
74         node = list;
75         while( node ) {
76                 str = node->data;
77                 len += 1 + strlen( str );
78                 node = g_slist_next( node );
79         }
80
81         /* Create new buffer. */
82         buf = g_new0( gchar, len+1 );
83         start = buf;
84         node = list;
85         while( node ) {
86                 str = node->data;
87                 len = strlen( str );
88                 strcpy( start, str );
89                 start += len;
90                 node = g_slist_next( node );
91         }
92         return buf;
93 }
94
95 /*
96 * Replace existing string with new string.
97 */
98 gchar *mgu_replace_string( gchar *str, const gchar *value ) {
99         g_free( str );
100         if( value ) {
101                 str = g_strdup( value );
102                 g_strstrip( str );
103         }
104         else {
105                 str = NULL;
106         }
107         return str;
108 }
109
110 /*
111 * Test and reformat an email address.
112 * Enter:  address.
113 * Return: Address, or NULL if address is empty.
114 * Note: Leading and trailing white space is removed.
115 */
116 gchar *mgu_email_check_empty( gchar *address ) {
117         gchar *retVal = NULL;
118         if( address ) {
119                 retVal = g_strdup( address );
120                 retVal = g_strstrip( retVal );
121                 if( *retVal == '\0' ) {
122                         g_free( retVal );
123                         retVal = NULL;
124                 }
125         }
126         return retVal;
127 }
128
129 /*
130 * Parse string into linked list. Whitespace is used as a delimiter in parsing.
131 * Strings are parsed until maxTokens - 1 is reached. The remainder of the
132 * input string is copied into last element of list.
133 * Enter: line      String to parse.
134 *        maxTokens Maximum number of tokens to parse.
135 *        tokenCnt  If arg supplied, update with count of number of token parsed.
136 * Return: Linked list. The list contents should be g_free'd and list should
137 * freed when done.
138 */
139 GList *mgu_parse_string( gchar *line, const gint maxTokens, gint *tokenCnt ) {
140         gchar *ptr, *pStart, *pFound, *str;
141         gint  args = 0;
142         GList *list = NULL;
143         gboolean done = FALSE;
144
145         if( tokenCnt ) *tokenCnt = 0;
146         if( line == NULL ) return NULL;
147         if( maxTokens < 1 ) return NULL;
148
149         ptr = line;
150         while( ! done ) {
151                 args++;
152                 /* Skip over leading spaces */
153                 while( *ptr ) {
154                         if( ! isspace( *ptr ) ) break;
155                         ptr++;  
156                 }
157
158                 /* Find terminating space */
159                 pFound = NULL;
160                 pStart = ptr;
161                 while( *ptr ) {
162                         if( isspace( *ptr ) ) {
163                                 pFound = pStart;
164                                 break;
165                         }
166                         ptr++;
167                 }
168
169                 if( pFound ) {
170                         if( args == maxTokens ) {
171                                 /* Rest of string */
172                                 str = g_strdup( pStart );
173                                 done = TRUE;
174                         }
175                         else {
176                                 /* Extract part of string */
177                                 str = g_strndup( pStart, ptr - pFound );
178                         }
179                 }
180                 else {
181                         /* Nothing there - treat as rest of string */
182                         str = g_strdup( pStart );
183                         done = TRUE;
184                 }
185                 list = g_list_append( list, str );
186         }
187         if( tokenCnt ) *tokenCnt = args;
188         return list;
189 }
190
191 /*
192  * Unescape characters by removing backslash character from input string.
193  * Enter: str String to process.
194  */
195 void mgu_str_unescape( gchar *str ) {
196         gchar *p;
197         gint ilen;
198
199         p = str;
200         while( *p ) {
201                 if( *p == '\\' ) {
202                         ilen = strlen( p + 1 );
203                         memmove( p, p + 1, ilen );
204                 }
205                 p++;
206         }
207 }
208
209 /*
210  * Replace leading and trailing characters (eg, quotes) in input string
211  * with spaces. Only matching non-blank characters that appear at both
212  * start and end of string are replaces. Control characters are also
213  * replaced with spaces.
214  * Enter: str    String to process.
215  *        chlea  Lead character to remove.
216  *        chtail Matching trailing character.
217  */
218 void mgu_str_ltc2space( gchar *str, gchar chlead, gchar chtail ) {
219         gchar *as;
220         gchar *ae;
221
222         /* Search forwards for first non-space match */
223         as = str;
224         ae = -1 + str + strlen( str );
225         while( as < ae ) {
226                 if( *as != ' ' ) {
227                         if( *as == chlead ) {
228                                 /* Search backwards from end for match */
229                                 while( ae > as ) {
230                                         if( *ae != ' ' ) {
231                                                 if( *ae == chtail ) {
232                                                         *as = ' ';
233                                                         *ae = ' ';
234                                                         return;
235                                                 }
236                                                 if( *ae < 32 ) {
237                                                         *ae = ' ';
238                                                 }
239                                                 else if( *ae == 127 ) {
240                                                         *ae = ' ';
241                                                 }
242                                                 else {
243                                                         return;
244                                                 }
245                                         }
246                                         ae--;
247                                 }
248                         }
249                         if( *as < 32 ) {
250                                 *as = ' ';
251                         }
252                         else if( *as == 127 ) {
253                                 *as = ' ';
254                         }
255                         else {
256                                 return;
257                         }
258                 }
259                 as++;
260         }
261         return;
262 }
263
264 /*
265  * Return reference to longest entry in the specified linked list.
266  * It is assumed that the list contains only gchar objects.
267  * Enter:  list List of gchar strings to examine.
268  * Return: Reference to longest entry, or NULL if nothing found.
269  */
270 gchar *mgu_slist_longest_entry( GSList *list ) {
271         GSList *node;
272         gchar *name = NULL;
273         gint iLen = 0, iLenT = 0;
274
275         node = list;
276         while( node ) {
277                 if( name == NULL ) {
278                         name = node->data;
279                         iLen = strlen( name );
280                 }
281                 else {
282                         iLenT = strlen( node->data );
283                         if( iLenT > iLen ) {
284                                 name = node->data;
285                                 iLen = iLenT;
286                         }
287                 }
288                 node = g_slist_next( node );
289         }
290         return name;
291 }       
292
293 /*
294 * End of Source.
295 */