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

📄 page.c

📁 reads a set of C-source files and generates a two-column listing of those sources
💻 C
字号:
/* page.c -- functions and variables to compose and output pages *//*    This is part of cdg - a C-source Documentation Generator.    Copyright (C) 1995, 1996 Peter Knoppers.    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include "cdg.h"#define ESC	'\033'/* * Printer specific command strings. * Can be overridden with -Dxxx=yyy on the compiler command line (if you * figure out how to escape all those nasty escapes...) * * All printer specific stuff is contained in this file. * * There are three sets of codes: * PostScript * HP LaserJet * HP DeskJet 500 * The (default) codes are good for my HP deskjet 500 printer. * * The output is for A4 sized paper, PostScript output can also be * generated for US Letter. *//* * The PRINTERINITSTRING sets up the printer in landscape mode and prepares * things so that the next call to PRINTERSTARTLINE will position the "cursor" * on the first position of the first line of the page. */#ifndef PRINTERINITSTRING#ifdef POSTSCRIPT#ifdef USLETTER#define PRINTERINITSTRING	printf ("%%!PS-Adobe-3.0\n\%%%%Pages: (atend)\ngsave\n\/R {/Courier      findfont 7 scalefont setfont} def R \n\/B {/Courier-Bold findfont 7 scalefont setfont} def\n\/L {C 13 grestore moveto gsave 90 rotate C 9 add /C exch def} def\n\statusdict /setduplexmode known {statusdict begin true setduplexmode end} if\n\gsave\n%%%%Page: 1 1\n/C 28 def\n")#else#define PRINTERINITSTRING	printf ("%%!PS-Adobe-3.0\n\%%%%Pages: (atend)\ngsave\n\/R {/Courier      findfont 7 scalefont setfont} def R \n\/B {/Courier-Bold findfont 7 scalefont setfont} def\n\/L {C 44 grestore moveto gsave 90 rotate C 9 add /C exch def} def\n\statusdict /setduplexmode known {statusdict begin true setduplexmode end} if\n\gsave\n%%%%Page: 1 1\n/C 28 def\n")#endif#else#ifdef LASERJET#define PRINTERINITSTRING	printf (\"%c&l1O%c&l26A%c(s16H%c&l8D%c(s9V%c&l1S%c&l0L%c&a5L%c&l2E%c&a0R", \ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC)#else#define PRINTERINITSTRING	printf (\"%c&l1O%c&l26A%c(s16H%c&l8D%c&l1E%c&l60F%c(s9V", \ESC, ESC, ESC, ESC, ESC, ESC, ESC)#endif#endif#endif/* * The PRINTERSTARTLINE code positions the cursor on position 1 of the NEXT * line. */ #ifndef PRINTERSTARTLINE#ifdef POSTSCRIPT#define PRINTERSTARTLINE	printf ("L (")#else#ifdef LASERJET#define PRINTERSTARTLINE	/* No action required */#else#define PRINTERSTARTLINE	/* No action required */#endif#endif#endif/* * The PRINTERENDLINE code terminates the current line. */#ifndef PRINTERENDLINE#ifdef POSTSCRIPT#define PRINTERENDLINE		printf (") show\n")#else#ifdef LASERJET#define PRINTERENDLINE		printf ("\r\n")#else#define PRINTERENDLINE		printf ("\r\n")#endif#endif#endif/* * The PRINTERHIGHLIGHTON code set the printer into bold-face (or some other * highlighting) mode. * For some printers highlighting is done on a per-character basis. In these * cases the PRINTERHIGHLIGHTON and PRINTERHIGHLIGHTOFF macros may be empty. * It is guaranteed that PRINTERHIGHLIGHTON and PRINTERHIGHLIGHTOFF are called * in "pairs", and highlighting is never active accross lines. */#ifndef PRINTERHIGHLIGHTON#ifdef POSTSCRIPT#define PRINTERHIGHLIGHTON	printf (") show\nB (")#else#ifdef LASERJET#define PRINTERHIGHLIGHTON	/* No action required */#else#define PRINTERHIGHLIGHTON	/* No action required */#endif#endif#endif/* * The PRINTERHIGHLIGHTOFF code resets the printer after it has been put into * bold-face (or some other highlighting) mode. */#ifndef PRINTERHIGHLIGHTOFF#ifdef POSTSCRIPT#define PRINTERHIGHLIGHTOFF	printf (") show\nR (")#else#ifdef LASERJET#define PRINTERHIGHLIGHTOFF	/* No action required */#else#define PRINTERHIGHLIGHTOFF	/* No action required */#endif#endif#endif/* * The PRINTERHIGHLIGHTOUTCHAR code is a macro that outputs one char in * highlight-mode (the PRINTERHIGHLIGHTON code has been called before this * macro). * For printers that have a highlight-start and a highlight-end code, this * macro often can be identical to PRINTEROUTCHAR. */#ifndef PRINTERHIGHLIGHTOUTCHAR#ifdef POSTSCRIPT#define PRINTERHIGHLIGHTOUTCHAR(c)	PRINTEROUTCHAR(c)#else#ifdef LASERJET/* These stupid HP laserprinters don't do boldface with scaled characters * (at least not in landscape mode). * My fix is to output the char twice at a slightly different position. * This makes the output file rather long... * The distance over which the character is shifted is in steps of 1/120 inch. * Luckily this even works with fractions of this step (here 0.7). * The space in this escape sequence causes the micro-shift. */#define PRINTERHIGHLIGHTOUTCHAR(c)	printf (\"%c&f0S%c&k0.7H %c(s16H%c%c&f1S%c", ESC, ESC, ESC, c, ESC, c)#else/* * Highlighing by overstriking. This is a nondocumented feature of the * HP DeskJet 500 printer which also refuses to do boldface when controlled * according to the HP documentation... */#define PRINTERHIGHLIGHTOUTCHAR(c)	PRINTEROUTCHAR(c), \PRINTEROUTCHAR('\b'), PRINTEROUTCHAR(c)#endif#endif#endif/* * The PRINTEROUTCHAR macro outputs one character while the printer is in * normal output mode. */#ifndef PRINTEROUTCHAR#ifdef POSTSCRIPT/* * In PostScript some printable characters must be escaped. Tabs have already * been expanded, so these can not cause problems here. */#define PRINTEROUTCHAR(c)	if (strchr ("()\\", c))\{fputc ('\\', stdout); fputc (c, stdout);} else fputc (c, stdout)#else#ifdef LASERJET#define PRINTEROUTCHAR(c)	fputc (c, stdout)#else#define PRINTEROUTCHAR(c)	fputc (c, stdout)#endif#endif#endif/* * The PRINTERNEXTPAGESTRING macro ejects the current page and positions the * the "cursor" on position 1 of the top-most line of the next page. * The argument is the number of the next page. * This number does _not_ correspond to the page number printed on most pages. * (The difference is the number of pages occupied by the Table Of Contents.) * * On all pages all 60 lines are always output. */#ifndef PRINTERNEXTPAGESTRING#ifdef POSTSCRIPT#define PRINTERNEXTPAGESTRING(n)	printf (\"showpage\n%%%%Page: %d %d\n/C 28 def\n", n, n)#else#ifdef LASERJET#define PRINTERNEXTPAGESTRING(n)	printf ("\f")#else#define PRINTERNEXTPAGESTRING(n)	/* No action required */#endif#endif#endif/* * The PRINTERRESETSTRING macro ejects the current page and resets the printer * to power-on state. * The argument is the total page count. */#ifndef PRINTERRESETSTRING#ifdef POSTSCRIPT#define PRINTERRESETSTRING(n)	printf (\"showpage\n%%%%Trailer\ngrestore grestore\n%%%%Pages: %d\n", n)#else#ifdef LASERJET#define PRINTERRESETSTRING(n)	printf ("%cE", ESC)#else#define PRINTERRESETSTRING(n)	printf ("%cE", ESC)#endif#endif#endif#ifndef PRINTERSETTING#ifdef POSTSCRIPT#define PRINTERSETTING		"PostScript"#else#ifdef LASERJET#define PRINTERSETTING		"HP-LaserJet"#else#define PRINTERSETTING		"HP-DeskJet"#endif#endif#endifchar printertype[] = PRINTERSETTING;/* * trim:		Remove trailing newline(s), spaces and tabs from a *			string. This function should've been part of stdlib... * arguments: * char * l:		Pointer to string that is to be trimmed. * returns:		Nothing. */void trim (char * l){    char * cp;    for (cp = &l[strlen (l) - 1]; cp >= l; cp--)	if ((*cp == '\n') || (*cp == '\r') || isspace (*cp))	    *cp = '\0';	else	    break;}/* * The functions update_insertednewlines and copyout deal with writing the * source listings to a temporary file. *//* * Inserted newlines produced _during_ copyout of a token are added to the * lineno of all subsequent tokens (but not the the lineno of the current * token). * If a token is split over several lines, the line on which the token starts * must be used in the cross reference list. */static int insertednewlines = 0;	/* incremented in copyout() */int totalinsertednewlines = 0;		/* global visibility is intended */int column = 0;				/* column in copyout file */int outputlineno = 0;			/* line number in copyout file *//* * update_insertednewlines: Add the number of newlines inserted by copyout to *			totalinsertednewlines and reset insertednewlines. *			This function must be called _before_ a new token is *			copied out so totalinsertednewlines reflects the total *			number of newlines inserted _before_ the new token. * arguments:		None. * returns:		Nothing. */void update_insertednewlines (void){    totalinsertednewlines += insertednewlines;    insertednewlines = 0;}/* * copyout:		Copy one input character to the output listing, adding *			linenumbers and breaking up lines as necessary. When a *			line is broken, a \ is put in position MAXCOLUMN. *			The variable "insertednewlines" is incremented each *			time a line is broken. * arguments: * char c:		Character to output. * returns:		Nothing. */void copyout (char c){    if (column == 0)	fprintf (listfile, "%6d  ", outputlineno + 1);/* humans count from 1 */    if (c == '\n')    {	column = 0;	outputlineno++;    }    else if (c == '\t')    {					/* expand tab */	do	{	    column++;	    fputc (' ', listfile);	}	while (((column % 8) != 0) && (column < MAXCOLUMN));	/* Is this correct when MAXCOLUMN % 8 != 0 ?? */	return;    }    else	column++;    if (column > MAXCOLUMN)    {					/* break up line */	insertednewlines++;	fputc ('\\', listfile);	copyout ('\n');	copyout (c);			/* must output line number first */    }    else	fputc (c, listfile);}/* * The remainder of this file contains functions and variables that are used * to compose and write the multi-column output pages. */static int pages = 0;	/* count output pages (!= pagenumber) *//* * resetprinter:	Output the printer reset string. This string should *			reset the printer to power-on state. (Cancelling *			landscape mode, scaled characters, etc. * Arguments:		None. * returns:		Nothing. */static void resetprinter (void){    PRINTERRESETSTRING (pages);}#define COLSTART	(currentcol * (COLWIDTH + COLSEP))int pageno = 0;				/* if 0, no page number on page */					/* else auto-incrementing pageno */static char page[MAXPAGELINE][MAXPAGECOL + MINCOLSEP + 2];/* construct page */static int currentline;static int currentcol;int cols;				/* number of columns */char headerline [MAXPAGECOL + 1];	/* header for each column *//* * flushpage:		Write out the contents of the constructed page. *			If the page is empty, no output is generated. * Arguments: * int newcolcount:	New value for cols per page. * returns:		Nothing. * remark:		If newcolcount == 0, the printer-reset string is *			output after the page. */void flushpage (int newcolcount){    int line;    while ((currentline > 0) && (currentline < LINESPERCOLUMN))	addline ("");		/* will eventually recurse to flushpage */    if ((currentcol == 0) && (currentline == 0))    {				/* page is (now) empty */	if (newcolcount == 0)	    resetprinter ();	/* Done. */	cols = newcolcount;	return;    }    if (pages++ == 0)			/* initial page */    {	PRINTERINITSTRING;    }    else				/* subsequent page */    {	/* These braces ({, }) prevent problems in case the macro is empty */	PRINTERNEXTPAGESTRING (pages);    }    for (line = 0; line < MAXPAGELINE; line++)    {	/*	 * Output one line from the buffer, switching highlighting on and	 * off as indicated.	 *	 * Highlighting can only be switched on for whole words.	 */	char * cp;	int highlightison = 0;	trim (page[line]);	if ((line == COLUMNHEADLINE) && (pageno > 0))	    sprintf (page[line] + strlen (page[line]),		    "%*sPage %4d", MAXPAGECOL - 9 - (int) strlen (page[line]),		    "", pageno++);	PRINTERSTARTLINE;	for (cp = page[line]; *cp; cp++)	{	    if (*cp == HIGHLIGHTWORD)	    {	        PRINTEROUTCHAR (' ');		highlightison = 1;		PRINTERHIGHLIGHTON;		continue;	    }	    else if (*cp == ' ')	    {		if (highlightison != 0)		{			/* Don't delete these braces! */		    PRINTERHIGHLIGHTOFF;		}		highlightison = 0;	    }	    if (highlightison != 0)	        PRINTERHIGHLIGHTOUTCHAR (*cp);	    else	        PRINTEROUTCHAR (*cp);	}	if (highlightison != 0)	{				/* Don't delete these braces! */	    PRINTERHIGHLIGHTOFF;	}	highlightison = 0;	PRINTERENDLINE;	if (line < LINESPERCOLUMN + BODYHEADLINE)	    page[line][0] = '\0';	/* don't erase the footer */    }    currentcol = 0;    currentline = 0;    if (newcolcount == 0)	resetprinter ();    cols = newcolcount;}/* * addline:		Add one line to the "body" of the page under *			construction. If the page is full, call flushpage to *			output it. * Arguments: * char * l:		Character pointer to string that is to be added. * returns:		Nothing. */void addline (char * l){    sprintf (page[BODYHEADLINE + currentline++] + COLSTART, "%-*.*s",	    COLWIDTH + COLSEP, COLWIDTH + COLSEP, l);/* add and padd the line */    if (currentline >= LINESPERCOLUMN)	/* currentcol is full */    {	sprintf(page[COLUMNHEADLINE] + COLSTART, "%-*.*s",		COLWIDTH + COLSEP, COLWIDTH + COLSEP, headerline);	if (++currentcol >= cols)	/* page is full */	    flushpage(cols);	currentline = 0;    }}/* * addlinehard:		Copy a string to a specified line in the page under *			construction. * Arguments: * int where:		Line number in the page. * char * l:		Character pointer to string that is to be put at the *			specified line.. * returns:		Nothing. */void addlinehard (int where, char * l){    strcpy (page[where], l);}

⌨️ 快捷键说明

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