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

📄 pass3.c

📁 操作系统源代码
💻 C
字号:
/* *	pass3.c - cawf(1) pass 3 function *//* *	Copyright (c) 1991 Purdue University Research Foundation, *	West Lafayette, Indiana 47907.  All rights reserved. * *	Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue *	University Computing Center.  Not derived from licensed software; *	derived from awf(1) by Henry Spencer of the University of Toronto. * *	Permission is granted to anyone to use this software for any *	purpose on any computer system, and to alter it and redistribute *	it freely, subject to the following restrictions: * *	1. The author is not responsible for any consequences of use of *	   this software, even if they arise from flaws in it. * *	2. The origin of this software must not be misrepresented, either *	   by explicit claim or by omission.  Credits must appear in the *	   documentation. * *	3. Altered versions must be plainly marked as such, and must not *	   be misrepresented as being the original software.  Credits must *	   appear in the documentation. * *	4. This notice may not be removed or altered. */#include "cawf.h"voidPass3(len, word, sarg, narg)	int len;			/* length (negative is special) */	unsigned char *word;		/* word */	unsigned char *sarg;		/* string argument */	int narg;			/* numeric argument */{	int addto;			/* spaces to add to all words */	int i, j, k;			/* temporary index */	unsigned char msg[MAXLINE];	/* message buffer */	int n;				/* temporary number */	unsigned char *s1;		/* temporary string pointer */	int sp = 0;			/* no-break spacing switch */	int sp_Outll;			/* sp-saved Outll */	char sp_Outln;			/* sp-saved Outln[0] */	int sp_Outlx;			/* sp-saved Outlx */	int sp_Padx;			/* sp-saved Padx */	int sp_Tind;			/* sp-saved Tind */	int wl;				/* real word length */	int xsp;			/* extra spaces to add */	int vsp;			/* vertical spacing status */	vsp = 0;	if (word != NULL)		wl = strlen((char *)word);    /*     * If not a special command, process a word.     */	if (len >= 0 && Outll < 0) {	/*	 * Enter first word.	 */		(void) strcpy((char *)Outln, (char *)word);		Outll = len;		Outlx = wl;		Padx = 0;	} else if (len >= 0	       && (Outll+Contlen+len+narg) <= (LL-Pgoff-Ind-Tind)) {	/*	 * The word fits, so enter it.	 */		if ((Contlen + len) > 0) {line_too_big:			if ((Outlx + Contlen + wl) >= MAXOLL) {				Error3(len, (char *)word, (char *)sarg, narg,					"output line too big");				return;			} else {				if (Contlen > 0 && Cont != NULL) {					if (Contlen == 1 && *Cont == ' ') {						Padchar[Padx++] = Outlx;						Outln[Outlx++] = ' ';					} else {					    (void) strcpy((char *)&Outln[Outlx],						(char *)Cont);					    Outlx += Contlen;					}				}				if (len > 0) {					(void) strcpy((char *)&Outln[Outlx],						(char *)word);					Outlx += wl;				}			}		}		Outll += Contlen + len;	} else if (len == NOBREAK || len == MESSAGE) {		/*		 * Do nothing (equivalent to break)		 */	} else if (len == DOBREAK && strcmp((char *)word, "need") == 0	       &&  (Nxtln + narg) < (Pglen + 1 - Botmarg)) {		/*		 * Do nothing, because there is room on the page.		 */	} else if (len == DOBREAK && strcmp((char *)word, "toindent") == 0	       &&  (Ind + Tind + Outll) < Ind) {	/*	 * Move to indent position with line - there is room.	 */		n = Ind - (Ind + Tind +Outll);		Outll += n;		if ((Outlx + n) >= MAXOLL)			goto line_too_big;		for (i = n; i; i--)			Outln[Outlx++] = ' ';		Padx = 0;		Free(&Cont);		Contlen = 0;	} else if (Outll >= 0	       || (len == DOBREAK && strcmp((char *)word, "need") == 0)) {	/*	 * A non-empty line or a "need" forces output.	 */		vsp = 0;print_line:		if (Nxtln == 1) {	    /*	     * We're at the top of the page, so issue the header.	     */			if (Thispg > 1)				Charput((int)'\f');			for (i = (Topmarg - 1)/2; i > 0; i--) {				Charput((int)'\n');				Nxtln++;			}		    /*		     * Print the page header, as required.		     */			if (Fph || Thispg > 1) {				i = LenprtHF(Hdc, Thispg, 0)				  + LenprtHF(Hdl, Thispg, 0)				  + LenprtHF(Hdr, Thispg, 0) + 2;				j = (LL - i - Pgoff) / 2 + 1;				n = LL - Pgoff - i - j + 2;				for (k = 0; k < Pgoff; k++)					Charput((int)' ');				if (Hdl)					LenprtHF(Hdl, Thispg, 1);				while (j--)					Charput((int)' ');				if (Hdc)					LenprtHF(Hdc, Thispg, 1);				while (n--)					Charput((int)' ');				if (Hdr)					LenprtHF(Hdr, Thispg, 1);				Charput((int)'\n');			} else				Charput((int)'\n');			Nxtln++;			while(Nxtln <= Topmarg) {				Charput((int)'\n');				Nxtln++;			}		}	    /*	     *  Add a trailing hyphen, if mecessary.	     */     		if (vsp == 0 && Eollen > 0 && Eol != NULL) {			i = strlen((char *)Eol);			if ((Outlx + i) >= MAXOLL)				goto line_too_big;			(void) strcpy((char *)&Outln[Outlx], (char *)Eol);			Outlx += i;			Outll += Eollen;		}	    /*	     * Trim trailing spaces from the output line.	     */     		while (Outlx > 0) {			if (Outln[Outlx - 1] != ' ')				break;			if (Padx > 0 && (Outlx - 1) == Padchar[Padx - 1])				Padx--;			Outlx--;			Outln[Outlx] = '\0';			Outll--;		}		if (Outlx == 0)			Charput((int)'\n');		else if (len == DOBREAK && strcmp((char *)word, "center") == 0)		    {		    /*		     * Center the output line.		     */			i = (LL - Pgoff - Outll) / 2;			if (i < 0)				i = 0;			for (j = (Pgoff + Ind + Tind + i); j; j--)				Charput((int)' ');			Stringput(Outln);			Charput((int)'\n');		} else if (Adj == LEFTADJ		       || (Adj == BOTHADJ && (len < 0 || Padx == 0))) {		    /*		     * No right margin adjustment - disabled, inappropriate		     * (line ended by break) or impossible.		     */			for (i = 0; i < (Pgoff + Ind + Tind); i++)				Charput((int)' ');			Stringput(Outln);			Charput((int)'\n');		} else if (Adj == BOTHADJ) {		    /*		     * Adjust right margin.		     */			for (i = 0; i < (Pgoff + Ind + Tind); i++)				Charput((int)' ');			i = LL - (Pgoff + Ind + Tind);			j = i - Outll;			addto = Padx ? (j / Padx) : 0;			xsp = j - (Padx * addto);			for (i = 0, s1 = Outln; i < Padx; i++) {				while (*s1 && (s1 - Outln) <= Padchar[i])					Charput((int)*s1++);				if (*s1 == '\0')					break;				j = addto;				if (Padfrom == PADLEFT) {					if (i < xsp)						j++;				} else if (i >= (Padx - xsp))					j++;				while (j--)					Charput((int)' ');			}			while (*s1)				Charput((int)*s1++);			Charput((int)'\n');			Padfrom = (Padfrom == PADLEFT) ? PADRIGHT : PADLEFT;		}	    /*	     * End of line housekeeping	     */		Nxtln++;		Outll = -1;		Outlx = 0;		Padx = 0;		Tind = 0;		Nospmode = 0;		if (vsp == 0 && len == DOBREAK		&&  strcmp((char *)word, "need") == 0) {		    /*		     * Break caused by "need" - satisfy it.		     */			while (Nxtln < (Pglen + 1 - Botmarg)) {				Charput((int)'\n');				Nxtln++;			}		}		if (Nxtln >= (Pglen + 1 - Botmarg)) {	    /*	     * Footer required	     */			for (i = (Botmarg - 1)/2; i > 0; i--) {				Charput((int)'\n');				Nxtln++;			}			i = LenprtHF(Ftl, Thispg, 0) + LenprtHF(Ftc, Thispg, 0)			  + LenprtHF(Ftr, Thispg, 0) + 2;			j = (LL - i - Pgoff) / 2 + 1;			n = LL - Pgoff - i - j + 2;			for (k = 0; k < Pgoff; k++)				Charput((int)' ');			if (Ftl)				LenprtHF(Ftl, Thispg, 1);			while (j--)				Charput((int)' ');			if (Ftc)				LenprtHF(Ftc, Thispg, 1);			while (n--)				Charput((int)' ');			if (Ftr)				LenprtHF(Ftr, Thispg, 1);			Charput((int)'\n');			Nxtln++;		/*		 * The last blank line on the page is suppressed to assist		 * printers that can't look ahead to the following FF.		 */			while (Nxtln < Pglen) {				Charput((int)'\n');				Nxtln++;			}			Nxtln = 1;			Thispg++;			Nospmode = 1;			Padfrom = PADRIGHT;		}	    /*	     * Initiate any extra vertical spacing.	     */		if (++vsp < Vspace)			goto print_line;	    /*	     * Save any input word that might have forced output.	     */		if (len >= 0) {			(void) strcpy((char *)Outln, (char *)word);			Outll = len;			Outlx = wl;			Padx = 0;		}	}    /*     * A break causes padding reversal.     */	if (len == DOBREAK)		Padfrom = PADRIGHT;	if (len >= 0 || strcmp((char *)word, "nohyphen") == 0) {    /*     * Reset continuation and hyphenation.     */		if (Contlen != 1 || Cont[0] != ' ') {			Free(&Cont);			Cont = Newstr((unsigned char *)" ");			Contlen = 1;		}		if (Eollen > 0) {			Free(&Eol);			Eollen = 0;		}		return;	}    /*     * Now post-process any special commands.     */	if (len == MESSAGE) {		Error3(len, (char *)word, (char *)sarg, narg, NULL);		return;	}	switch (*word) {	case 'b':				/* both */	    /*	     * Adjust on both margins.	     */		Adj = BOTHADJ;		return;	case 'c':				/* center */		return;	case 'e':				/* errsto */	    /*	     * "errsto" comes from awf.	     */		return;	case 'f':				/* flush and fph */		if (word[1] == 'l')			return;		else if (word[1] == 'p') {	    /*	     * First page header status	     */			Fph = narg;			return;		}		break;	case 'g':				/* gap */	    /*	     * Increase word gap.  (Space is not paddable.)	     */		if (Outll >= 0) {			if ((Outlx + narg - 1) >= MAXOLL)				goto line_too_big;			for (i = 0; i < (narg - 1); i++) {				Outln[Outlx++] = ' ';				Outll++;			}		}		return;	case 'h':				/* hyphen */	    /*	     * Set discretionary hyphen.	     */		Free(&Cont);		Contlen = 0;		Free(&Eol);		Eol = (sarg != NULL) ? Newstr(sarg) : NULL;		Eollen = narg;		return;	case 'i':				/* indent */	    /*	     * Set indentation.	     */		Ind = narg;		return;	case 'l':				/* left or linelen */		if (word[1] == 'e') {	    /*	     * Adjust on left margin.	     */			Adj = LEFTADJ;			return;		} else if (word[1] == 'i') {	    /*	     * Set line length.	     */			LL = narg;			return;		}		break;	case 'n':				/* need or nospace */		if (word[1] == 'e')			return;			/* need */		else if (word[1] == 'o') {	    /*	     * Set no space mode.	     */			Nospmode = 1;			return;		}		break;	case 'p':				/* pagelen or pageoffset */		if (strncmp((char *)&word[1], "age", 3) != 0)			break;		if (word[4] == 'l') {	    /*	     * Set page length.	     */			Pglen = narg;			return;		} else if (word[4] == 'o') {	    /*	     * Set page offset.	     */			Pgoff = narg;			return;		}		break;	case 's':				/* space */		if (sp) {		/*		 * Restore values after NOBREAK spacing ("^'sp").		 */			Outlx = sp_Outlx;			Outln[0] = sp_Outln;			Padx = sp_Padx;			Outll = sp_Outll;			Tind = sp_Tind;			return;		}		if (Nospmode == 0) {			if (len == NOBREAK) {					/*			 * Set up for NOBREAK spacing.			 */				sp_Outlx = Outlx;				sp_Outln = Outln[0];				sp_Padx = Padx;				sp_Outll = Outll;				sp_Tind = Tind;				vsp = Vspace + 1;				sp = 1;			}		/*		 * Generate a blank line.		 */			Outlx = 0;			Outln[0] = '\0';			Padx = 0;			Outll = LL - 1;			if (sp)				goto print_line;		}		return;	case 't':				/* tabto, tempindent, or						 * toindent */		if (word[1] == 'a') {	    /*	     * Move to TAB stop.	     */			if (Outll < 0)				Outll = 0;			if ((n = narg - Outll) > 0) {				if ((Outlx + n) >= MAXOLL)					goto line_too_big;				Outll += n;				for (i = n; i > 0; i--)					Outln[Outlx++] = ' ';				Free(&Cont);				Contlen = 0;				Padx = 0;			}			return;		} else if (word[1] == 'e') {	    /*	     * Set temporary indentation.	     */			if (*sarg == '\0' && narg >= 0)				Tind = narg - Ind;			else				Tind = ((Ind + narg) >= 0) ? narg : -Ind;			return;		} else if (word[1] == 'o')			return;				/* toindent */		break;	case 'u':					/* userhyphen */	    /*	     * Set line length.	     */		Free(&Cont);		Free(&Eol);		Contlen = Eollen = narg;		Cont = (sarg == NULL) ? NULL : Newstr(sarg);		Eol = (sarg == NULL) ? NULL : Newstr(sarg);		return;	case 'v':					/* vspace */	    /*	     * Set vertical spacing.	     */		Vspace = (narg == 0) ? 1 : narg;		return;	case 'y':					/* yesspace */	    /*	     * Set space mode.	     */		Nospmode = 0;		return;	}				/* end of switch(*word) */    /*     * Locate header and footer defintions.     */	if (regexec(Pat[14].pat, word)) {		if (strcmp((char *)word, "LH") == 0) {		    /*		     * Left header		     */			Free(&Hdl);			if (sarg != NULL)				Hdl = Newstr(sarg);			return;		}		if (strcmp((char *)word, "CH") == 0) {		    /*		     * Center header		     */			Free(&Hdc);			if (sarg != NULL)				Hdc = Newstr(sarg);			return;		}		if (strcmp((char *)word, "RH") == 0) {		    /*		     * Right header		     */			Free(&Hdr);			if (sarg != NULL)				Hdr = Newstr(sarg);			return;		}		if (strcmp((char *)word, "LF") == 0) {		    /*		     * Left footer		     */			Free(&Ftl);			if (sarg != NULL)				Ftl = Newstr(sarg);			return;		}		if (strcmp((char *)word, "CF") == 0) {		    /*		     * Center footer		     */			Free(&Ftc);			if (sarg != NULL)				Ftc = Newstr(sarg);			return;		}		if (strcmp((char *)word, "RF") == 0) {		    /*		     * Right footer		     */			Free(&Ftr);			if (sarg != NULL)				Ftr = Newstr(sarg);			return;		}	}    /*     * Error on unknown arguments     */	Error3(len, (char *)word, (char *)sarg, narg, "unknown request");}

⌨️ 快捷键说明

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