xref: /plan9/sys/src/cmd/htmlroff/t8.c (revision 426d2b71458df9b491ba6c167f699b3f1f7b0428)
1*426d2b71SDavid du Colombier #include "a.h"
2*426d2b71SDavid du Colombier /*
3*426d2b71SDavid du Colombier  * 8. Number Registers
4*426d2b71SDavid du Colombier  * (Reg register implementation is also here.)
5*426d2b71SDavid du Colombier  */
6*426d2b71SDavid du Colombier 
7*426d2b71SDavid du Colombier /*
8*426d2b71SDavid du Colombier  *	\nx		N
9*426d2b71SDavid du Colombier  *	\n(xx	N
10*426d2b71SDavid du Colombier  *	\n+x		N+=M
11*426d2b71SDavid du Colombier  *	\n-x		N-=M
12*426d2b71SDavid du Colombier  *
13*426d2b71SDavid du Colombier  *	.nr R ±N M
14*426d2b71SDavid du Colombier  *	.af R c
15*426d2b71SDavid du Colombier  *
16*426d2b71SDavid du Colombier  *	formats
17*426d2b71SDavid du Colombier  *		1	0, 1, 2, 3, ...
18*426d2b71SDavid du Colombier  *		001	001, 002, 003, ...
19*426d2b71SDavid du Colombier  *		i	0, i, ii, iii, iv, v, ...
20*426d2b71SDavid du Colombier  *		I	0, I, II, III, IV, V, ...
21*426d2b71SDavid du Colombier  *		a	0, a, b, ..., aa, ab, ..., zz, aaa, ...
22*426d2b71SDavid du Colombier  *		A	0, A, B, ..., AA, AB, ..., ZZ, AAA, ...
23*426d2b71SDavid du Colombier  *
24*426d2b71SDavid du Colombier  *	\gx \g(xx return format of number register
25*426d2b71SDavid du Colombier  *
26*426d2b71SDavid du Colombier  *	.rr R
27*426d2b71SDavid du Colombier  */
28*426d2b71SDavid du Colombier 
29*426d2b71SDavid du Colombier typedef struct Reg Reg;
30*426d2b71SDavid du Colombier struct Reg
31*426d2b71SDavid du Colombier {
32*426d2b71SDavid du Colombier 	Reg *next;
33*426d2b71SDavid du Colombier 	Rune *name;
34*426d2b71SDavid du Colombier 	Rune *val;
35*426d2b71SDavid du Colombier 	Rune *fmt;
36*426d2b71SDavid du Colombier 	int inc;
37*426d2b71SDavid du Colombier };
38*426d2b71SDavid du Colombier 
39*426d2b71SDavid du Colombier Reg *dslist;
40*426d2b71SDavid du Colombier Reg *nrlist;
41*426d2b71SDavid du Colombier 
42*426d2b71SDavid du Colombier /*
43*426d2b71SDavid du Colombier  * Define strings and numbers.
44*426d2b71SDavid du Colombier  */
45*426d2b71SDavid du Colombier void
dsnr(Rune * name,Rune * val,Reg ** l)46*426d2b71SDavid du Colombier dsnr(Rune *name, Rune *val, Reg **l)
47*426d2b71SDavid du Colombier {
48*426d2b71SDavid du Colombier 	Reg *s;
49*426d2b71SDavid du Colombier 
50*426d2b71SDavid du Colombier 	for(s = *l; s != nil; s = *l){
51*426d2b71SDavid du Colombier 		if(runestrcmp(s->name, name) == 0)
52*426d2b71SDavid du Colombier 			break;
53*426d2b71SDavid du Colombier 		l = &s->next;
54*426d2b71SDavid du Colombier 	}
55*426d2b71SDavid du Colombier 	if(val == nil){
56*426d2b71SDavid du Colombier 		if(s){
57*426d2b71SDavid du Colombier 			*l = s->next;
58*426d2b71SDavid du Colombier 			free(s->val);
59*426d2b71SDavid du Colombier 			free(s->fmt);
60*426d2b71SDavid du Colombier 			free(s);
61*426d2b71SDavid du Colombier 		}
62*426d2b71SDavid du Colombier 		return;
63*426d2b71SDavid du Colombier 	}
64*426d2b71SDavid du Colombier 	if(s == nil){
65*426d2b71SDavid du Colombier 		s = emalloc(sizeof(Reg));
66*426d2b71SDavid du Colombier 		*l = s;
67*426d2b71SDavid du Colombier 		s->name = erunestrdup(name);
68*426d2b71SDavid du Colombier 	}else
69*426d2b71SDavid du Colombier 		free(s->val);
70*426d2b71SDavid du Colombier 	s->val = erunestrdup(val);
71*426d2b71SDavid du Colombier }
72*426d2b71SDavid du Colombier 
73*426d2b71SDavid du Colombier Rune*
getdsnr(Rune * name,Reg * list)74*426d2b71SDavid du Colombier getdsnr(Rune *name, Reg *list)
75*426d2b71SDavid du Colombier {
76*426d2b71SDavid du Colombier 	Reg *s;
77*426d2b71SDavid du Colombier 
78*426d2b71SDavid du Colombier 	for(s=list; s; s=s->next)
79*426d2b71SDavid du Colombier 		if(runestrcmp(name, s->name) == 0)
80*426d2b71SDavid du Colombier 			return s->val;
81*426d2b71SDavid du Colombier 	return nil;
82*426d2b71SDavid du Colombier }
83*426d2b71SDavid du Colombier 
84*426d2b71SDavid du Colombier void
ds(Rune * name,Rune * val)85*426d2b71SDavid du Colombier ds(Rune *name, Rune *val)
86*426d2b71SDavid du Colombier {
87*426d2b71SDavid du Colombier 	dsnr(name, val, &dslist);
88*426d2b71SDavid du Colombier }
89*426d2b71SDavid du Colombier 
90*426d2b71SDavid du Colombier void
as(Rune * name,Rune * val)91*426d2b71SDavid du Colombier as(Rune *name, Rune *val)
92*426d2b71SDavid du Colombier {
93*426d2b71SDavid du Colombier 	Rune *p, *q;
94*426d2b71SDavid du Colombier 
95*426d2b71SDavid du Colombier 	p = getds(name);
96*426d2b71SDavid du Colombier 	if(p == nil)
97*426d2b71SDavid du Colombier 		p = L("");
98*426d2b71SDavid du Colombier 	q = runemalloc(runestrlen(p)+runestrlen(val)+1);
99*426d2b71SDavid du Colombier 	runestrcpy(q, p);
100*426d2b71SDavid du Colombier 	runestrcat(q, val);
101*426d2b71SDavid du Colombier 	ds(name, q);
102*426d2b71SDavid du Colombier 	free(q);
103*426d2b71SDavid du Colombier }
104*426d2b71SDavid du Colombier 
105*426d2b71SDavid du Colombier Rune*
getds(Rune * name)106*426d2b71SDavid du Colombier getds(Rune *name)
107*426d2b71SDavid du Colombier {
108*426d2b71SDavid du Colombier 	return getdsnr(name, dslist);
109*426d2b71SDavid du Colombier }
110*426d2b71SDavid du Colombier 
111*426d2b71SDavid du Colombier void
printds(int t)112*426d2b71SDavid du Colombier printds(int t)
113*426d2b71SDavid du Colombier {
114*426d2b71SDavid du Colombier 	int n, total;
115*426d2b71SDavid du Colombier 	Reg *s;
116*426d2b71SDavid du Colombier 
117*426d2b71SDavid du Colombier 	total = 0;
118*426d2b71SDavid du Colombier 	for(s=dslist; s; s=s->next){
119*426d2b71SDavid du Colombier 		if(s->val)
120*426d2b71SDavid du Colombier 			n = runestrlen(s->val);
121*426d2b71SDavid du Colombier 		else
122*426d2b71SDavid du Colombier 			n = 0;
123*426d2b71SDavid du Colombier 		total += n;
124*426d2b71SDavid du Colombier 		if(!t)
125*426d2b71SDavid du Colombier 			fprint(2, "%S\t%d\n", s->name, n);
126*426d2b71SDavid du Colombier 	}
127*426d2b71SDavid du Colombier 	fprint(2, "total\t%d\n", total);
128*426d2b71SDavid du Colombier }
129*426d2b71SDavid du Colombier 
130*426d2b71SDavid du Colombier void
nr(Rune * name,int val)131*426d2b71SDavid du Colombier nr(Rune *name, int val)
132*426d2b71SDavid du Colombier {
133*426d2b71SDavid du Colombier 	Rune buf[20];
134*426d2b71SDavid du Colombier 
135*426d2b71SDavid du Colombier 	runesnprint(buf, nelem(buf), "%d", val);
136*426d2b71SDavid du Colombier 	_nr(name, buf);
137*426d2b71SDavid du Colombier }
138*426d2b71SDavid du Colombier 
139*426d2b71SDavid du Colombier void
af(Rune * name,Rune * fmt)140*426d2b71SDavid du Colombier af(Rune *name, Rune *fmt)
141*426d2b71SDavid du Colombier {
142*426d2b71SDavid du Colombier 	Reg *s;
143*426d2b71SDavid du Colombier 
144*426d2b71SDavid du Colombier 	if(_getnr(name) == nil)
145*426d2b71SDavid du Colombier 		_nr(name, L("0"));
146*426d2b71SDavid du Colombier 	for(s=nrlist; s; s=s->next)
147*426d2b71SDavid du Colombier 		if(runestrcmp(s->name, name) == 0)
148*426d2b71SDavid du Colombier 			s->fmt = erunestrdup(fmt);
149*426d2b71SDavid du Colombier }
150*426d2b71SDavid du Colombier 
151*426d2b71SDavid du Colombier Rune*
getaf(Rune * name)152*426d2b71SDavid du Colombier getaf(Rune *name)
153*426d2b71SDavid du Colombier {
154*426d2b71SDavid du Colombier 	Reg *s;
155*426d2b71SDavid du Colombier 
156*426d2b71SDavid du Colombier 	for(s=nrlist; s; s=s->next)
157*426d2b71SDavid du Colombier 		if(runestrcmp(s->name, name) == 0)
158*426d2b71SDavid du Colombier 			return s->fmt;
159*426d2b71SDavid du Colombier 	return nil;
160*426d2b71SDavid du Colombier }
161*426d2b71SDavid du Colombier 
162*426d2b71SDavid du Colombier void
printnr(void)163*426d2b71SDavid du Colombier printnr(void)
164*426d2b71SDavid du Colombier {
165*426d2b71SDavid du Colombier 	Reg *r;
166*426d2b71SDavid du Colombier 
167*426d2b71SDavid du Colombier 	for(r=nrlist; r; r=r->next)
168*426d2b71SDavid du Colombier 		fprint(2, "%S %S %d\n", r->name, r->val, r->inc);
169*426d2b71SDavid du Colombier }
170*426d2b71SDavid du Colombier 
171*426d2b71SDavid du Colombier /*
172*426d2b71SDavid du Colombier  * Some internal number registers are actually strings,
173*426d2b71SDavid du Colombier  * so provide _ versions to get at them.
174*426d2b71SDavid du Colombier  */
175*426d2b71SDavid du Colombier void
_nr(Rune * name,Rune * val)176*426d2b71SDavid du Colombier _nr(Rune *name, Rune *val)
177*426d2b71SDavid du Colombier {
178*426d2b71SDavid du Colombier 	dsnr(name, val, &nrlist);
179*426d2b71SDavid du Colombier }
180*426d2b71SDavid du Colombier 
181*426d2b71SDavid du Colombier Rune*
_getnr(Rune * name)182*426d2b71SDavid du Colombier _getnr(Rune *name)
183*426d2b71SDavid du Colombier {
184*426d2b71SDavid du Colombier 	return getdsnr(name, nrlist);
185*426d2b71SDavid du Colombier }
186*426d2b71SDavid du Colombier 
187*426d2b71SDavid du Colombier int
getnr(Rune * name)188*426d2b71SDavid du Colombier getnr(Rune *name)
189*426d2b71SDavid du Colombier {
190*426d2b71SDavid du Colombier 	Rune *p;
191*426d2b71SDavid du Colombier 
192*426d2b71SDavid du Colombier 	p = _getnr(name);
193*426d2b71SDavid du Colombier 	if(p == nil)
194*426d2b71SDavid du Colombier 		return 0;
195*426d2b71SDavid du Colombier 	return eval(p);
196*426d2b71SDavid du Colombier }
197*426d2b71SDavid du Colombier 
198*426d2b71SDavid du Colombier /* new register */
199*426d2b71SDavid du Colombier void
r_nr(int argc,Rune ** argv)200*426d2b71SDavid du Colombier r_nr(int argc, Rune **argv)
201*426d2b71SDavid du Colombier {
202*426d2b71SDavid du Colombier 	Reg *s;
203*426d2b71SDavid du Colombier 
204*426d2b71SDavid du Colombier 	if(argc < 2)
205*426d2b71SDavid du Colombier 		return;
206*426d2b71SDavid du Colombier 	if(argc < 3)
207*426d2b71SDavid du Colombier 		nr(argv[1], 0);
208*426d2b71SDavid du Colombier 	else{
209*426d2b71SDavid du Colombier 		if(argv[2][0] == '+')
210*426d2b71SDavid du Colombier 			nr(argv[1], getnr(argv[1])+eval(argv[2]+1));
211*426d2b71SDavid du Colombier 		else if(argv[2][0] == '-')
212*426d2b71SDavid du Colombier 			nr(argv[1], getnr(argv[1])-eval(argv[2]+1));
213*426d2b71SDavid du Colombier 		else
214*426d2b71SDavid du Colombier 			nr(argv[1], eval(argv[2]));
215*426d2b71SDavid du Colombier 	}
216*426d2b71SDavid du Colombier 	if(argc > 3){
217*426d2b71SDavid du Colombier 		for(s=nrlist; s; s=s->next)
218*426d2b71SDavid du Colombier 			if(runestrcmp(s->name, argv[1]) == 0)
219*426d2b71SDavid du Colombier 				s->inc = eval(argv[3]);
220*426d2b71SDavid du Colombier 	}
221*426d2b71SDavid du Colombier }
222*426d2b71SDavid du Colombier 
223*426d2b71SDavid du Colombier /* assign format */
224*426d2b71SDavid du Colombier void
r_af(int argc,Rune ** argv)225*426d2b71SDavid du Colombier r_af(int argc, Rune **argv)
226*426d2b71SDavid du Colombier {
227*426d2b71SDavid du Colombier 	USED(argc);
228*426d2b71SDavid du Colombier 
229*426d2b71SDavid du Colombier 	af(argv[1], argv[2]);
230*426d2b71SDavid du Colombier }
231*426d2b71SDavid du Colombier 
232*426d2b71SDavid du Colombier /* remove register */
233*426d2b71SDavid du Colombier void
r_rr(int argc,Rune ** argv)234*426d2b71SDavid du Colombier r_rr(int argc, Rune **argv)
235*426d2b71SDavid du Colombier {
236*426d2b71SDavid du Colombier 	int i;
237*426d2b71SDavid du Colombier 
238*426d2b71SDavid du Colombier 	for(i=1; i<argc; i++)
239*426d2b71SDavid du Colombier 		_nr(argv[i], nil);
240*426d2b71SDavid du Colombier }
241*426d2b71SDavid du Colombier 
242*426d2b71SDavid du Colombier /* fmt integer in base 26 */
243*426d2b71SDavid du Colombier void
alpha(Rune * buf,int n,int a)244*426d2b71SDavid du Colombier alpha(Rune *buf, int n, int a)
245*426d2b71SDavid du Colombier {
246*426d2b71SDavid du Colombier 	int i, v;
247*426d2b71SDavid du Colombier 
248*426d2b71SDavid du Colombier 	i = 1;
249*426d2b71SDavid du Colombier 	for(v=n; v>0; v/=26)
250*426d2b71SDavid du Colombier 		i++;
251*426d2b71SDavid du Colombier 	if(i == 0)
252*426d2b71SDavid du Colombier 		i = 1;
253*426d2b71SDavid du Colombier 	buf[i] = 0;
254*426d2b71SDavid du Colombier 	while(i > 0){
255*426d2b71SDavid du Colombier 		buf[--i] = a+n%26;
256*426d2b71SDavid du Colombier 		n /= 26;
257*426d2b71SDavid du Colombier 	}
258*426d2b71SDavid du Colombier }
259*426d2b71SDavid du Colombier 
260*426d2b71SDavid du Colombier struct romanv {
261*426d2b71SDavid du Colombier 	char *s;
262*426d2b71SDavid du Colombier 	int v;
263*426d2b71SDavid du Colombier } romanv[] =
264*426d2b71SDavid du Colombier {
265*426d2b71SDavid du Colombier 	"m",	1000,
266*426d2b71SDavid du Colombier 	"cm", 900,
267*426d2b71SDavid du Colombier 	"d", 500,
268*426d2b71SDavid du Colombier 	"cd", 400,
269*426d2b71SDavid du Colombier 	"c", 100,
270*426d2b71SDavid du Colombier 	"xc", 90,
271*426d2b71SDavid du Colombier 	"l", 50,
272*426d2b71SDavid du Colombier 	"xl", 40,
273*426d2b71SDavid du Colombier 	"x", 10,
274*426d2b71SDavid du Colombier 	"ix", 9,
275*426d2b71SDavid du Colombier 	"v", 5,
276*426d2b71SDavid du Colombier 	"iv", 4,
277*426d2b71SDavid du Colombier 	"i", 1
278*426d2b71SDavid du Colombier };
279*426d2b71SDavid du Colombier 
280*426d2b71SDavid du Colombier /* fmt integer in roman numerals! */
281*426d2b71SDavid du Colombier void
roman(Rune * buf,int n,int upper)282*426d2b71SDavid du Colombier roman(Rune *buf, int n, int upper)
283*426d2b71SDavid du Colombier {
284*426d2b71SDavid du Colombier 	Rune *p;
285*426d2b71SDavid du Colombier 	char *q;
286*426d2b71SDavid du Colombier 	struct romanv *r;
287*426d2b71SDavid du Colombier 
288*426d2b71SDavid du Colombier 	if(upper)
289*426d2b71SDavid du Colombier 		upper = 'A' - 'a';
290*426d2b71SDavid du Colombier 	if(n >= 5000 || n <= 0){
291*426d2b71SDavid du Colombier 		runestrcpy(buf, L("-"));
292*426d2b71SDavid du Colombier 		return;
293*426d2b71SDavid du Colombier 	}
294*426d2b71SDavid du Colombier 	p = buf;
295*426d2b71SDavid du Colombier 	r = romanv;
296*426d2b71SDavid du Colombier 	while(n > 0){
297*426d2b71SDavid du Colombier 		while(n >= r->v){
298*426d2b71SDavid du Colombier 			for(q=r->s; *q; q++)
299*426d2b71SDavid du Colombier 				*p++ = *q + upper;
300*426d2b71SDavid du Colombier 			n -= r->v;
301*426d2b71SDavid du Colombier 		}
302*426d2b71SDavid du Colombier 		r++;
303*426d2b71SDavid du Colombier 	}
304*426d2b71SDavid du Colombier 	*p = 0;
305*426d2b71SDavid du Colombier }
306*426d2b71SDavid du Colombier 
307*426d2b71SDavid du Colombier Rune*
getname(void)308*426d2b71SDavid du Colombier getname(void)
309*426d2b71SDavid du Colombier {
310*426d2b71SDavid du Colombier 	int i, c, cc;
311*426d2b71SDavid du Colombier 	static Rune buf[100];
312*426d2b71SDavid du Colombier 
313*426d2b71SDavid du Colombier 	/* XXX add [name] syntax as in groff */
314*426d2b71SDavid du Colombier 	c = getnext();
315*426d2b71SDavid du Colombier 	if(c < 0)
316*426d2b71SDavid du Colombier 		return L("");
317*426d2b71SDavid du Colombier 	if(c == '\n'){
318*426d2b71SDavid du Colombier 		warn("newline in name\n");
319*426d2b71SDavid du Colombier 		ungetnext(c);
320*426d2b71SDavid du Colombier 		return L("");
321*426d2b71SDavid du Colombier 	}
322*426d2b71SDavid du Colombier 	if(c == '['){
323*426d2b71SDavid du Colombier 		for(i=0; i<nelem(buf)-1; i++){
324*426d2b71SDavid du Colombier 			if((c = getrune()) < 0)
325*426d2b71SDavid du Colombier 				return L("");
326*426d2b71SDavid du Colombier 			if(c == ']'){
327*426d2b71SDavid du Colombier 				buf[i] = 0;
328*426d2b71SDavid du Colombier 				return buf;
329*426d2b71SDavid du Colombier 			}
330*426d2b71SDavid du Colombier 			buf[i] = c;
331*426d2b71SDavid du Colombier 		}
332*426d2b71SDavid du Colombier 		return L("");
333*426d2b71SDavid du Colombier 	}
334*426d2b71SDavid du Colombier 	if(c != '('){
335*426d2b71SDavid du Colombier 		buf[0] = c;
336*426d2b71SDavid du Colombier 		buf[1] = 0;
337*426d2b71SDavid du Colombier 		return buf;
338*426d2b71SDavid du Colombier 	}
339*426d2b71SDavid du Colombier 	c = getnext();
340*426d2b71SDavid du Colombier 	cc = getnext();
341*426d2b71SDavid du Colombier 	if(c < 0 || cc < 0)
342*426d2b71SDavid du Colombier 		return L("");
343*426d2b71SDavid du Colombier 	if(c == '\n' | cc == '\n'){
344*426d2b71SDavid du Colombier 		warn("newline in \\n");
345*426d2b71SDavid du Colombier 		ungetnext(cc);
346*426d2b71SDavid du Colombier 		if(c == '\n')
347*426d2b71SDavid du Colombier 			ungetnext(c);
348*426d2b71SDavid du Colombier 	}
349*426d2b71SDavid du Colombier 	buf[0] = c;
350*426d2b71SDavid du Colombier 	buf[1] = cc;
351*426d2b71SDavid du Colombier 	buf[2] = 0;
352*426d2b71SDavid du Colombier 	return buf;
353*426d2b71SDavid du Colombier }
354*426d2b71SDavid du Colombier 
355*426d2b71SDavid du Colombier /* \n - return number register */
356*426d2b71SDavid du Colombier int
e_n(void)357*426d2b71SDavid du Colombier e_n(void)
358*426d2b71SDavid du Colombier {
359*426d2b71SDavid du Colombier 	int inc, v, l;
360*426d2b71SDavid du Colombier 	Rune *name, *fmt, buf[100];
361*426d2b71SDavid du Colombier 	Reg *s;
362*426d2b71SDavid du Colombier 
363*426d2b71SDavid du Colombier 	inc = getnext();
364*426d2b71SDavid du Colombier 	if(inc < 0)
365*426d2b71SDavid du Colombier 		return -1;
366*426d2b71SDavid du Colombier 	if(inc != '+' && inc != '-'){
367*426d2b71SDavid du Colombier 		ungetnext(inc);
368*426d2b71SDavid du Colombier 		inc = 0;
369*426d2b71SDavid du Colombier 	}
370*426d2b71SDavid du Colombier 	name = getname();
371*426d2b71SDavid du Colombier 	if(_getnr(name) == nil)
372*426d2b71SDavid du Colombier 		_nr(name, L("0"));
373*426d2b71SDavid du Colombier 	for(s=nrlist; s; s=s->next){
374*426d2b71SDavid du Colombier 		if(runestrcmp(s->name, name) == 0){
375*426d2b71SDavid du Colombier 			if(s->fmt == nil && !inc && s->val[0]){
376*426d2b71SDavid du Colombier 				/* might be a string! */
377*426d2b71SDavid du Colombier 				pushinputstring(s->val);
378*426d2b71SDavid du Colombier 				return 0;
379*426d2b71SDavid du Colombier 			}
380*426d2b71SDavid du Colombier 			v = eval(s->val);
381*426d2b71SDavid du Colombier 			if(inc){
382*426d2b71SDavid du Colombier 				if(inc == '+')
383*426d2b71SDavid du Colombier 					v += s->inc;
384*426d2b71SDavid du Colombier 				else
385*426d2b71SDavid du Colombier 					v -= s->inc;
386*426d2b71SDavid du Colombier 				runesnprint(buf, nelem(buf), "%d", v);
387*426d2b71SDavid du Colombier 				free(s->val);
388*426d2b71SDavid du Colombier 				s->val = erunestrdup(buf);
389*426d2b71SDavid du Colombier 			}
390*426d2b71SDavid du Colombier 			fmt = s->fmt;
391*426d2b71SDavid du Colombier 			if(fmt == nil)
392*426d2b71SDavid du Colombier 				fmt = L("1");
393*426d2b71SDavid du Colombier 			switch(fmt[0]){
394*426d2b71SDavid du Colombier 			case 'i':
395*426d2b71SDavid du Colombier 			case 'I':
396*426d2b71SDavid du Colombier 				roman(buf, v, fmt[0]=='I');
397*426d2b71SDavid du Colombier 				break;
398*426d2b71SDavid du Colombier 			case 'a':
399*426d2b71SDavid du Colombier 			case 'A':
400*426d2b71SDavid du Colombier 				alpha(buf, v, fmt[0]);
401*426d2b71SDavid du Colombier 				break;
402*426d2b71SDavid du Colombier 			default:
403*426d2b71SDavid du Colombier 				l = runestrlen(fmt);
404*426d2b71SDavid du Colombier 				if(l == 0)
405*426d2b71SDavid du Colombier 					l = 1;
406*426d2b71SDavid du Colombier 				runesnprint(buf, sizeof buf, "%0*d", l, v);
407*426d2b71SDavid du Colombier 				break;
408*426d2b71SDavid du Colombier 			}
409*426d2b71SDavid du Colombier 			pushinputstring(buf);
410*426d2b71SDavid du Colombier 			return 0;
411*426d2b71SDavid du Colombier 		}
412*426d2b71SDavid du Colombier 	}
413*426d2b71SDavid du Colombier 	pushinputstring(L(""));
414*426d2b71SDavid du Colombier 	return 0;
415*426d2b71SDavid du Colombier }
416*426d2b71SDavid du Colombier 
417*426d2b71SDavid du Colombier /* \g - number register format */
418*426d2b71SDavid du Colombier int
e_g(void)419*426d2b71SDavid du Colombier e_g(void)
420*426d2b71SDavid du Colombier {
421*426d2b71SDavid du Colombier 	Rune *p;
422*426d2b71SDavid du Colombier 
423*426d2b71SDavid du Colombier 	p = getaf(getname());
424*426d2b71SDavid du Colombier 	if(p == nil)
425*426d2b71SDavid du Colombier 		p = L("1");
426*426d2b71SDavid du Colombier 	pushinputstring(p);
427*426d2b71SDavid du Colombier 	return 0;
428*426d2b71SDavid du Colombier }
429*426d2b71SDavid du Colombier 
430*426d2b71SDavid du Colombier void
r_pnr(int argc,Rune ** argv)431*426d2b71SDavid du Colombier r_pnr(int argc, Rune **argv)
432*426d2b71SDavid du Colombier {
433*426d2b71SDavid du Colombier 	USED(argc);
434*426d2b71SDavid du Colombier 	USED(argv);
435*426d2b71SDavid du Colombier 	printnr();
436*426d2b71SDavid du Colombier }
437*426d2b71SDavid du Colombier 
438*426d2b71SDavid du Colombier void
t8init(void)439*426d2b71SDavid du Colombier t8init(void)
440*426d2b71SDavid du Colombier {
441*426d2b71SDavid du Colombier 	addreq(L("nr"), r_nr, -1);
442*426d2b71SDavid du Colombier 	addreq(L("af"), r_af, 2);
443*426d2b71SDavid du Colombier 	addreq(L("rr"), r_rr, -1);
444*426d2b71SDavid du Colombier 	addreq(L("pnr"), r_pnr, 0);
445*426d2b71SDavid du Colombier 
446*426d2b71SDavid du Colombier 	addesc('n', e_n, CopyMode|ArgMode|HtmlMode);
447*426d2b71SDavid du Colombier 	addesc('g', e_g, 0);
448*426d2b71SDavid du Colombier }
449*426d2b71SDavid du Colombier 
450