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

📄 mnihongo.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/*output language from troff:all numbers are character stringssn	size in pointsfn	font as number from 1-ncx	ascii character xCxyz	funny char xyz. terminated by white spaceNn	absolute character number n on this font.  dittoHn	go to absolute horizontal position nVn	go to absolute vertical position n (down is positive)hn	go n units horizontally (relative)vn	ditto verticallynnc	move right nn, then print c (exactly 2 digits!)		(this wart is an optimization that shrinks output file size		 about 35% and run-time about 15% while preserving ascii-ness)Dt ...\n	draw operation 't':	Dl x y		line from here by x,y	Dc d		circle of diameter d with left side here	De x y		ellipse of axes x,y with left side here	Da dx dy dx dy	arc counter-clockwise, center at dx,dx, end at dx,dy	D~ x y x y ...	wiggly line by x,y then x,y ...nb a	end of line (information only -- no action needed)w	paddable word space -- no action needed	b = space before line, a = afterp	new page begins -- set v to 0#...\n	commentx ...\n	device control functions:	x i	init	x T s	name of device is s	x r n h v	resolution is n/inch		h = min horizontal motion, v = min vert	x p	pause (can restart)	x s	stop -- done for ever	x t	generate trailer	x f n s	font position n contains font s	x H n	set character height to n	x S n	set slant to N	Subcommands like "i" are often spelled out like "init".*/#include <u.h>#include <libc.h>#include <draw.h>#include <bio.h>#define hmot(n)	hpos += n#define hgoto(n)	hpos = n#define vmot(n)	vgoto(vpos + n)#define vgoto(n)	vpos = n#define	putchar(x)	Bprint(&bout, "%C", x)int	hpos;	/* horizontal position where we are supposed to be next (left = 0) */int	vpos;	/* current vertical position (down positive) */char	*fontfile	= "/lib/font/bit/pelm/unicode.9x24.font";char	*pschar(char *, char *hex, int *wid, int *ht);int	kanji(char *);void	Bgetstr(Biobuf *bp, char *s);void	Bgetline(Biobuf *bp, char *s);void	Bgetint(Biobuf *bp, int *n);Biobuf bin, bout;voidmain(void){	int c, n;	char str[100], *args[10];	int jfont, curfont;	if(initdraw(0, fontfile, 0) < 0){		fprint(2, "mnihongo: can't initialize display: %r\n");		exits("open");	}	Binit(&bin, 0, OREAD);	Binit(&bout, 1, OWRITE);	jfont = -1;	curfont = 1;	while ((c = Bgetc(&bin)) >= 0) {		switch (c) {		case '\n':	/* when input is text */		case ' ':		case '\0':		/* occasional noise creeps in */			putchar(c);			break;		case '0': case '1': case '2': case '3': case '4':		case '5': case '6': case '7': case '8': case '9':			/* two motion digits plus a character */			putchar(c);	/* digit 1 */			n = (c-'0')*10;			c = Bgetc(&bin);			putchar(c);	/* digit 2 */			n += c - '0';			hmot(n);			putchar(Bgetc(&bin));	/* char itself */			break;		case 'c':	/* single character */			c = Bgetrune(&bin);			if(c==' ')	/* why does this happen? it's troff - bwk */				break;			else if(jfont == curfont){				Bungetrune(&bin);				Bgetstr(&bin, str);				kanji(str);			}else{				putchar('c');				putchar(c);			}			break;		case 'C':			Bgetstr(&bin, str);			Bprint(&bout, "C%s", str);			break;		case 'f':			Bgetstr(&bin, str);			curfont = atoi(str);			if(curfont < 0 || curfont > 20)				curfont = 1;	/* sanity */			Bprint(&bout, "%c%s", c, str);			break;		case 'N':	/* absolute character number */		case 's':		case 'p':	/* new page */			Bgetint(&bin, &n);			Bprint(&bout, "%c%d", c, n);			break;		case 'H':	/* absolute horizontal motion */			Bgetint(&bin, &n);			Bprint(&bout, "%c%d", c, n);			hgoto(n);			break;		case 'h':	/* relative horizontal motion */			Bgetint(&bin, &n);			Bprint(&bout, "%c%d", c, n);			hmot(n);			break;		case 'V':			Bgetint(&bin, &n);			Bprint(&bout, "%c%d", c, n);			vgoto(n);			break;		case 'v':			Bgetint(&bin, &n);			Bprint(&bout, "%c%d", c, n);			vmot(n);			break;		case 'w':	/* word space */			putchar(c);			break;		case 'x':	/* device control */			Bgetline(&bin, str);			Bprint(&bout, "%c%s", c, str);			if(tokenize(str, args, 10)>2 && args[0][0]=='f' && ('0'<=args[1][0] && args[1][0]<='9')){				if(strncmp(args[2], "Jp", 2) == 0)					jfont = atoi(args[1]);				else if(atoi(args[1]) == jfont)					jfont = -1;			}			break;		case 'D':	/* draw function */		case 'n':	/* end of line */		case '#':	/* comment */			Bgetline(&bin, str);			Bprint(&bout, "%c%s", c, str);			break;		default:			fprint(2, "mnihongo: unknown input character %o %c\n", c, c);			exits("error");		}	}}int kanji(char *s)	/* very special pleading */{			/* dump as kanji char if looks like one */	Rune r;	char hex[500];	int size = 10, ht, wid;	chartorune(&r, s);	pschar(s, hex, &wid, &ht);	Bprint(&bout, "x X PS save %d %d m\n", hpos, vpos);	Bprint(&bout, "x X PS currentpoint translate %d %d scale ptsize dup scale\n", size, size);	Bprint(&bout, "x X PS %d %d true [%d 0 0 -%d 0 %d]\n",		wid, ht, wid, wid, ht-2);	/* kludge; ought to use ->ascent */	Bprint(&bout, "x X PS {<%s>}\n", hex);	Bprint(&bout, "x X PS imagemask restore\n");	return 1;}char *pschar(char *s, char *hex, int *wid, int *ht){	Point chpt, spt;	Image *b;	uchar rowdata[100];	char *hp = hex;	int y, i;	chpt = stringsize(font, s);		/* bounding box of char */	*wid = ((chpt.x+7) / 8) * 8;	*ht = chpt.y;	/* postscript is backwards to video, so draw white (ones) on black (zeros) */	b = allocimage(display, Rpt(ZP, chpt), GREY1, 0, DBlack);	/* place to put it */	spt = string(b, Pt(0,0), display->white, ZP, font, s);	/* put it there *//* Bprint(&bout, "chpt %P, spt %P, wid,ht %d,%d\n", chpt, spt, *wid, *ht);/* Bflush(&bout); */	for (y = 0; y < chpt.y; y++) {	/* read bits a row at a time */		memset(rowdata, 0, sizeof rowdata);		unloadimage(b, Rect(0, y, chpt.x, y+1), rowdata, sizeof rowdata);		for (i = 0; i < spt.x; i += 8) {	/* 8 == byte */			sprint(hp, "%2.2x", rowdata[i/8]);			hp += 2;		}	}	*hp = 0;	freeimage(b);	return hex;}void	Bgetstr(Biobuf *bp, char *s)	/* get a string */{	int c;	while ((c = Bgetc(bp)) >= 0) {		if (c == ' ' || c == '\t' || c == '\n') {			Bungetc(bp);			break;		}		*s++ = c;	}	*s = 0;}void	Bgetline(Biobuf *bp, char *s)	/* get a line, including newline */{	int c;	while ((c = Bgetc(bp)) >= 0) {		*s++ = c;		if (c == '\n')			break;	}	*s = 0;}void	Bgetint(Biobuf *bp, int *n)	/* get an integer */{	double d;	Bgetd(bp, &d);	*n = d;}

⌨️ 快捷键说明

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