shithub: riscv

Download patch

ref: 313216e6fb269a0a8bd04e44547250a31b83c2df
parent: b43720e3f75c02ea7ddfea4ac46b37839498db35
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Apr 19 19:51:18 EDT 2020

?c: get rid of sprint(), strcpy() and strcat()/strncat(), cleanup

--- a/sys/src/cmd/1c/bits.c
+++ /dev/null
@@ -1,127 +1,0 @@
-#define	EXTERN
-#include "gc.h"
-
-/*
-Bits
-bor(Bits a, Bits b)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = a.b[i] | b.b[i];
-	return c;
-}
-*/
-
-/*
-Bits
-band(Bits a, Bits b)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = a.b[i] & b.b[i];
-	return c;
-}
-*/
-
-/*
-Bits
-bnot(Bits a)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = ~a.b[i];
-	return c;
-}
-*/
-
-int
-bany(Bits *a)
-{
-	int i;
-
-	for(i=0; i<BITS; i++)
-		if(a->b[i])
-			return 1;
-	return 0;
-}
-
-/*
-int
-beq(Bits a, Bits b)
-{
-	int i;
-
-	for(i=0; i<BITS; i++)
-		if(a.b[i] != b.b[i])
-			return 0;
-	return 1;
-}
-*/
-
-int
-bnum(Bits a)
-{
-	int i;
-	long b;
-
-	for(i=0; i<BITS; i++)
-		if(b = a.b[i])
-			return 32*i + bitno(b);
-	diag(Z, "bad in bnum");
-	return 0;
-}
-
-Bits
-blsh(unsigned n)
-{
-	Bits c;
-
-	c = zbits;
-	c.b[n/32] = 1L << (n%32);
-	return c;
-}
-
-/*
-int
-bset(Bits a, unsigned n)
-{
-	int i;
-
-	if(a.b[n/32] & (1L << (n%32)))
-		return 1;
-	return 0;
-}
-*/
-
-int
-Bconv(va_list *arg, Fconv *fp)
-{
-	char str[STRINGSZ], ss[STRINGSZ], *s;
-	Bits bits;
-	int i;
-
-	str[0] = 0;
-	bits = va_arg(*arg, Bits);
-	while(bany(&bits)) {
-		i = bnum(bits);
-		if(str[0])
-			strcat(str, " ");
-		if(var[i].sym == S) {
-			sprint(ss, "$%ld", var[i].offset);
-			s = ss;
-		} else
-			s = var[i].sym->name;
-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
-			break;
-		strcat(str, s);
-		bits.b[i/32] &= ~(1L << (i%32));
-	}
-	strconv(str, fp);
-	return 0;
-}
--- a/sys/src/cmd/2c/bits.c
+++ /dev/null
@@ -1,127 +1,0 @@
-#define	EXTERN
-#include "gc.h"
-
-/*
-Bits
-bor(Bits a, Bits b)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = a.b[i] | b.b[i];
-	return c;
-}
-*/
-
-/*
-Bits
-band(Bits a, Bits b)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = a.b[i] & b.b[i];
-	return c;
-}
-*/
-
-/*
-Bits
-bnot(Bits a)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = ~a.b[i];
-	return c;
-}
-*/
-
-int
-bany(Bits *a)
-{
-	int i;
-
-	for(i=0; i<BITS; i++)
-		if(a->b[i])
-			return 1;
-	return 0;
-}
-
-/*
-int
-beq(Bits a, Bits b)
-{
-	int i;
-
-	for(i=0; i<BITS; i++)
-		if(a.b[i] != b.b[i])
-			return 0;
-	return 1;
-}
-*/
-
-int
-bnum(Bits a)
-{
-	int i;
-	long b;
-
-	for(i=0; i<BITS; i++)
-		if(b = a.b[i])
-			return 32*i + bitno(b);
-	diag(Z, "bad in bnum");
-	return 0;
-}
-
-Bits
-blsh(unsigned n)
-{
-	Bits c;
-
-	c = zbits;
-	c.b[n/32] = 1L << (n%32);
-	return c;
-}
-
-/*
-int
-bset(Bits a, unsigned n)
-{
-	int i;
-
-	if(a.b[n/32] & (1L << (n%32)))
-		return 1;
-	return 0;
-}
-*/
-
-int
-Bconv(va_list *arg, Fconv *fp)
-{
-	char str[STRINGSZ], ss[STRINGSZ], *s;
-	Bits bits;
-	int i;
-
-	str[0] = 0;
-	bits = va_arg(*arg, Bits);
-	while(bany(&bits)) {
-		i = bnum(bits);
-		if(str[0])
-			strcat(str, " ");
-		if(var[i].sym == S) {
-			sprint(ss, "$%ld", var[i].offset);
-			s = ss;
-		} else
-			s = var[i].sym->name;
-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
-			break;
-		strcat(str, s);
-		bits.b[i/32] &= ~(1L << (i%32));
-	}
-	strconv(str, fp);
-	return 0;
-}
--- a/sys/src/cmd/5c/list.c
+++ b/sys/src/cmd/5c/list.c
@@ -42,7 +42,7 @@
 int
 Pconv(Fmt *fp)
 {
-	char str[STRINGSZ], sc[20];
+	char sc[20];
 	Prog *p;
 	int a, s;
 
@@ -59,31 +59,30 @@
 	if(s & C_UBIT)		/* ambiguous with FBIT */
 		strcat(sc, ".U");
 	if(a == AMULL || a == AMULAL || a == AMULLU || a == AMULALU)
-		snprint(str, sizeof str, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
+		return fmtprint(fp, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
 	else
 	if(a == AMOVM) {
 		if(p->from.type == D_CONST)
-			snprint(str, sizeof str, "	%A%s	%R,%D", a, sc, &p->from, &p->to);
+			return fmtprint(fp, "	%A%s	%R,%D", a, sc, &p->from, &p->to);
 		else
 		if(p->to.type == D_CONST)
-			snprint(str, sizeof str, "	%A%s	%D,%R", a, sc, &p->from, &p->to);
+			return fmtprint(fp, "	%A%s	%D,%R", a, sc, &p->from, &p->to);
 		else
-			snprint(str, sizeof str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
+			return fmtprint(fp, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
 	} else
 	if(a == ADATA)
-		snprint(str, sizeof str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
+		return fmtprint(fp, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
 	else
 	if(p->as == ATEXT)
-		snprint(str, sizeof str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
+		return fmtprint(fp, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
 	else
 	if(p->reg == NREG)
-		snprint(str, sizeof str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
+		return fmtprint(fp, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
 	else
 	if(p->from.type != D_FREG)
-		snprint(str, sizeof str, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
+		return fmtprint(fp, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
 	else
-		snprint(str, sizeof str, "	%A%s	%D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
-	return fmtstrcpy(fp, str);
+		return fmtprint(fp, "	%A%s	%D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
 }
 
 int
@@ -102,7 +101,6 @@
 int
 Dconv(Fmt *fp)
 {
-	char str[STRINGSZ];
 	Adr *a;
 	char *op;
 	int v;
@@ -109,86 +107,77 @@
 
 	a = va_arg(fp->args, Adr*);
 	switch(a->type) {
-
 	default:
-		snprint(str, sizeof str, "GOK-type(%d)", a->type);
-		break;
+		return fmtprint(fp, "GOK-type(%d)", a->type);
 
 	case D_NONE:
-		str[0] = 0;
 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
-			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
-		break;
+			return fmtprint(fp, "%N(R%d)(NONE)", a, a->reg);
+		return 0;
 
 	case D_CONST:
 		if(a->reg != NREG)
-			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
+			return fmtprint(fp, "$%N(R%d)", a, a->reg);
 		else
-			snprint(str, sizeof str, "$%N", a);
-		break;
+			return fmtprint(fp, "$%N", a);
 
 	case D_SHIFT:
 		v = a->offset;
 		op = "<<>>->@>" + (((v>>5) & 3) << 1);
 		if(v & (1<<4))
-			snprint(str, sizeof str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
+			fmtprint(fp, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
 		else {
 			int sh = (v>>7)&31;
 			if(sh == 0 && (v & (3<<5)) != 0)
 				sh = 32;
-			snprint(str, sizeof str, "R%d%c%c%d", v&15, op[0], op[1], sh);
+			fmtprint(fp, "R%d%c%c%d", v&15, op[0], op[1], sh);
 		}
 		if(a->reg != NREG)
-			snprint(str+strlen(str), sizeof(str)-strlen(str), "(R%d)", a->reg);
-		break;
+			fmtprint(fp, "(R%d)", a->reg);
+		return 0;
 
 	case D_OREG:
 		if(a->reg != NREG)
-			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
+			return fmtprint(fp, "%N(R%d)", a, a->reg);
 		else
-			snprint(str, sizeof str, "%N", a);
-		break;
+			return fmtprint(fp, "%N", a);
 
 	case D_REGREG:
-		snprint(str, sizeof str, "(R%d,R%d)", a->reg, (char)a->offset);
-		break;
+		return fmtprint(fp, "(R%d,R%d)", a->reg, (char)a->offset);
 
 	case D_REG:
-		snprint(str, sizeof str, "R%d", a->reg);
 		if(a->name != D_NONE || a->sym != S)
-			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
-		break;
+			return fmtprint(fp, "%N(R%d)(REG)", a, a->reg);
+		else
+			return fmtprint(fp, "R%d", a->reg);
 
 	case D_FREG:
-		snprint(str, sizeof str, "F%d", a->reg);
 		if(a->name != D_NONE || a->sym != S)
-			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
-		break;
+			return fmtprint(fp, "%N(R%d)(REG)", a, a->reg);
+		else
+			return fmtprint(fp, "F%d", a->reg);
 
 	case D_PSR:
-		snprint(str, sizeof str, "PSR");
 		if(a->name != D_NONE || a->sym != S)
-			snprint(str, sizeof str, "%N(PSR)(REG)", a);
-		break;
+			return fmtprint(fp, "%N(PSR)(REG)", a);
+		else
+			return fmtprint(fp, "PSR");
 
 	case D_BRANCH:
-		snprint(str, sizeof str, "%ld(PC)", a->offset-pc);
-		break;
+		return fmtprint(fp, "%ld(PC)", a->offset-pc);
 
 	case D_FCONST:
-		snprint(str, sizeof str, "$%.17e", a->dval);
-		break;
+		return fmtprint(fp, "$%.17e", a->dval);
 
 	case D_SCONST:
-		snprint(str, sizeof str, "$\"%S\"", a->sval);
-		break;
+		return fmtprint(fp, "$\"%S\"", a->sval);
 	}
-	return fmtstrcpy(fp, str);
 }
 
 int
 Rconv(Fmt *fp)
 {
+	char str[STRINGSZ], *p, *e;
 	Adr *a;
 	int i, v;
 
@@ -200,14 +189,19 @@
 		if(a->sym != S)
 			break;
 		v = a->offset;
-		fmtprint(fp, "[");
+		p = str;
+		e = str+sizeof(str);
 		for(i=0; i<NREG; i++) {
-			if(v & (1<<i))
-				fmtprint(fp, "R%d,", i);
+			if(v & (1<<i)) {
+				if(p == str)
+					p = seprint(p, e, "[R%d", i);
+				else
+					p = seprint(p, e, ",R%d", i);
+			}
 		}
-		fmtprint(fp, "]");
+		seprint(p, e, "]");
 	}
-	return 0;
+	return fmtstrcpy(fp, str);
 }
 
 int
@@ -260,41 +254,30 @@
 int
 Nconv(Fmt *fp)
 {
-	char str[STRINGSZ];
 	Adr *a;
 	Sym *s;
 
 	a = va_arg(fp->args, Adr*);
 	s = a->sym;
-	if(s == S) {
-		snprint(str, sizeof str, "%ld", a->offset);
-		goto out;
-	}
+	if(s == S)
+		return fmtprint(fp, "%ld", a->offset);
 	switch(a->name) {
 	default:
-		snprint(str, sizeof str, "GOK-name(%d)", a->name);
-		break;
+		return fmtprint(fp, "GOK-name(%d)", a->name);
 
 	case D_NONE:
-		snprint(str, sizeof str, "%ld", a->offset);
-		break;
+		return fmtprint(fp, "%ld", a->offset);
 
 	case D_EXTERN:
-		snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
-		break;
+		return fmtprint(fp, "%s+%ld(SB)", s->name, a->offset);
 
 	case D_STATIC:
-		snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
-		break;
+		return fmtprint(fp, "%s<>+%ld(SB)", s->name, a->offset);
 
 	case D_AUTO:
-		snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
-		break;
+		return fmtprint(fp, "%s-%ld(SP)", s->name, -a->offset);
 
 	case D_PARAM:
-		snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
-		break;
+		return fmtprint(fp, "%s+%ld(FP)", s->name, a->offset);
 	}
-out:
-	return fmtstrcpy(fp, str);
 }
--- a/sys/src/cmd/5c/mul.c
+++ b/sys/src/cmd/5c/mul.c
@@ -117,8 +117,7 @@
 	if(g) {
 		m1 = mulcon0(v);
 		if(m1) {
-			strcpy(m->code, m1->code);
-			sprint(strchr(m->code, 0), "%c0", g+'a');
+			snprint(m->code, sizeof(m->code), "%s%c0", m1->code, g+'a');
 			return m;
 		}
 	}
--- a/sys/src/cmd/7c/list.c
+++ b/sys/src/cmd/7c/list.c
@@ -17,27 +17,19 @@
 int
 Bconv(Fmt *fp)
 {
-	char str[STRINGSZ], ss[STRINGSZ], *s;
 	Bits bits;
 	int i;
 
-	str[0] = 0;
 	bits = va_arg(fp->args, Bits);
 	while(bany(&bits)) {
 		i = bnum(bits);
-		if(str[0])
-			strcat(str, " ");
-		if(var[i].sym == S) {
-			snprint(ss, sizeof(ss), "$%lld", var[i].offset);
-			s = ss;
-		} else
-			s = var[i].sym->name;
-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
-			break;
-		strcat(str, s);
 		bits.b[i/32] &= ~(1L << (i%32));
+		if(var[i].sym == S)
+			fmtprint(fp, "$%lld ", var[i].offset);
+		else
+			fmtprint(fp, "%s ", var[i].sym->name);
 	}
-	return fmtstrcpy(fp, str);
+	return 0;
 }
 
 static char *conds[] = {
@@ -88,7 +80,6 @@
 int
 Dconv(Fmt *fp)
 {
-	char str[STRINGSZ];
 	Adr *a;
 	char *op;
 	int v;
@@ -96,116 +87,97 @@
 
 	a = va_arg(fp->args, Adr*);
 	switch(a->type) {
-
 	default:
-		snprint(str, sizeof(str), "GOK-type(%d)", a->type);
-		break;
+		return fmtprint(fp, "GOK-type(%d)", a->type);
 
 	case D_NONE:
-		str[0] = 0;
 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
-			snprint(str, sizeof(str), "%N(R%d)(NONE)", a, a->reg);
-		break;
+			return fmtprint(fp, "%N(R%d)(NONE)", a, a->reg);
+		return 0;
 
 	case D_CONST:
 		if(a->reg != NREG)
-			snprint(str, sizeof(str), "$%N(R%d)", a, a->reg);
+			return fmtprint(fp, "$%N(R%d)", a, a->reg);
 		else
-			snprint(str, sizeof(str), "$%N", a);
-		break;
+			return fmtprint(fp, "$%N", a);
 
 	case D_SHIFT:
 		v = a->offset;
 		op = "<<>>->@>" + (((v>>5) & 3) << 1);
 		if(v & (1<<4))
-			snprint(str, sizeof(str), "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
+			fmtprint(fp, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
 		else
-			snprint(str, sizeof(str), "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
+			fmtprint(fp, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
 		if(a->reg != NREG)
-			sprint(str+strlen(str), "(R%d)", a->reg);
-		break;
+			fmtprint(fp, "(R%d)", a->reg);
+		return 0;
 
 	case D_OREG:
 		if(a->reg != NREG)
-			snprint(str, sizeof(str), "%N(R%d)", a, a->reg);
+			return fmtprint(fp, "%N(R%d)", a, a->reg);
 		else
-			snprint(str, sizeof(str), "%N", a);
-		break;
+			return fmtprint(fp, "%N", a);
 
 	case D_XPRE:
 		if(a->reg != NREG)
-			snprint(str, sizeof(str), "%N(R%d)!", a, a->reg);
+			return fmtprint(fp, "%N(R%d)!", a, a->reg);
 		else
-			snprint(str, sizeof(str), "%N!", a);
-		break;
+			return fmtprint(fp, "%N!", a);
 
 	case D_XPOST:
 		if(a->reg != NREG)
-			snprint(str, sizeof(str), "(R%d)%N!", a->reg, a);
+			return fmtprint(fp, "(R%d)%N!", a->reg, a);
 		else
-			snprint(str, sizeof(str), "%N!", a);
-		break;
+			return fmtprint(fp, "%N!", a);
 
 	case D_EXTREG:
 		v = a->offset;
 		if(v & (7<<10))
-			snprint(str, sizeof(str), "R%d%s<<%d", (v>>16)&31, extop[(v>>13)&7], (v>>10)&7);
+			return fmtprint(fp, "R%d%s<<%d", (v>>16)&31, extop[(v>>13)&7], (v>>10)&7);
 		else
-			snprint(str, sizeof(str), "R%d%s", (v>>16)&31, extop[(v>>13)&7]);
-		break;
+			return fmtprint(fp, "R%d%s", (v>>16)&31, extop[(v>>13)&7]);
 
 	case D_REG:
-		snprint(str, sizeof(str), "R%d", a->reg);
 		if(a->name != D_NONE || a->sym != S)
-			snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
-		break;
+			return fmtprint(fp, "%N(R%d)(REG)", a, a->reg);
+		else
+			return fmtprint(fp, "R%d", a->reg);
 
 	case D_SP:
 		if(a->name != D_NONE || a->sym != S)
-			snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
+			return fmtprint(fp, "%N(R%d)(REG)", a, a->reg);
 		else
-			strcpy(str, "SP");
-		break;
+			return fmtprint(fp, "SP");
 
 	case D_FREG:
-		snprint(str, sizeof(str), "F%d", a->reg);
 		if(a->name != D_NONE || a->sym != S)
-			snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
-		break;
+			return fmtprint(fp, "%N(R%d)(REG)", a, a->reg);
+		else
+			return fmtprint(fp, "F%d", a->reg);
 
-
 	case D_SPR:
+		if(a->name != D_NONE || a->sym != S)
+			return fmtprint(fp, "%N(SPR(%lld))(REG)", a, a->offset);
 		switch((ulong)a->offset){
 		case D_FPSR:
-			sprint(str, "FPSR");
-			break;
+			return fmtprint(fp, "FPSR");
 		case D_FPCR:
-			sprint(str, "FPCR");
-			break;
+			return fmtprint(fp, "FPCR");
 		case D_NZCV:
-			sprint(str, "NZCV");
-			break;
+			return fmtprint(fp, "NZCV");
 		default:
-			sprint(str, "SPR(%#llux)", a->offset);
-			break;
+			return fmtprint(fp, "SPR(%#llux)", a->offset);
 		}
-		if(a->name != D_NONE || a->sym != S)
-			snprint(str, sizeof(str), "%N(SPR(%lld))(REG)", a, a->offset);
-		break;
 
 	case D_BRANCH:
-		snprint(str, sizeof(str), "%lld(PC)", a->offset-pc);
-		break;
+		return fmtprint(fp, "%lld(PC)", a->offset-pc);
 
 	case D_FCONST:
-		snprint(str, sizeof(str), "$%.17e", a->dval);
-		break;
+		return fmtprint(fp, "$%.17e", a->dval);
 
 	case D_SCONST:
-		snprint(str, sizeof(str), "$\"%S\"", a->sval);
-		break;
+		return fmtprint(fp, "$\"%S\"", a->sval);
 	}
-	return fmtstrcpy(fp, str);
 }
 
 int
@@ -289,41 +261,30 @@
 int
 Nconv(Fmt *fp)
 {
-	char str[STRINGSZ];
 	Adr *a;
 	Sym *s;
 
 	a = va_arg(fp->args, Adr*);
 	s = a->sym;
-	if(s == S) {
-		snprint(str, sizeof(str), "%lld", a->offset);
-		goto out;
-	}
+	if(s == S)
+		return fmtprint(fp, "%lld", a->offset);
 	switch(a->name) {
 	default:
-		snprint(str, sizeof(str), "GOK-name(%d)", a->name);
-		break;
+		return fmtprint(fp, "GOK-name(%d)", a->name);
 
 	case D_NONE:
-		snprint(str, sizeof(str), "%lld", a->offset);
-		break;
+		return fmtprint(fp, "%lld", a->offset);
 
 	case D_EXTERN:
-		snprint(str, sizeof(str), "%s+%lld(SB)", s->name, a->offset);
-		break;
+		return fmtprint(fp, "%s+%lld(SB)", s->name, a->offset);
 
 	case D_STATIC:
-		snprint(str, sizeof(str), "%s<>+%lld(SB)", s->name, a->offset);
-		break;
+		return fmtprint(fp, "%s<>+%lld(SB)", s->name, a->offset);
 
 	case D_AUTO:
-		snprint(str, sizeof(str), "%s-%lld(SP)", s->name, -a->offset);
-		break;
+		return fmtprint(fp, "%s-%lld(SP)", s->name, -a->offset);
 
 	case D_PARAM:
-		snprint(str, sizeof(str), "%s+%lld(FP)", s->name, a->offset);
-		break;
+		return fmtprint(fp, "%s+%lld(FP)", s->name, a->offset);
 	}
-out:
-	return fmtstrcpy(fp, str);
 }
--- a/sys/src/cmd/7c/mul.c
+++ b/sys/src/cmd/7c/mul.c
@@ -117,8 +117,7 @@
 	if(g) {
 		m1 = mulcon0(v);
 		if(m1) {
-			strcpy(m->code, m1->code);
-			sprint(strchr(m->code, 0), "%c0", g+'a');
+			snprint(m->code, sizeof(m->code), "%s%c0", m1->code, g+'a');
 			return m;
 		}
 	}
--- a/sys/src/cmd/8c/list.c
+++ b/sys/src/cmd/8c/list.c
@@ -34,20 +34,18 @@
 int
 Pconv(Fmt *fp)
 {
-	char str[STRINGSZ];
 	Prog *p;
 
 	p = va_arg(fp->args, Prog*);
 	if(p->as == ADATA)
-		snprint(str, sizeof(str), "	%A	%D/%d,%D",
+		return fmtprint(fp, "	%A	%D/%d,%D",
 			p->as, &p->from, p->from.scale, &p->to);
 	else if(p->as == ATEXT)
-		snprint(str, sizeof(str), "	%A	%D,%d,%D",
+		return fmtprint(fp, "	%A	%D,%d,%D",
 			p->as, &p->from, p->from.scale, &p->to);
 	else
-		snprint(str, sizeof(str), "	%A	%D,%D",
+		return fmtprint(fp, "	%A	%D,%D",
 			p->as, &p->from, &p->to);
-	return fmtstrcpy(fp, str);
 }
 
 int
@@ -213,16 +211,13 @@
 int
 Rconv(Fmt *fp)
 {
-	char str[20];
 	int r;
 
 	r = va_arg(fp->args, int);
 	if(r >= D_AL && r <= D_NONE)
-		snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
+		return fmtprint(fp, "%s", regstr[r-D_AL]);
 	else
-		snprint(str, sizeof(str), "gok(%d)", r);
-
-	return fmtstrcpy(fp, str);
+		return fmtprint(fp, "gok(%d)", r);
 }
 
 int
--- a/sys/src/cmd/cc/lex.c
+++ b/sys/src/cmd/cc/lex.c
@@ -60,7 +60,7 @@
 void
 main(int argc, char *argv[])
 {
-	char *defs[50], *p;
+	char **defs, *p;
 	int nproc, nout, status, i, c, ndef;
 
 	memset(debug, 0, sizeof(debug));
@@ -71,6 +71,7 @@
 
 	profileflg = 1;	/* #pragma can turn it off */
 	tufield = simplet((1L<<tfield->etype) | BUNSIGNED);
+	defs = 0;
 	ndef = 0;
 	outfile = 0;
 	include[ninclude++] = ".";
@@ -97,6 +98,8 @@
 	case 'D':
 		p = ARGF();
 		if(p) {
+			if((ndef & 15) == 0)
+				defs = allocn(defs, ndef*sizeof(defs[0]), 16*sizeof(defs[0]));
 			defs[ndef++] = p;
 			dodefine(p);
 		}
@@ -109,7 +112,7 @@
 		break;
 	} ARGEND
 	if(argc < 1 && outfile == 0) {
-		print("usage: %cc [-options] files\n", thechar);
+		print("usage: %Cc [-options] files\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -176,12 +179,11 @@
 int
 compile(char *file, char **defs, int ndef)
 {
-	char ofile[400], incfile[20];
-	char *p, *av[100], opt[256];
+	char *ofile, *p, **av;
 	int i, c, fd[2];
 	static int first = 1;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		*p++ = 0;
@@ -191,21 +193,17 @@
 		p = ofile;
 
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile) {
+		if(p) {
+			outfile = p;
 			if(p = utfrrune(outfile, '.'))
 				if(p[1] == 'c' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
 			if(debug['a'] && debug['n'])
-				strcat(p, ".acid");
+				outfile = smprint("%s.acid", outfile);
 			else if(debug['Z'] && debug['n'])
-				strcat(p, "_pickle.c");
-			else {
-				p[0] = '.';
-				p[1] = thechar;
-				p[2] = 0;
-			}
+				outfile = smprint("%s_pickle.c", outfile);
+			else
+				outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -214,8 +212,7 @@
 		setinclude(p);
 	} else {
 		if(systemtype(Plan9)) {
-			sprint(incfile, "/%s/include", thestring);
-			setinclude(strdup(incfile));
+			setinclude(smprint("/%s/include", thestring));
 			setinclude("/sys/include");
 		}
 	}
@@ -265,22 +262,19 @@
 			close(fd[0]);
 			mydup(fd[1], 1);
 			close(fd[1]);
-			av[0] = CPP;
-			i = 1;
-			sprint(opt, "-+");
-			av[i++] = strdup(opt);
-			if(debug['.']){
-				sprint(opt, "-.");
-				av[i++] = strdup(opt);
-			}
-			for(c = 0; c < ndef; c++) {
-				sprint(opt, "-D%s", defs[c]);
-				av[i++] = strdup(opt);
-			}
-			for(c = 0; c < ninclude; c++) {
-				sprint(opt, "-I%s", include[c]);
-				av[i++] = strdup(opt);
-			}
+
+			i = 8+ndef+ninclude;
+			av = alloc(i*sizeof(av[0]));
+
+			i = 0;
+			av[i++] = CPP;
+			av[i++] = "-+";
+			if(debug['.'])
+				av[i++] = "-.";
+			for(c = 0; c < ndef; c++)
+				av[i++] = smprint("-D%s", defs[c]);
+			for(c = 0; c < ninclude; c++)
+				av[i++] = smprint("-I%s", include[c]);
 			if(strcmp(file, "stdin") != 0)
 				av[i++] = file;
 			av[i] = 0;
@@ -367,7 +361,7 @@
 	if(f < 0)
 		i->f = open(s, 0);
 	if(i->f < 0) {
-		yyerror("%cc: %r: %s", thechar, s);
+		yyerror("%Cc: %r: %s", thechar, s);
 		errorexit();
 	}
 	fi.c = 0;
@@ -377,8 +371,11 @@
 Sym*
 slookup(char *s)
 {
-
-	strcpy(symb, s);
+	strncpy(symb, s, NSYMB);
+	if(symb[NSYMB-1] != '\0'){
+		yyerror("symbol too long: %s", s);
+		errorexit();
+	}
 	return lookup();
 }
 
@@ -410,7 +407,6 @@
 	s->name = alloc(n);
 	memmove(s->name, symb, n);
 
-	strcpy(s->name, symb);
 	s->link = hash[h];
 	hash[h] = s;
 	syminit(s);
@@ -1341,7 +1337,6 @@
 int
 Lconv(Fmt *fp)
 {
-	char str[STRINGSZ], s[STRINGSZ];
 	Hist *h;
 	struct
 	{
@@ -1383,87 +1378,62 @@
 	}
 	if(n > HISTSZ)
 		n = HISTSZ;
-	str[0] = 0;
+	if(n == 0)
+		return fmtprint(fp, "<eof>");
 	for(i=n-1; i>=0; i--) {
 		if(i != n-1) {
 			if(fp->flags & ~(FmtWidth|FmtPrec))	/* BUG ROB - was f3 */
 				break;
-			strcat(str, " ");
+			fmtrune(fp, ' ');
 		}
 		if(a[i].line)
-			snprint(s, STRINGSZ, "%s:%ld[%s:%ld]",
+			fmtprint(fp, "%s:%ld[%s:%ld]",
 				a[i].line->name, l-a[i].ldel+1,
 				a[i].incl->name, l-a[i].idel+1);
 		else
-			snprint(s, STRINGSZ, "%s:%ld",
+			fmtprint(fp, "%s:%ld",
 				a[i].incl->name, l-a[i].idel+1);
-		if(strlen(s)+strlen(str) >= STRINGSZ-10)
-			break;
-		strcat(str, s);
 		l = a[i].incl->line - 1;	/* now print out start of this file */
 	}
-	if(n == 0)
-		strcat(str, "<eof>");
-	return fmtstrcpy(fp, str);
+	return 0;
 }
 
 int
 Tconv(Fmt *fp)
 {
-	char str[STRINGSZ+20], s[STRINGSZ+20];
 	Type *t, *t1;
 	int et;
 	long n;
 
-	str[0] = 0;
-	for(t = va_arg(fp->args, Type*); t != T; t = t->link) {
+	t = va_arg(fp->args, Type*);
+	while(t != T) {
+		if(t->garb&~GINCOMPLETE)
+			fmtprint(fp, "%s ", gnames[t->garb&~GINCOMPLETE]);
 		et = t->etype;
-		if(str[0])
-			strcat(str, " ");
-		if(t->garb&~GINCOMPLETE) {
-			sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]);
-			if(strlen(str) + strlen(s) < STRINGSZ)
-				strcat(str, s);
+		fmtprint(fp, "%s", tnames[et]);
+		if(et == TFUNC && (t1 = t->down) != T) {
+			fmtprint(fp, "(%T", t1);
+			while((t1 = t1->down) != T)
+				fmtprint(fp, ", %T", t1);
+			fmtprint(fp, ")");
 		}
-		sprint(s, "%s", tnames[et]);
-		if(strlen(str) + strlen(s) < STRINGSZ)
-			strcat(str, s);
-		if(et == TFUNC && (t1 = t->down)) {
-			sprint(s, "(%T", t1);
-			if(strlen(str) + strlen(s) < STRINGSZ)
-				strcat(str, s);
-			while(t1 = t1->down) {
-				sprint(s, ", %T", t1);
-				if(strlen(str) + strlen(s) < STRINGSZ)
-					strcat(str, s);
-			}
-			if(strlen(str) + strlen(s) < STRINGSZ)
-				strcat(str, ")");
-		}
 		if(et == TARRAY) {
 			n = t->width;
-			if(t->link && t->link->width)
+			if(t->link != T && t->link->width)
 				n /= t->link->width;
-			sprint(s, "[%ld]", n);
-			if(strlen(str) + strlen(s) < STRINGSZ)
-				strcat(str, s);
+			fmtprint(fp, "[%ld]", n);
 		}
-		if(t->nbits) {
-			sprint(s, " %d:%d", t->shift, t->nbits);
-			if(strlen(str) + strlen(s) < STRINGSZ)
-				strcat(str, s);
-		}
+		if(t->nbits)
+			fmtprint(fp, " %d:%d", t->shift, t->nbits);
 		if(typesu[et]) {
-			if(t->tag) {
-				strcat(str, " ");
-				if(strlen(str) + strlen(t->tag->name) < STRINGSZ)
-					strcat(str, t->tag->name);
-			} else
-				strcat(str, " {}");
+			fmtprint(fp, " %s", t->tag? t->tag->name: "{}");
 			break;
 		}
+		if((t = t->link) == T)
+			break;
+		fmtrune(fp, ' ');
 	}
-	return fmtstrcpy(fp, str);
+	return 0;
 }
 
 int
@@ -1482,46 +1452,36 @@
 int
 Qconv(Fmt *fp)
 {
-	char str[STRINGSZ+20], *s;
 	long b;
 	int i;
 
-	str[0] = 0;
-	for(b = va_arg(fp->args, long); b;) {
+	b = va_arg(fp->args, long);
+	while(b) {
 		i = bitno(b);
-		if(str[0])
-			strcat(str, " ");
-		s = qnames[i];
-		if(strlen(str) + strlen(s) >= STRINGSZ)
-			break;
-		strcat(str, s);
 		b &= ~(1L << i);
+		fmtprint(fp, "%s%s", qnames[i], b? " ": "");
 	}
-	return fmtstrcpy(fp, str);
+	return 0;
 }
 
 int
 VBconv(Fmt *fp)
 {
-	char str[STRINGSZ];
-	int i, n, t, pc;
+	int n, t, pc;
 
 	n = va_arg(fp->args, int);
 	pc = 0;	/* BUG: was printcol */
-	i = 0;
 	while(pc < n) {
 		t = (pc+4) & ~3;
 		if(t <= n) {
-			str[i++] = '\t';
+			fmtrune(fp, '\t');
 			pc = t;
-			continue;
+		} else {
+			fmtrune(fp, ' ');
+			pc++;
 		}
-		str[i++] = ' ';
-		pc++;
 	}
-	str[i] = 0;
-
-	return fmtstrcpy(fp, str);
+	return 0;
 }
 
 void
--- a/sys/src/cmd/kc/bits.c
+++ /dev/null
@@ -1,127 +1,0 @@
-#define	EXTERN
-#include "gc.h"
-
-/*
-Bits
-bor(Bits a, Bits b)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = a.b[i] | b.b[i];
-	return c;
-}
-*/
-
-/*
-Bits
-band(Bits a, Bits b)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = a.b[i] & b.b[i];
-	return c;
-}
-*/
-
-/*
-Bits
-bnot(Bits a)
-{
-	Bits c;
-	int i;
-
-	for(i=0; i<BITS; i++)
-		c.b[i] = ~a.b[i];
-	return c;
-}
-*/
-
-int
-bany(Bits *a)
-{
-	int i;
-
-	for(i=0; i<BITS; i++)
-		if(a->b[i])
-			return 1;
-	return 0;
-}
-
-/*
-int
-beq(Bits a, Bits b)
-{
-	int i;
-
-	for(i=0; i<BITS; i++)
-		if(a.b[i] != b.b[i])
-			return 0;
-	return 1;
-}
-*/
-
-int
-bnum(Bits a)
-{
-	int i;
-	long b;
-
-	for(i=0; i<BITS; i++)
-		if(b = a.b[i])
-			return 32*i + bitno(b);
-	diag(Z, "bad in bnum");
-	return 0;
-}
-
-Bits
-blsh(unsigned n)
-{
-	Bits c;
-
-	c = zbits;
-	c.b[n/32] = 1L << (n%32);
-	return c;
-}
-
-/*
-int
-bset(Bits a, unsigned n)
-{
-	int i;
-
-	if(a.b[n/32] & (1L << (n%32)))
-		return 1;
-	return 0;
-}
-*/
-
-int
-Bconv(va_list *arg, Fconv *fp)
-{
-	char str[STRINGSZ], ss[STRINGSZ], *s;
-	Bits bits;
-	int i;
-
-	str[0] = 0;
-	bits = va_arg(*arg, Bits);
-	while(bany(&bits)) {
-		i = bnum(bits);
-		if(str[0])
-			strcat(str, " ");
-		if(var[i].sym == S) {
-			sprint(ss, "$%ld", var[i].offset);
-			s = ss;
-		} else
-			s = var[i].sym->name;
-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
-			break;
-		strcat(str, s);
-		bits.b[i/32] &= ~(1L << (i%32));
-	}
-	strconv(str, fp);
-	return 0;
-}
--- a/sys/src/cmd/kc/mul.c
+++ b/sys/src/cmd/kc/mul.c
@@ -117,8 +117,7 @@
 	if(g) {
 		m1 = mulcon0(n, v);
 		if(m1) {
-			strcpy(m->code, m1->code);
-			sprint(strchr(m->code, 0), "%c0", g+'a');
+			snprint(m->code, sizeof(m->code), "%s%c0", m1->code, g+'a');
 			return m;
 		}
 	}
--- a/sys/src/cmd/qc/mul.c
+++ b/sys/src/cmd/qc/mul.c
@@ -117,8 +117,7 @@
 	if(g) {
 		m1 = mulcon0(n, v);
 		if(m1) {
-			strcpy(m->code, m1->code);
-			sprint(strchr(m->code, 0), "%c0", g+'a');
+			snprint(m->code, sizeof(m->code), "%s%c0", m1->code, g+'a');
 			return m;
 		}
 	}