dreameddeath | Donc pour éviter le slip chaussette, j'ai modifié mon code pour checker la taille au fur et à mesure, j'en ai profité pour assouplir le passage de paramètre en pouvant passer 3 types (int, float et string) et des codes retours normalisés ...
Je pense (j'espère?) que c'est bon maintenant
Taz, je te laisse seul juge
Code :
- /* Return Code Definition */
- typedef enum {
- MY_SPRINTF_OK=0,
- MY_SPRINTF_ERR_BUF_SIZE=1,
- MY_SPRINTF_ERR_SYNTAX=2,
- MY_SPRINTF_ERR_PARAMS=3,
- MY_SPRINTF_ERR_FMT_SIZE=4
- } my_sprintf_errcode ;
- my_sprintf_errcode my_sprintf_array(char * buf,int buf_max_len, char * fmt, int nb_params, void ** array_values){
- char *fmt_curr_p = fmt;
- char *last_pos_fmt = fmt;
- char sub_fmt_p[MAX_FMT_STATEMENT_LEN+1]="";
- my_sprintf_errcode ret_code = MY_SPRINTF_OK;
- int curr_param_pos = 0;
- int remaining_len = buf_max_len - 1; //already take into account the \0
- int appened_str_len = 0;
- int fmt_str_len = 0;
-
- /*clean the buffer*/
- strcpy(buf,"" );
-
- /*start loop on % chars if buffer has still place */
- while((remaining_len>=0) && (fmt_curr_p=strpbrk(fmt_curr_p,"%" ))){
- /*determine the part len to copy*/
- appened_str_len = fmt_curr_p-last_pos_fmt;
- /*compute the future remaining len*/
- remaining_len -= appened_str_len;
- /*check buf remaining size*/
- if((remaining_len)<0){
- ret_code = MY_SPRINTF_ERR_BUF_SIZE;
- break;
- }
-
- /*copy all the char from last pos to the new one excepted*/
- strncat(buf,last_pos_fmt,appened_str_len);
- last_pos_fmt=fmt_curr_p;
- /*if next char is a %, it's a protection */
- if(*(fmt_curr_p+1)=='%'){
- remaining_len-=1;
- /*check remaining len minus one char (%)*/
- if((remaining_len)<0){
- ret_code = MY_SPRINTF_ERR_BUF_SIZE;
- break;
- }
- /*add % in the buf*/
- strcat(buf,"%" );
- /*move forward to skip the %% */
- fmt_curr_p+=2;
- last_pos_fmt = fmt_curr_p;
- continue;
- }
- /*it is a format*/
- else{
- /*try to find the end of the formatting*/
- fmt_curr_p=strpbrk(fmt_curr_p,"sdf" );
-
- /*end of parameter not found*/
- if(fmt_curr_p==NULL){
- fprintf(stderr,"Error wrong format in fmt :\n'%s'.\n The char %% found without s or f or d after. Please put a %%%% for the %% char\n",fmt);
- ret_code = MY_SPRINTF_ERR_SYNTAX;
- break;
- }
-
- /*not enough parameters*/
- if(curr_param_pos >= nb_params){
- fprintf(stderr,"Not enough strings at least %d required and %d found\n",curr_param_pos,nb_params);
- ret_code = MY_SPRINTF_ERR_PARAMS;
- break;
- }
-
- /*clean and copy the %s format into the string*/
- strcpy(sub_fmt_p,"" );
- /*check the format size*/
- fmt_str_len = fmt_curr_p-last_pos_fmt+1;
- if(fmt_str_len > MAX_FMT_STATEMENT_LEN){
- fprintf(stderr,"A format rule '%*.*s' is two big\n",fmt_str_len,fmt_str_len,last_pos_fmt);
- ret_code = MY_SPRINTF_ERR_FMT_SIZE;
- break;
- }
- strncat(sub_fmt_p,last_pos_fmt,fmt_str_len);
-
- /*snprintf to the end of the current buffer (pos = strlen(buf))*/
- /*the max size is the remaining size +1 (due to count of \n)*/
- switch(*fmt_curr_p){
- case 's':
- appened_str_len = snprintf(buf+strlen(buf),remaining_len+1,sub_fmt_p,(char*)array_values[curr_param_pos]);
- break;
- case 'd' :
- appened_str_len = snprintf(buf+strlen(buf),remaining_len+1,sub_fmt_p,*((int*)array_values[curr_param_pos]));
- break;
- case 'f' :
- appened_str_len = snprintf(buf+strlen(buf),remaining_len+1,sub_fmt_p,*((float*)array_values[curr_param_pos]));
- break;
- }
-
- /*check the snprinft max size reached */
- if(appened_str_len < 0){
- ret_code = MY_SPRINTF_ERR_BUF_SIZE;
- break;
- }
- else{
- remaining_len-=appened_str_len;
- }
-
- /*change of input string param*/
- curr_param_pos++;
- /*move to the next char of the input fmt*/
- fmt_curr_p++;
- last_pos_fmt=fmt_curr_p;
- }/*end of fmt string par management*/
-
- }/*end loop while % are found*/
-
- /* If no errors print the residual part if any*/
- if(ret_code == MY_SPRINTF_OK){
- /*copy the last part of the format if not empty*/
- appened_str_len = strlen(last_pos_fmt);
- remaining_len -= appened_str_len;
- /*size check*/
- if(remaining_len<0){
- ret_code = MY_SPRINTF_ERR_BUF_SIZE;
- }
- else if(appened_str_len!=0){
- strcat(buf,last_pos_fmt);
- }
- }
-
-
- /*Errors management*/
- if(ret_code != MY_SPRINTF_OK){
- switch(ret_code){
- case MY_SPRINTF_ERR_BUF_SIZE :
- fprintf(stderr, "Error MY_SPRINTF_ERR_BUF_SIZE occurs.\n" );
- break;
- case MY_SPRINTF_ERR_PARAMS :
- fprintf(stderr, "Error MY_SPRINTF_ERR_PARAMS occurs.\n" );
- break;
- case MY_SPRINTF_ERR_SYNTAX :
- fprintf(stderr, "Error MY_SPRINTF_ERR_SYNTAX occurs.\n" );
- break;
- case MY_SPRINTF_ERR_FMT_SIZE :
- fprintf(stderr, "Error MY_SPRINTF_ERR_FMT_SIZE occurs.\n" );
- break;
- default:
- fprintf(stderr, "An unknown Error occurs.\n" );
-
- }
- fprintf(stderr, "The full format was : %s.\n",fmt);
- fprintf(stderr, "The real processed format is '%*.*s'\n",last_pos_fmt-fmt,last_pos_fmt-fmt,fmt);
- }
- /*if no errors checking the consumption of all params consumption*/
- else if(curr_param_pos!=nb_params){
- fprintf(stderr, "Warning : All parameters not used (%d used on %d)\n",curr_param_pos,nb_params);
- }
-
- /*teel the final result*/
- return ret_code;
- }/*end of my_sprintf_array*/
|
J'espère n'avoir rien oublié cette fois ;p Message édité par dreameddeath le 05-03-2008 à 18:38:43
|