diff --git a/src/modules/sprintf/sprintf.c b/src/modules/sprintf/sprintf.c index 851113b1e7c9fb9535eee774c24c1b54410293de..27248092659845746f89c77335e30a6c2f2c97d4 100644 --- a/src/modules/sprintf/sprintf.c +++ b/src/modules/sprintf/sprintf.c @@ -30,6 +30,7 @@ :n set field size & precision ;n Set column width * if n is a * then next argument is used + ~ get pad string from argument list 'X' Set a pad string. ' cannot be a part of the pad_string (yet) < Use same arg again ^ repeat this on every line produced @@ -428,14 +429,27 @@ INLINE static int do_one(struct format_info *f) #define DO_OP() \ if(fsp->flags & SNURKEL) \ { \ - if(!v) \ + struct array *_v; \ + string _b; \ + _b.str=0; \ + _b.len=0; \ + GET_ARRAY(_v); \ + for(tmp=0;tmp<_v->size;tmp++) \ { \ - GET_ARRAY(v); \ - pos=0; \ + struct svalue *save_sp=sp; \ + array_index_no_free(sp,_v,tmp); \ + sp++; \ + _b=low_pike_sprintf(begin,a-begin+1,sp-1,1,_b,nosnurkel+1); \ + if(save_sp < sp) pop_stack(); \ } \ - if(pos>=v->size) { fsp--; break; } \ - array_index(& temp_svalue, v, pos++ ); \ - arg=&temp_svalue; \ + fsp->b=_b.str; \ + fsp->len=_b.len; \ + fsp->free_string=fsp->b; \ + fsp->pad_string=" "; \ + fsp->pad_length=1; \ + fsp->column_width=0; \ + fsp->pos_pad=fsp->flags=fsp->width=fsp->precision=0; \ + break; \ } @@ -448,20 +462,22 @@ static string low_pike_sprintf(char *format, int format_len, struct svalue *argp, int num_arg, - string prefix) + string prefix, + int nosnurkel) { int tmp,setwhat,pos,d,e; - char *a; + char *a,*begin; char buffer[40]; struct format_info *f,*start; float tf; struct svalue *arg=0; /* pushback argument */ struct svalue *lastarg=0; - struct array *v; start=fsp; for(a=format;a<format+format_len;a++) { + int num_snurkel; + fsp++; if(fsp-format_info_stack==FORMAT_INFO_STACK_SIZE) sprintf_error("Sprintf stack overflow.\n"); @@ -480,9 +496,10 @@ static string low_pike_sprintf(char *format, a+=e-1; continue; } + num_snurkel=0; arg=NULL; - v=NULL; setwhat=pos=0; + begin=a; for(a++;;a++) { @@ -532,14 +549,17 @@ static string low_pike_sprintf(char *format, case '+': fsp->pos_pad='+'; continue; case '!': fsp->flags^=DO_TRUNC; continue; case '^': fsp->flags|=REPEAT; continue; - case '@': fsp->flags|=SNURKEL; continue; case '>': fsp->flags|=MULTI_LINE_BREAK; continue; case '_': fsp->flags|=WIDTH_OF_DATA; continue; + case '@': + if(++num_snurkel > nosnurkel) + fsp->flags|=SNURKEL; + continue; case '\'': tmp=0; for(a++;a[tmp]!='\'';tmp++) - if(!a[tmp]) + if(a >= format + format_len ) sprintf_error("Unfinished pad string in format string.\n"); if(tmp) { @@ -549,6 +569,15 @@ static string low_pike_sprintf(char *format, a+=tmp; continue; + case '~': + { + struct pike_string *s; + GET_STRING(s); + fsp->pad_string=s->str; + fsp->pad_length=s->len; + continue; + } + case '<': if(!lastarg) sprintf_error("No last argument.\n"); @@ -603,7 +632,7 @@ static string low_pike_sprintf(char *format, array_index_no_free(sp,w,tmp); sp++; } - b=low_pike_sprintf(a+1,e-2,s,sp-s,b); + b=low_pike_sprintf(a+1,e-2,s,sp-s,b,0); pop_n_elems(sp-s); } fsp->b=b.str; @@ -711,17 +740,6 @@ static string low_pike_sprintf(char *format, break; } } - if((fsp->flags & SNURKEL) && v->size>pos) - { - check_signals(); - fsp++; - if(fsp-format_info_stack==FORMAT_INFO_STACK_SIZE) - sprintf_error("Format stack overflow.\n"); - fsp[0]=fsp[-1]; - fsp->free_string=NULL; /* we don't want to free it twice */ - a--; - continue; - } break; } } @@ -796,7 +814,7 @@ string pike_sprintf(char *format,struct svalue *argp,int num_arg) free_sprintf_strings(); fsp=format_info_stack-1; - return low_pike_sprintf(format,strlen(format),argp,num_arg,prefix); + return low_pike_sprintf(format,strlen(format),argp,num_arg,prefix,0); } /* The efun */ @@ -815,10 +833,11 @@ static void f_sprintf(INT32 num_arg) error("Bad argument 1 to sprintf.\n"); s=low_pike_sprintf(argp->u.string->str, - argp->u.string->len, - argp+1, - num_arg-1, - prefix); + argp->u.string->len, + argp+1, + num_arg-1, + prefix, + 0); free_svalue(&temp_svalue); temp_svalue.type=T_INT; pop_n_elems(num_arg);