Example #1
0
int
__fmtcpy(Fmt *f, const void *vm, int n, int sz)
{
	Rune *rt, *rs, r;
	char *t, *s, *m, *me;
	ulong fl;
	int nc, w;

	m = (char*)vm;
	me = m + sz;
	fl = f->flags;
	w = 0;
	if(fl & FmtWidth)
		w = f->width;
	if((fl & FmtPrec) && n > f->prec)
		n = f->prec;
	if(f->runes){
		if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
			return -1;
		rt = (Rune*)f->to;
		rs = (Rune*)f->stop;
		for(nc = n; nc > 0; nc--){
			r = *(uchar*)m;
			if(r < Runeself)
				m++;
			else if((me - m) >= UTFmax || fullrune(m, me-m))
				m += chartorune(&r, m);
			else
				break;
			FMTRCHAR(f, rt, rs, r);
		}
		f->nfmt += rt - (Rune *)f->to;
		f->to = rt;
		if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
			return -1;
	}else{
		if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
			return -1;
		t = (char*)f->to;
		s = (char*)f->stop;
		for(nc = n; nc > 0; nc--){
			r = *(uchar*)m;
			if(r < Runeself)
				m++;
			else if((me - m) >= UTFmax || fullrune(m, me-m))
				m += chartorune(&r, m);
			else
				break;
			FMTRUNE(f, t, s, r);
		}
		f->nfmt += t - (char *)f->to;
		f->to = t;
		if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
			return -1;
	}
	return 0;
}
Example #2
0
int
__fmtrcpy(Fmt *f, const void *vm, int n)
{
	Rune r, *m, *me, *rt, *rs;
	char *t, *s;
	ulong fl;
	int w;

	m = (Rune*)vm;
	fl = f->flags;
	w = 0;
	if(fl & FmtWidth)
		w = f->width;
	if((fl & FmtPrec) && n > f->prec)
		n = f->prec;
	if(f->runes){
		if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
			return -1;
		rt = (Rune*)f->to;
		rs = (Rune*)f->stop;
		for(me = m + n; m < me; m++)
			FMTRCHAR(f, rt, rs, *m);
		f->nfmt += rt - (Rune *)f->to;
		f->to = rt;
		if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
			return -1;
	}else{
		if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
			return -1;
		t = (char*)f->to;
		s = (char*)f->stop;
		for(me = m + n; m < me; m++){
			r = *m;
			FMTRUNE(f, t, s, r);
		}
		f->nfmt += t - (char *)f->to;
		f->to = t;
		if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
			return -1;
	}
	return 0;
}
Example #3
0
int
__efgfmt(Fmt *fmt)
{
	double f;
	char s1[NSIGNIF+10];
	int e, d, n;
	int c1, c2, c3, c4, ucase, sign, chr, prec, fl;

	f = va_arg(fmt->args, double);
	prec = FDEFLT;
	fl = fmt->flags;
	fmt->flags = 0;
	if(fl & FmtPrec)
		prec = fmt->prec;
	chr = fmt->r;
	ucase = 0;
	if(chr == 'E'){
		chr = 'e';
		ucase = 1;
	}else if(chr == 'F'){
		chr = 'f';
		ucase = 1;
	}else if(chr == 'G'){
		chr = 'g';
		ucase = 1;
	}
	if(prec > 0 && chr == 'g')
		prec--;
	if(prec < 0)
		prec = 0;

	xdodtoa(s1, f, chr, prec, &e, &sign);
	e--;
	if(*s1 == 'i' || *s1 == 'n'){
		if(ucase){
			if(*s1 == 'i'){
				strcpy(s1, "INF");
			}else{
				strcpy(s1, "NAN");
			}
		}
		fmt->flags = fl & (FmtWidth|FmtLeft);
		return __fmtcpy(fmt, (const void*)s1, 3, 3);
	}

	/*
	 * copy into final place
	 * c1 digits of leading '0'
	 * c2 digits from conversion
	 * c3 digits of trailing '0'
	 * c4 digits after '.'
	 */
	c1 = 0;
	c2 = prec + 1;
	c3 = 0;
	c4 = prec;
	switch(chr) {
	default:
		chr = 'e';
		break;
	case 'g':
		/*
		 * decide on 'e' of 'f' style convers
		 */
		if(e >= -4 && e <= prec) {
			c1 = -e;
			c4 = prec - e;
			chr = 'h';	/* flag for 'f' style */
		}
		break;
	case 'f':
		c1 = -e;
		if(c1 > prec)
			c1 = prec + 1;
		c2 += e;
		break;
	}

	/*
	 * clean up c1 c2 and c3
	 */
	if(c1 < 0)
		c1 = 0;
	if(c2 < 0)
		c2 = 0;
	if(c2 > NSIGNIF) {
		c3 = c2-NSIGNIF;
		c2 = NSIGNIF;
	}

	/*
	 * trim trailing zeros for %g
	 */
	if(!(fl & FmtSharp)
	&& (chr == 'g' || chr == 'h')){
		if(c4 >= c3){
			c4 -= c3;
			c3 = 0;
		}else{
			c3 -= c4;
			c4 = 0;
		}
		while(c4 && c2 > 1 && s1[c2 - 1] == '0'){
			c4--;
			c2--;
		}
	}

	/*
	 * calculate the total length
	 */
	n = c1 + c2 + c3;
	if(sign || (fl & (FmtSign|FmtSpace)))
		n++;
	if(c4 || (fl & FmtSharp)){
		n++;
	}
	if(chr == 'e' || chr == 'g'){
		n += 4;
		if(e >= 100)
			n++;
	}

	/*
	 * pad to width if right justified
	 */
	if((fl & (FmtWidth|FmtLeft)) == FmtWidth && n < fmt->width){
		if(fl & FmtZero){
			c1 += fmt->width - n;
		}else{
			if(__fmtpad(fmt, fmt->width - n) < 0){
				return -1;
			}
		}
	}

	/*
	 * sign
	 */
	d = 0;
	if(sign)
		d = '-';
	else if(fl & FmtSign)
		d = '+';
	else if(fl & FmtSpace)
		d = ' ';
	if(d && fmtrune(fmt, d) < 0){
		return -1;
	}

	/*
	 * copy digits
	 */
	c4 = c1 + c2 + c3 - c4;
	if(c1 > 0){
		if(fmtzdotpad(fmt, c1, c4) < 0){
			return -1;
		}
		c4 -= c1;
	}
	d = 0;
	if(c4 >= 0 && c4 < c2){
		if(__fmtcpy(fmt, s1, c4, c4) < 0 || fmtrune(fmt, '.') < 0)
			return -1;
		d = c4;
		c2 -= c4;
		c4 = -1;
	}
	if(__fmtcpy(fmt, (const void*)(s1 + d), c2, c2) < 0){
		return -1;
	}
	c4 -= c2;
	if(c3 > 0){
		if(fmtzdotpad(fmt, c3, c4) < 0){
			return -1;
		}
		c4 -= c3;
	}

	/*
	 * strip trailing '0' on g conv
	 */
	if((fl & FmtSharp) && c4 == 0 && fmtrune(fmt, '.') < 0){
		return -1;
	}
	if(chr == 'e' || chr == 'g') {
		d = 0;
		if(ucase)
			s1[d++] = 'E';
		else
			s1[d++] = 'e';
		c1 = e;
		if(c1 < 0) {
			s1[d++] = '-';
			c1 = -c1;
		} else
			s1[d++] = '+';
		if(c1 >= 100) {
			s1[d++] = c1/100 + '0';
			c1 = c1%100;
		}
		s1[d++] = c1/10 + '0';
		s1[d++] = c1%10 + '0';
		if(__fmtcpy(fmt, s1, d, d) < 0){
			return -1;
		}
	}
	if((fl & (FmtWidth|FmtLeft)) == (FmtWidth|FmtLeft) && n < fmt->width){
		if(__fmtpad(fmt, fmt->width - n) < 0){
			return -1;
		}
	}
	return 0;
}
Example #4
0
static int
qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
{
	Rune r, *rm, *rme;
	char *t, *s, *m, *me;
	Rune *rt, *rs;
	ulong fl;
	int nc, w;

	m = sin;
	me = m + q->nbytesin;
	rm = rin;
	rme = rm + q->nrunesin;

	fl = f->flags;
	w = 0;
	if(fl & FmtWidth)
		w = f->width;
	if(f->runes){
		if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
			return -1;
	}else{
		if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
			return -1;
	}
	t = (char*)f->to;
	s = (char*)f->stop;
	rt = (Rune*)f->to;
	rs = (Rune*)f->stop;
	if(f->runes)
		FMTRCHAR(f, rt, rs, '\'');
	else
		FMTRUNE(f, t, s, '\'');
	for(nc = q->nrunesin; nc > 0; nc--){
		if(sin){
			r = *(uchar*)m;
			if(r < Runeself)
				m++;
			else if((me - m) >= UTFmax || fullrune(m, (int)(me-m)))
				m += chartorune(&r, m);
			else
				break;
		}else{
			if(rm >= rme)
				break;
			r = *(uchar*)rm++;
		}
		if(f->runes){
			FMTRCHAR(f, rt, rs, r);
			if(r == '\'')
				FMTRCHAR(f, rt, rs, r);
		}else{
			FMTRUNE(f, t, s, r);
			if(r == '\'')
				FMTRUNE(f, t, s, r);
		}
	}

	if(f->runes){
		FMTRCHAR(f, rt, rs, '\'');
		USED(rs);
		f->nfmt += (int)(rt - (Rune *)f->to);
		f->to = rt;
		if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
			return -1;
	}else{
		FMTRUNE(f, t, s, '\'');
		USED(s);
		f->nfmt += (int)(t - (char *)f->to);
		f->to = t;
		if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
			return -1;
	}
	return 0;
}