⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t8.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "a.h"/* * 8. Number Registers * (Reg register implementation is also here.) *//* *	\nx		N *	\n(xx	N *	\n+x		N+=M *	\n-x		N-=M * *	.nr R ±N M *	.af R c * *	formats *		1	0, 1, 2, 3, ... *		001	001, 002, 003, ... *		i	0, i, ii, iii, iv, v, ... *		I	0, I, II, III, IV, V, ... *		a	0, a, b, ..., aa, ab, ..., zz, aaa, ... *		A	0, A, B, ..., AA, AB, ..., ZZ, AAA, ... * *	\gx \g(xx return format of number register * *	.rr R */typedef struct Reg Reg;struct Reg{	Reg *next;	Rune *name;	Rune *val;	Rune *fmt;	int inc;};Reg *dslist;Reg *nrlist;/* * Define strings and numbers. */voiddsnr(Rune *name, Rune *val, Reg **l){	Reg *s;	for(s = *l; s != nil; s = *l){		if(runestrcmp(s->name, name) == 0)			break;		l = &s->next;	}	if(val == nil){		if(s){			*l = s->next;			free(s->val);			free(s->fmt);			free(s);		}		return;	}	if(s == nil){		s = emalloc(sizeof(Reg));		*l = s;		s->name = erunestrdup(name);	}else		free(s->val);	s->val = erunestrdup(val);}Rune*getdsnr(Rune *name, Reg *list){	Reg *s;		for(s=list; s; s=s->next)		if(runestrcmp(name, s->name) == 0)			return s->val;	return nil;}voidds(Rune *name, Rune *val){	dsnr(name, val, &dslist);}voidas(Rune *name, Rune *val){	Rune *p, *q;		p = getds(name);	if(p == nil)		p = L("");	q = runemalloc(runestrlen(p)+runestrlen(val)+1);	runestrcpy(q, p);	runestrcat(q, val);	ds(name, q);	free(q);}Rune*getds(Rune *name){	return getdsnr(name, dslist);}voidprintds(int t){	int n, total;	Reg *s;		total = 0;	for(s=dslist; s; s=s->next){		if(s->val)			n = runestrlen(s->val);		else			n = 0;		total += n;		if(!t)			fprint(2, "%S\t%d\n", s->name, n);	}	fprint(2, "total\t%d\n", total);}voidnr(Rune *name, int val){	Rune buf[20];		runesnprint(buf, nelem(buf), "%d", val);	_nr(name, buf);}voidaf(Rune *name, Rune *fmt){	Reg *s;	if(_getnr(name) == nil)		_nr(name, L("0"));	for(s=nrlist; s; s=s->next)		if(runestrcmp(s->name, name) == 0)			s->fmt = erunestrdup(fmt);}Rune*getaf(Rune *name){	Reg *s;		for(s=nrlist; s; s=s->next)		if(runestrcmp(s->name, name) == 0)			return s->fmt;	return nil;}voidprintnr(void){	Reg *r;		for(r=nrlist; r; r=r->next)		fprint(2, "%S %S %d\n", r->name, r->val, r->inc);}/* * Some internal number registers are actually strings, * so provide _ versions to get at them. */void_nr(Rune *name, Rune *val){	dsnr(name, val, &nrlist);}Rune*_getnr(Rune *name){	return getdsnr(name, nrlist);}intgetnr(Rune *name){	Rune *p;	p = _getnr(name);	if(p == nil)		return 0;	return eval(p);}/* new register */voidr_nr(int argc, Rune **argv){	Reg *s;	if(argc < 2)		return;	if(argc < 3)		nr(argv[1], 0);	else{		if(argv[2][0] == '+')			nr(argv[1], getnr(argv[1])+eval(argv[2]+1));		else if(argv[2][0] == '-')			nr(argv[1], getnr(argv[1])-eval(argv[2]+1));		else			nr(argv[1], eval(argv[2]));	}	if(argc > 3){		for(s=nrlist; s; s=s->next)			if(runestrcmp(s->name, argv[1]) == 0)				s->inc = eval(argv[3]);	}}/* assign format */voidr_af(int argc, Rune **argv){	USED(argc);		af(argv[1], argv[2]);}/* remove register */voidr_rr(int argc, Rune **argv){	int i;		for(i=1; i<argc; i++)		_nr(argv[i], nil);}/* fmt integer in base 26 */voidalpha(Rune *buf, int n, int a){	int i, v;		i = 1;	for(v=n; v>0; v/=26)		i++;	if(i == 0)		i = 1;	buf[i] = 0;	while(i > 0){		buf[--i] = a+n%26;		n /= 26;	}}struct romanv {	char *s;	int v;} romanv[] ={	"m",	1000,	"cm", 900,	"d", 500,	"cd", 400,	"c", 100,	"xc", 90,	"l", 50,	"xl", 40,	"x", 10,	"ix", 9,	"v", 5,	"iv", 4,	"i", 1};/* fmt integer in roman numerals! */voidroman(Rune *buf, int n, int upper){	Rune *p;	char *q;	struct romanv *r;		if(upper)		upper = 'A' - 'a';	if(n >= 5000 || n <= 0){		runestrcpy(buf, L("-"));		return;	}	p = buf;	r = romanv;	while(n > 0){		while(n >= r->v){			for(q=r->s; *q; q++)				*p++ = *q + upper;			n -= r->v;		}		r++;	}	*p = 0;}Rune*getname(void){	int i, c, cc;	static Rune buf[100];		/* XXX add [name] syntax as in groff */	c = getnext();	if(c < 0)		return L("");	if(c == '\n'){		warn("newline in name\n");		ungetnext(c);		return L("");	}	if(c == '['){		for(i=0; i<nelem(buf)-1; i++){			if((c = getrune()) < 0)				return L("");			if(c == ']'){				buf[i] = 0;				return buf;			}			buf[i] = c;		}		return L("");	}	if(c != '('){		buf[0] = c;		buf[1] = 0;		return buf;	}	c = getnext();	cc = getnext();	if(c < 0 || cc < 0)		return L("");	if(c == '\n' | cc == '\n'){		warn("newline in \\n");		ungetnext(cc);		if(c == '\n')			ungetnext(c);	}	buf[0] = c;	buf[1] = cc;	buf[2] = 0;	return buf;}/* \n - return number register */inte_n(void){	int inc, v, l;	Rune *name, *fmt, buf[100];	Reg *s;		inc = getnext();	if(inc < 0)		return -1;	if(inc != '+' && inc != '-'){		ungetnext(inc);		inc = 0;	}	name = getname();	if(_getnr(name) == nil)		_nr(name, L("0"));	for(s=nrlist; s; s=s->next){		if(runestrcmp(s->name, name) == 0){			if(s->fmt == nil && !inc && s->val[0]){				/* might be a string! */				pushinputstring(s->val);				return 0;			}			v = eval(s->val);			if(inc){				if(inc == '+')					v += s->inc;				else					v -= s->inc;				runesnprint(buf, nelem(buf), "%d", v);				free(s->val);				s->val = erunestrdup(buf);			}			fmt = s->fmt;			if(fmt == nil)				fmt = L("1");			switch(fmt[0]){			case 'i':			case 'I':				roman(buf, v, fmt[0]=='I');				break;			case 'a':			case 'A':				alpha(buf, v, fmt[0]);				break;			default:				l = runestrlen(fmt);				if(l == 0)					l = 1;				runesnprint(buf, sizeof buf, "%0*d", l, v);				break;			}			pushinputstring(buf);			return 0;		}	}	pushinputstring(L(""));	return 0;}/* \g - number register format */inte_g(void){	Rune *p;	p = getaf(getname());	if(p == nil)		p = L("1");	pushinputstring(p);	return 0;}voidr_pnr(int argc, Rune **argv){	USED(argc);	USED(argv);	printnr();}voidt8init(void){	addreq(L("nr"), r_nr, -1);	addreq(L("af"), r_af, 2);	addreq(L("rr"), r_rr, -1);	addreq(L("pnr"), r_pnr, 0);		addesc('n', e_n, CopyMode|ArgMode|HtmlMode);	addesc('g', e_g, 0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -