/* Op‚ration sur tableaux de chaines de caractŠres G‚n‚ralement chaque item du tableau est allou‚ dynamiquement (strdup()). tris sp‚cifiques */ #include #include #include #include #include #include "vfs.h" static int cmp (const void *p1, const void *p2) { char *pt1 = *(char**)p1; char *pt2 = *(char**)p2; return (strcmp(pt1,pt2)); } /* tri des chaines de caracteres */ void tbstr_sort ( char *tb[], /* tableau de chaine a trier */ int nbstr) /* nombre de chaine a trier */ { hsort (tb,nbstr,sizeof(char*),cmp); } /* Elimine une chaine d'une table Retourne le nouveau nombre de chaine dans la table */ int tbstr_delete ( char *tbstr[], int nbstr, int nodelete, int dofree) /* free() applique sur la chaine si != 0 */ { if (nodelete >= 0 && nodelete < nbstr){ if (dofree) free (tbstr[nodelete]); nbstr--; if (nodelete < nbstr){ memmove (tbstr+nodelete,tbstr+nodelete+1 ,(nbstr-nodelete)*sizeof(char *)); } } return (nbstr); } /* InsŠre une chaine dans une table. */ void tbstr_insert ( char *tbstr[], int nbstr, const char *str, /* Chaine a insŠrer */ int pos, /* Position d'insertion */ int dupli) /* Place dans la table via strdup_err ou pas */ { if (pos < nbstr){ memmove (tbstr+pos+1,tbstr+pos,(nbstr-pos)*sizeof(char*)); } if (dupli) str = strdup (str); tbstr[pos] = (char*) str; } /* libŠre les ‚l‚ments d'une table de chaine G‚n‚ralement, chaque ‚l‚ment a ‚t‚ allou‚ par strdup() */ void tbstr_free (char *tb[], int nbelm) { int i; for (i=0; i maxlen) maxlen = len; } return (maxlen); } /* S‚pare une chaine en une table de chaine Utilis‚ tbstr_free pour lib‚rer tb[] */ int tbstr_str2tb( const char *str, /* Chaine … s‚parer */ char mark, /* S‚parateur des sous-chaines */ /* Remplac‚ par '\0' */ char *tb[]) /* recrevra les sous-chaines avec strdup() */ { int nb = 0; char *buf = strdup (str); char *pt = buf; assert (buf!=NULL); while (*pt != '\0'){ char *pt2 = strchr(pt,mark); if (pt2 != NULL){ *pt2++ = '\0'; }else{ pt2 = ""; /* force terminaison la prochaine fois */ } tb[nb++] = strdup(pt); pt = pt2; } free (buf); return (nb); } /* Copie les chaines d'une table dans une chaine en concantŠnant Utilis‚ tbstr_free pour lib‚rer tb[] Retourne la longueur de la chaine */ int tbstr_2str( const char *tbstr[],/* recrevra les sous-chaines avec strdup() */ int nbstr, /* nombre de chaine */ char mark, /* S‚parateur qui sera plac‚ entre les chaines */ /* Si '\0', les chaines seront coll‚s */ char *str) /* Destination (doit ˆtre de longueur suffisante) */ { char *debstr = str; int i; for (i=0; i ' ') str++; return ((char*) str); } /* Positionne au d‚but du prochain mot. Si pointe sur un mot, saute par dessus et saute les blancs suivant. Si pointe sur un blanc, saute les blancs. Si pointe sur '\0', fait rien. */ char *str_nextword(const char *str) { if (str[0] != '\0'){ if (isspace(str[0])){ str = str_skip (str); }else{ str = str_skip(str_skipword(str)); } } return (char*)str; } /* saute un certain nombre de mot compos‚ de caractŠres non blancs Retourne un pointeur vers le n'iŠme mot ou un pointeur vers la fin de la chaine '\0' */ char *str_skipnword(const char *str, int nbskip) { int i; for (i=0; i ' ') str++; } while (isspace(*str)) str++; return ((char*) str); } /* Compte le nombre de mot dans une chaine */ export int str_nbword (const char *str) { int ret = 0; str = str_skip(str); while (*str != '\0'){ str = str_skip(str_skipword(str)); ret++; } return ret; } /* Copie un mot compos‚ de caractŠres non blancs Retourne un pointeur vers le premier caractŠre blanc aprŠs le mot ou un pointeur vers la fin de la chaine '\0' */ export char *str_copyword(char *dest, const char *str) { while (*str > ' ') *dest++ = *str++; *dest = '\0'; return ((char*) str); } /* Copie une s‚rie de chiffre d'une chaine Retourne un pointeur vers le premier caractŠre aprŠs la s‚rie ou un pointeur vers la fin de la chaine '\0' */ export char *str_copydig(char *dest, const char *str) { while (isdigit(*str)) *dest++ = *str++; *dest = '\0'; return ((char*) str); } /* Lit une ligne de texte en interpr‚tant les demandes de continuation et commentaires Retourne buf, ou NULL si eof Les blancs … la fin de la ligne sont toujours ‚limin‚s. Tous ce qui suit un comcar est un commentaire. la ligne est coup‚ avant */ export char *fgets_strip0 ( char *buf, int sizebuf, FILE *fin, char contcar, /* CaractŠre de continuation, g‚n‚ralement \ */ char comcar, /* D‚but d'un commentaire, g‚n‚ralement # */ int *noline, /* Compteur r‚viser permettant de connaitre */ /* o— on est rendu dans le fichier */ /* Ou NULL */ int *empty) /* Sera != 0 si la ligne est vide et ne contennait */ /* mˆme pas un commentaire */ { int nocomment = 1; /* Aucun commentaire rencontr‚ ? */ int contline=0; char *debut = buf; char *ret = NULL; *buf = '\0'; *empty = 1; while (fgets(buf,sizebuf,fin)!=NULL){ char *end = strip_end (buf); char *pt = strchr(buf,comcar); if (pt != NULL){ nocomment = 0; *pt = '\0'; end = strip_end (buf); } if (noline != NULL) (*noline)++; ret = debut; if (contline){ char *pt = str_skip(buf); if (pt > buf+1){ strcpy (buf+1,pt); buf[0] = ' '; end-=(int)(pt-buf)-1; }else if (pt == buf+1){ buf[0] = ' '; } } if (end > buf && *(end-1) == contcar){ if (end == buf+1 || *(end-2) != contcar){ /* Continuation demand‚ */ contline = 1; end--; *end = '\0'; buf = end; }else{ *(end-1) = '\0'; break; } }else{ break; } } *empty = debut[0] == '\0' && nocomment; return ret; } /* Lit une ligne de texte en interpr‚tant les demandes de continuation et commentaires Retourne buf, ou NULL si eof Les blancs … la fin de la ligne sont toujours ‚limin‚s. Tous ce qui suit un comcar est un commentaire. la ligne est coup‚ avant */ export char *fgets_strip ( char *buf, int sizebuf, FILE *fin, char contcar, /* CaractŠre de continuation, g‚n‚ralement \ */ char comcar, /* D‚but d'un commentaire, g‚n‚ralement # */ int *noline) /* Compteur r‚viser permettant de connaitre */ /* o— on est rendu dans le fichier */ /* Ou NULL */ { int empty; return fgets_strip0 (buf,sizebuf,fin,contcar,comcar,noline,&empty); } /* copie un mot d'une chaine str dans une chaine dest Un mot est une suite de caractŠre contigue r‚pondant au critŠre isgraph() Saute les blancs au d‚but de str Retourne l'adresse du premier caractŠre aprŠs le mot dans la chaine Retourne NULL si la chaine ne contenait pas de mot. La chaine dest est toujours termin‚e mˆme s'il n'y a pas de mot. */ export char *str_copymot ( char *dest, /* recoit le mot */ const char *str) { char *ret = NULL; while (isspace(*str)) str++; if (*str > ' '){ while (*str>' ') *dest++ = *str++; ret = (char*) str; } *dest = '\0'; return (ret); } /* elimine les blancs et saut de ligne de la fin d'une chaine newstr et str peuvent ˆtre la mˆme variable Retourne le nombre de byte eliminer au bout de la chaine */ export int str_strip ( const char *str, /* Chaine a tronquer */ char *newstr) /* Resultat */ { int ret = 0; int len = strlen(str); char *pt = newstr + len-1; strcpy (newstr,str); while (len > 0 && isspace(*pt)){ *pt-- = '\0'; len --; ret ++; } return (ret); }