Beispiel #1
0
/* public helper routine: fmt out a null terminated string already in hand */
int
fmtstrcpy(Fmt *f, char *s)
{
	int i, j;

	if(!s)
		return __fmtcpy(f, "<nil>", 5, 5);
	/* if precision is specified, make sure we don't wander off the end */
	if(f->flags & FmtPrec){
#ifdef PLAN9PORT
		Rune r;
		i = 0;
		for(j=0; j<f->prec && s[i]; j++)
			i += chartorune(&r, s+i);
#else
		/* ANSI requires precision in bytes, not Runes */
		for(i=0; i<f->prec; i++)
			if(s[i] == 0)
				break;
		j = utfnlen(s, i);	/* won't print partial at end */
#endif
		return __fmtcpy(f, s, j, i);
	}
	return __fmtcpy(f, s, utflen(s), strlen(s));
}
Beispiel #2
0
/* public helper routine: fmt out a null terminated string already in hand */
int
fmtstrcpy(Fmt *f, char *s)
{
	int i, j;
	Rune r;

	if(!s)
		return __fmtcpy(f, "<nil>", 5, 5);
	/* if precision is specified, make sure we don't wander off the end */
	if(f->flags & FmtPrec){
		i = 0;
		for(j=0; j<f->prec && s[i]; j++)
			i += chartorune(&r, s+i);
		return __fmtcpy(f, s, j, i);
	}
	return __fmtcpy(f, s, utflen(s), strlen(s));
}
Beispiel #3
0
int
__errfmt(Fmt *f)
{
    char buf[ERRMAX];

    rerrstr(buf, sizeof buf);
    return __fmtcpy(f, buf, utflen(buf), strlen(buf));
}
Beispiel #4
0
/* public helper routine: fmt out a null terminated string already in hand */
int
fmtstrcpy(Fmt *f, char *s)
{
	int p, i;
	if(!s)
		return __fmtcpy(f, "<nil>", 5, 5);
	/* if precision is specified, make sure we don't wander off the end */
	if(f->flags & FmtPrec){
		p = f->prec;
		for(i = 0; i < p; i++)
			if(s[i] == 0)
				break;
		return __fmtcpy(f, s, utfnlen(s, i), i);	/* BUG?: won't print a partial rune at end */
	}

	return __fmtcpy(f, s, utflen(s), strlen(s));
}
Beispiel #5
0
/* fmt out one character */
int
__charfmt(Fmt *f)
{
	char x[1];

	x[0] = va_arg(f->args, int);
	f->prec = 1;
	return __fmtcpy(f, (const char*)x, 1, 1);
}
Beispiel #6
0
static int
floatfmt(Fmt *fmt, double f)
{
	char s[341];		/* precision+exponent+sign+'.'+null */

	xdtoa(fmt, s, f);
	fmt->flags &= FmtWidth|FmtLeft;
	__fmtcpy(fmt, s, strlen(s), strlen(s));
	return 0;
}
Beispiel #7
0
/* public helper routine: fmt out a null terminated rune string already in hand */
int
fmtrunestrcpy(Fmt *f, Rune *s)
{
	Rune *e;
	int n, p;

	if(!s)
		return __fmtcpy(f, "<nil>", 5, 5);
	/* if precision is specified, make sure we don't wander off the end */
	if(f->flags & FmtPrec){
		p = f->prec;
		for(n = 0; n < p; n++)
			if(s[n] == 0)
				break;
	}else{
		for(e = s; *e; e++)
			;
		n = e - s;
	}
	return __fmtrcpy(f, s, n);
}
Beispiel #8
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;
}