7 str_dup(const char *src
) {
10 if (s
== NULL
) abort();
15 verifie si la chaine est vide (cad si elle ne contient que des caractères non imprimables
18 str_is_empty(const char *s
) {
20 if (s
== NULL
) return 1;
21 else if (strlen(s
) == 0) return 1;
24 while (s
[i
] && s
[i
] <= ' ') i
++;
25 return (i
== (int)strlen(s
));
30 /* recherche la première occurence d'une des chaines 'keys' dans 'src' et renvoie un pointeur vers
31 cette occurence, ainsi que le numéro de la 'keys' trouvée
33 bien sûr c'est pas optimal du tout, mais ON S'EN FOUT(tm)
35 et oui, effectivement, 'str_multi_str' est un nom à la con
38 str_multi_str(const char *src
, const char **keys
, int nb_keys
, int *key_idx
)
46 for (i
=0; i
< nb_keys
; i
++) {
48 p
= strstr(src
, keys
[i
]);
49 if (p
&& (res
==NULL
|| p
< res
)) { res
= p
; *key_idx
= i
; }
54 /* renvoie une chaine (allouée correctement) contenant la substitution de toutes les occurences de
55 'key' dans 'src' par 'substitution' (key et substition sont des tableaux de chaines de
56 caractères, car pour faire plusieurs substitutions, mieux vaut les effectuer simultanement que
57 les enchainer pour eviter les effets de bords
60 str_multi_substitute(const char *src
, const char **keys
, const char **substitutions
, int nkeys
)
62 const char *p
, *p_key
;
66 if (src
== NULL
) return NULL
;
68 /* calcul de la longueur de la destination.. */
70 dest_sz
= strlen(src
)+1;
72 while ((p_key
=str_multi_str(p
, keys
, nkeys
, &j
))) {
73 dest_sz
+= (strlen(substitutions
[j
]) - strlen(keys
[j
]));
74 p
= p_key
+strlen(keys
[j
]);
77 dest
= malloc(dest_sz
);
82 while ((p_key
=str_multi_str(p
, keys
, nkeys
, &j
))) {
83 memcpy(p_dest
, p
, p_key
-p
);
85 memcpy(p_dest
, substitutions
[j
], strlen(substitutions
[j
]));
86 p_dest
+= strlen(substitutions
[j
]);
87 p
= p_key
+ strlen(keys
[j
]);
91 memcpy(p_dest
, p
, p_len
); p_dest
+= p_len
;
94 assert(p_dest
- dest
== dest_sz
-1); /* capote à bugs */
99 str_substitute(const char *src
, const char *key
, const char *substitution
) {
100 return str_multi_substitute(src
, &key
, &substitution
, 1);
103 /* quotage pour les commandes externes.. à priori c'est comme pour open_url
104 mais bon.. je me refuse à donner la moindre garantie sur la sécurité
109 shell_quote(const char *src
)
111 char *quote
= "&;`'\\\"|*?~<>^()[]{}$ ";
116 if (src
== NULL
|| strlen(src
) == 0) return strdup("");
118 dest_sz
= strlen(src
)+1;
119 for (p
=src
; *p
; p
++) {
120 if (strchr(quote
, *p
)) dest_sz
+=1;
122 dest
= malloc(dest_sz
);
124 for (p
=src
, i
=0; *p
; p
++) {
125 if (strchr(quote
, *p
)) {
128 if (*p
>=0 && *p
< ' ') {
135 assert(i
== dest_sz
-1); /* kapeaute à beugue */
140 static unsigned *crc_table
= NULL
;
142 void gen_crc_table(void) /* build the crc table */
148 for (i
= 0; i
< 256; i
++)
151 for (j
= 8; j
> 0; j
--)
154 crc
= (crc
>> 1) ^ poly
;
163 unsigned str_hash(const unsigned char *s
, int max_len
) /* calculate the crc value */
168 if (crc_table
== NULL
) {
169 crc_table
= calloc(256, sizeof(unsigned));
173 for (i
=0; i
< max_len
&& s
[i
]; i
++) {
174 crc
= ((crc
>>8) & 0x00FFFFFF) ^ crc_table
[ (crc
^s
[i
]) & 0xFF ];
176 return( crc
^0xFFFFFFFF );
180 unsigned char char_trans
[256];
181 static int char_trans_init
= 0;
186 const unsigned char *trans_accents
=
187 (const unsigned char*) "éèëêÊËÉÈàâáäÀÂÁÄûüùÙçÇîïíìÏÎÍÌôóòõÔÓÒÕñ";
188 const unsigned char *trans_accents2
=
189 (const unsigned char*) "eeeeeeeeaaaaaaaauuuucciiiiiiiioooooooon";
192 for (i
=0; i
< 256; i
++) {
194 if ((p
=(unsigned char*)strchr((char*)trans_accents
, i
))) {
195 char_trans
[i
] = trans_accents2
[(p
- trans_accents
)];
196 } else if (i
< (unsigned char)'A' || i
> (unsigned char)'Z') {
199 char_trans
[i
] = i
+ 'a' - 'A';
206 chr_noaccent_tolower(unsigned char c
)
208 if (char_trans_init
== 0) init_char_trans();
209 return char_trans
[c
];
213 str_noaccent_tolower(unsigned char *s
)
216 if (s
== NULL
) return;
217 if (char_trans_init
== 0) init_char_trans();
219 s
[i
] = char_trans
[s
[i
]]; i
++;
224 str_noaccent_casestr(const unsigned char *meule
, const unsigned char *aiguille
)
227 char *m
= strdup((char*)meule
);
228 char *a
= strdup((char*)aiguille
);
230 str_noaccent_tolower((unsigned char*)m
);
231 str_noaccent_tolower((unsigned char*)a
);
232 res
= (unsigned char*)strstr(m
, a
);
237 /* un printf pas très fin, mais avec allocation dynamique..
238 c'est pratique ces ptites choses */
240 str_printf(const char *fmt
, ...)
246 s_sz
= 10; /* a reaugmenter des que la fonction est validee : */
247 s
= malloc(s_sz
); assert(s
);
251 ret
= vsnprintf(s
, s_sz
, fmt
, ap
);
253 if (ret
== -1 || ret
>= s_sz
-1) {
255 assert(s_sz
< 100000);
256 s
= realloc(s
, s_sz
); assert(s
);
260 s
= realloc(s
, strlen(s
)+1); assert(s
);
264 /* read a line in a file and return the result in a dynamically
267 str_fget_line(FILE *f
)
273 s_sz
= 100; s
= malloc(s_sz
); assert(s
);
275 while ((c
= fgetc(f
)) > 0) {
276 if (c
>= ' ' || c
== '\t') {
279 s_sz
*= 2; assert(s_sz
< 100000);
280 s
= realloc(s
, s_sz
); assert(s
);
283 if (c
== '\n') break;
285 s
[i
] = 0; assert(i
< s_sz
);
286 s
= realloc(s
, strlen(s
)+1); assert(s
);
290 /* remove spaces at the beginning and at the end */
292 str_trim(unsigned char *s
) {
295 if (s
== NULL
) return;
296 j
= strlen((char*)s
)-1;
297 while (j
>=0 && s
[j
] <= ' ') s
[j
--] = 0;
300 while (s
[i
] && s
[i
] <= ' ') i
++;
302 memmove(s
, s
+i
, j
+2-i
);
306 /* insertion into a string list */
307 strlist
*strlist_ins(strlist
*head
, const char *s
) {
308 strlist
*p
; ALLOC_OBJ(p
);
309 p
->s
= strdup(s
); p
->next
= head
; return p
;