dockapps/wmhdplop/util.c

311 lines
6.8 KiB
C
Raw Normal View History

#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include "util.h"
char *
str_dup(const char *src) {
char *s;
s = strdup(src);
if (s == NULL) abort();
return s;
}
/*
verifie si la chaine est vide (cad si elle ne contient que des caract<EFBFBD>res non imprimables
*/
int
str_is_empty(const char *s) {
int i;
if (s == NULL) return 1;
else if (strlen(s) == 0) return 1;
else {
i = 0;
while (s[i] && s[i] <= ' ') i++;
return (i == (int)strlen(s));
}
}
/* recherche la premi<6D>re occurence d'une des chaines 'keys' dans 'src' et renvoie un pointeur vers
cette occurence, ainsi que le num<EFBFBD>ro de la 'keys' trouv<EFBFBD>e
bien s<EFBFBD>r c'est pas optimal du tout, mais ON S'EN FOUT(tm)
et oui, effectivement, 'str_multi_str' est un nom <EFBFBD> la con
*/
char *
str_multi_str(const char *src, const char **keys, int nb_keys, int *key_idx)
{
int i;
const char *res;
assert(key_idx);
*key_idx = 0;
res = NULL;
for (i=0; i < nb_keys; i++) {
const char *p;
p = strstr(src, keys[i]);
if (p && (res==NULL || p < res)) { res = p; *key_idx = i; }
}
return (char*)res;
}
/* renvoie une chaine (allou<6F>e correctement) contenant la substitution de toutes les occurences de
'key' dans 'src' par 'substitution' (key et substition sont des tableaux de chaines de
caract<EFBFBD>res, car pour faire plusieurs substitutions, mieux vaut les effectuer simultanement que
les enchainer pour eviter les effets de bords
*/
char *
str_multi_substitute(const char *src, const char **keys, const char **substitutions, int nkeys)
{
const char *p, *p_key;
char *dest, *p_dest;
int dest_sz, p_len,j;
if (src == NULL) return NULL;
/* calcul de la longueur de la destination.. */
p = src;
dest_sz = strlen(src)+1;
while ((p_key=str_multi_str(p, keys, nkeys, &j))) {
dest_sz += (strlen(substitutions[j]) - strlen(keys[j]));
p = p_key+strlen(keys[j]);
}
dest = malloc(dest_sz);
/* et l<> PAF ! */
p = src;
p_dest = dest;
while ((p_key=str_multi_str(p, keys, nkeys, &j))) {
memcpy(p_dest, p, p_key-p);
p_dest += p_key-p;
memcpy(p_dest, substitutions[j], strlen(substitutions[j]));
p_dest += strlen(substitutions[j]);
p = p_key + strlen(keys[j]);
}
p_len = strlen(p);
if (p_len) {
memcpy(p_dest, p, p_len); p_dest += p_len;
}
*p_dest = 0;
assert(p_dest - dest == dest_sz-1); /* capote <20> bugs */
return dest;
}
char *
str_substitute(const char *src, const char *key, const char *substitution) {
return str_multi_substitute(src, &key, &substitution, 1);
}
/* quotage pour les commandes externes.. <20> priori c'est comme pour open_url
mais bon.. je me refuse <EFBFBD> donner la moindre garantie sur la s<EFBFBD>curit<EFBFBD>
be aware
*/
char *
shell_quote(const char *src)
{
char *quote = "&;`'\\\"|*?~<>^()[]{}$ ";
int i,dest_sz;
const char *p;
char *dest;
if (src == NULL || strlen(src) == 0) return strdup("");
dest_sz = strlen(src)+1;
for (p=src; *p; p++) {
if (strchr(quote, *p)) dest_sz+=1;
}
dest = malloc(dest_sz);
for (p=src, i=0; *p; p++) {
if (strchr(quote, *p)) {
dest[i++] = '\\';
}
if (*p>=0 && *p < ' ') {
dest[i++] = ' ';
} else {
dest[i++] = *p;
}
}
dest[i] = 0;
assert(i == dest_sz-1); /* kapeaute <20> beugue */
return dest;
}
static unsigned *crc_table = NULL;
void gen_crc_table(void) /* build the crc table */
{
unsigned crc, poly;
int i, j;
poly = 0xEDB88320;
for (i = 0; i < 256; i++)
{
crc = i;
for (j = 8; j > 0; j--)
{
if (crc & 1)
crc = (crc >> 1) ^ poly;
else
crc >>= 1;
}
crc_table[i] = crc;
}
}
unsigned str_hash(const unsigned char *s, int max_len) /* calculate the crc value */
{
unsigned crc;
int i;
if (crc_table == NULL) {
crc_table = calloc(256, sizeof(unsigned));
gen_crc_table();
}
crc = 0xFFFFFFFF;
for (i=0; i < max_len && s[i]; i++) {
crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^s[i]) & 0xFF ];
}
return( crc^0xFFFFFFFF );
}
unsigned char char_trans[256];
static int char_trans_init = 0;
static void
init_char_trans()
{
const unsigned char *trans_accents =
(const unsigned char*) "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
const unsigned char *trans_accents2 =
(const unsigned char*) "eeeeeeeeaaaaaaaauuuucciiiiiiiioooooooon";
int i;
for (i=0; i < 256; i++) {
unsigned char *p;
if ((p=(unsigned char*)strchr((char*)trans_accents, i))) {
char_trans[i] = trans_accents2[(p - trans_accents)];
} else if (i < (unsigned char)'A' || i > (unsigned char)'Z') {
char_trans[i] = i;
} else {
char_trans[i] = i + 'a' - 'A';
}
}
char_trans_init = 1;
}
unsigned char
chr_noaccent_tolower(unsigned char c)
{
if (char_trans_init == 0) init_char_trans();
return char_trans[c];
}
void
str_noaccent_tolower(unsigned char *s)
{
int i;
if (s == NULL) return;
if (char_trans_init == 0) init_char_trans();
i = 0; while(s[i]) {
s[i] = char_trans[s[i]]; i++;
}
}
unsigned char *
str_noaccent_casestr(const unsigned char *meule, const unsigned char *aiguille)
{
unsigned char *res;
char *m = strdup((char*)meule);
char *a = strdup((char*)aiguille);
str_noaccent_tolower((unsigned char*)m);
str_noaccent_tolower((unsigned char*)a);
res = (unsigned char*)strstr(m, a);
free(a); free(m);
return res;
}
/* un printf pas tr<74>s fin, mais avec allocation dynamique..
c'est pratique ces ptites choses */
char *
str_printf(const char *fmt, ...)
{
va_list ap;
char *s;
int s_sz;
s_sz = 10; /* a reaugmenter des que la fonction est validee : */
s = malloc(s_sz); assert(s);
while (1) {
int ret;
va_start(ap, fmt);
ret = vsnprintf(s, s_sz, fmt, ap);
va_end(ap);
if (ret == -1 || ret >= s_sz-1) {
s_sz *= 2;
assert(s_sz < 100000);
s = realloc(s, s_sz); assert(s);
} else
break;
}
s = realloc(s, strlen(s)+1); assert(s);
return s;
}
/* read a line in a file and return the result in a dynamically
allocated buffer */
char *
str_fget_line(FILE *f)
{
int i,c;
char *s;
int s_sz;
s_sz = 100; s = malloc(s_sz); assert(s);
i = 0;
while ((c = fgetc(f)) > 0) {
if (c >= ' ' || c == '\t') {
s[i++] = c;
if (i == s_sz) {
s_sz *= 2; assert(s_sz < 100000);
s = realloc(s, s_sz); assert(s);
}
}
if (c == '\n') break;
}
s[i] = 0; assert(i < s_sz);
s = realloc(s, strlen(s)+1); assert(s);
return s;
}
/* remove spaces at the beginning and at the end */
void
str_trim(unsigned char *s) {
int i,j;
if (s == NULL) return;
j = strlen((char*)s)-1;
while (j>=0 && s[j] <= ' ') s[j--] = 0;
i = 0;
while (s[i] && s[i] <= ' ') i++;
if (i<=j) {
memmove(s, s+i, j+2-i);
}
}
/* insertion into a string list */
strlist *strlist_ins(strlist *head, const char *s) {
strlist *p; ALLOC_OBJ(p);
p->s = strdup(s); p->next = head; return p;
}