Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Make sure we don't went out of the string to handle *before* using it (thx valgrind)
[simgrid.git] / src / xbt / xbt_str.c
1
2 /* xbt_str.c - various helping functions to deal with strings               */
3
4 /* Copyright (C) 2005-2007 Malek Cherier, Martin Quinson.                   */
5 /* All rights reserved.                                                     */
6
7 /* This program is free software; you can redistribute it and/or modify it
8  * under the terms of the license (GNU LGPL) which comes with this package. 
9  */
10
11 /* Returns the string without leading whitespaces (xbt_str_ltrim), 
12  * trailing whitespaces (xbt_str_rtrim),
13  * or both leading and trailing whitespaces (xbt_str_trim). 
14  * (in-place modification of the string)
15  */
16   
17 #include "xbt/misc.h"
18 #include "xbt/sysdep.h"
19 #include "xbt/str.h" /* headers of these functions */
20 #include "portable.h"
21
22 /**  @brief Strip whitespace (or other characters) from the end of a string.
23  *
24  * This function returns a string with whitespace stripped from the end of s. 
25  * By default (without the second parameter char_list), xbt_str_rtrim() will strip these characters :
26  *      
27  *      - " "           (ASCII 32       (0x20)) space. 
28  *      - "\t"          (ASCII 9        (0x09)) tab. 
29  *      - "\n"          (ASCII 10       (0x0A)) line feed. 
30  *      - "\r"          (ASCII 13       (0x0D)) carriage return. 
31  *      - "\0"          (ASCII 0        (0x00)) NULL. 
32  *      - "\x0B"        (ASCII 11       (0x0B)) vertical tab. 
33  *
34  * @param s The string to strip.
35  * @param char_list A string which contains the characters you want to strip.
36  *
37  * @return If the specified is NULL the function returns NULL. Otherwise the
38  * function returns the string with whitespace stripped from the end.
39  */
40 char*
41 xbt_str_rtrim(char* s, const char* char_list)
42 {
43         char* cur = s;
44         const char* __char_list = " \t\n\r\x0B";
45         char white_char[256] = {1,0};
46         
47         if(!s)
48                 return NULL;
49
50         if(!char_list){
51                 while(*__char_list) {
52                         white_char[(unsigned char)*__char_list++] = 1;
53                 }
54         }else{
55                 while(*char_list) {
56                         white_char[(unsigned char)*char_list++] = 1;
57                 }
58         }
59
60         while(*cur)
61                 ++cur;
62
63         while((cur >= s) && white_char[(unsigned char)*cur])
64                 --cur;
65
66         *++cur = '\0';
67         return s;
68 }
69
70 /**  @brief Strip whitespace (or other characters) from the beginning of a string.
71  *
72  * This function returns a string with whitespace stripped from the beginning of s. 
73  * By default (without the second parameter char_list), xbt_str_ltrim() will strip these characters :
74  *      
75  *      - " "           (ASCII 32       (0x20)) space. 
76  *      - "\t"          (ASCII 9        (0x09)) tab. 
77  *      - "\n"          (ASCII 10       (0x0A)) line feed. 
78  *      - "\r"          (ASCII 13       (0x0D)) carriage return. 
79  *      - "\0"          (ASCII 0        (0x00)) NULL. 
80  *      - "\x0B"        (ASCII 11       (0x0B)) vertical tab. 
81  *
82  * @param s The string to strip.
83  * @param char_list A string which contains the characters you want to strip.
84  *
85  * @return If the specified is NULL the function returns NULL. Otherwise the
86  * function returns the string with whitespace stripped from the beginning.
87  */
88 char*
89 xbt_str_ltrim( char* s, const char* char_list)
90 {
91         char* cur = s;
92         const char* __char_list = " \t\n\r\x0B";
93         char white_char[256] = {1,0};
94         
95         if(!s)
96                 return NULL;
97
98         if(!char_list){
99                 while(*__char_list) {
100                         white_char[(unsigned char)*__char_list++] = 1;
101                 }
102         }else{
103                 while(*char_list) {
104                         white_char[(unsigned char)*char_list++] = 1;
105                 }
106         }
107
108         while(*cur && white_char[(unsigned char)*cur])
109                 ++cur;
110
111         return memmove(s,cur, strlen(cur));
112 }
113
114 /**  @brief Strip whitespace (or other characters) from the end and the begining of a string.
115  *
116  * This returns a string with whitespace stripped from the end and the begining of s. 
117  * By default (without the second parameter char_list), xbt_str_trim() will strip these characters :
118  *      
119  *      - " "           (ASCII 32       (0x20)) space. 
120  *      - "\t"          (ASCII 9        (0x09)) tab. 
121  *      - "\n"          (ASCII 10       (0x0A)) line feed. 
122  *      - "\r"          (ASCII 13       (0x0D)) carriage return. 
123  *      - "\0"          (ASCII 0        (0x00)) NULL. 
124  *      - "\x0B"        (ASCII 11       (0x0B)) vertical tab. 
125  *
126  * @param s The string to strip.
127  * @param char_list A string which contains the characters you want to strip.
128  *
129  * @return If the specified is NULL the function returns NULL. Otherwise the
130  * function returns the string with whitespace stripped from the end and the begining.
131  */
132 char* 
133 xbt_str_trim(char* s, const char* char_list ){
134         
135         if(!s)
136                 return NULL;
137                 
138     return xbt_str_ltrim(xbt_str_rtrim(s,char_list),char_list);
139 }
140
141 /**  @brief Replace double whitespaces (but no other characters) from the string.
142  *
143  * The function modifies the string so that each time that several spaces appear,
144  * they are replaced by a single space. It will only do so for spaces (ASCII 32, 0x20). 
145  *
146  * @param s The string to strip. Modified in place.
147  *
148  */
149 void
150 xbt_str_strip_spaces(char *s) {
151   char *p = s;
152   int   e = 0;
153
154   if (!s)
155     return;
156
157   while (1) {
158     if (!*p)
159       goto end;
160     
161     if (*p != ' ')
162       break;
163     
164     p++;
165   }
166   
167   e = 1;
168   
169   do {
170     if (e)
171       *s++ = *p;
172     
173     if (!*++p)
174       goto end;
175     
176     if (e ^ (*p!=' '))
177       if ((e = !e))
178         *s++ = ' ';
179   } while (1);
180
181  end:
182   *s = '\0';
183 }
184    
185 #ifndef HAVE_GETLINE
186 long getline(char **buf, size_t *n, FILE *stream) {
187    
188    int i, ch;
189    
190    if (!*buf) {
191      *buf = xbt_malloc(512);
192      *n = 512;
193    }
194    
195    if (feof(stream))
196      return (ssize_t)-1;
197    
198    for (i=0; (ch = fgetc(stream)) != EOF; i++)  {
199         
200       if (i >= (*n) + 1)
201         *buf = xbt_realloc(*buf, *n += 512);
202         
203       (*buf)[i] = ch;
204         
205       if ((*buf)[i] == '\n')  {
206          i++;
207          (*buf)[i] = '\0';
208          break;
209       }      
210    }
211       
212    if (i == *n) 
213      *buf = xbt_realloc(*buf, *n += 1);
214    
215    (*buf)[i] = '\0';
216
217    return (ssize_t)i;
218 }
219
220 #endif /* HAVE_GETLINE */