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

📄 maha.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	    "%s: pages should be given in non-descending order.\n",	    myname);    }}process_arg(){    register char ch;    register int  temp;    register char *p1;    register char *p2;    if (argv[0][0] == '-')    {	if ((ch = argv[0][1]) > '0' && ch <= '9')	{	    /* this is a column count specifier */	    columns = ch - '0';	}	else switch(ch)	{	    case '\0':		/* not an option */		return(No);	    case 'b':		banner = next_arg();		break;	    case 'c':		temp = atoi(copies = next_arg());		if (temp < 1)		{		    fprintf(stderr,			"%s: bogus number of copies; you only get one!\n",			myname);			copies = "1";		}		break;	    case 'f':		bodyfont_name = next_arg();		break;	    case 'F':		headfont_name = next_arg();		break;	    case 'H':			/* replace header */		tflg = No;		header = next_arg();		break;	    case 'h':			/* append to header */		tflg = No;		p1 = next_arg();		p2 = allocate(strlen(header) + strlen(p1) + 1);		(void) strcpy(p2, header);		(void) strcat(p2, "      ");		(void) strcat(p2, p1);		header = p2;		break;	    case 'l':		tflg = lflg = Yes;		break;	    case 'n':		name = next_arg();		break;	    case 'o':		output = next_arg();		send_to_printer = No;		break;	    case 'P':		printer = next_arg();		break;	    case 'r':		rflg = Yes;		break;	    case 'R':		rflg = No;		break;	    case 's':		pages = next_arg();		break;	    case 't':		tflg = Yes;		break;	    default:		fprintf(stderr, "%s: unknown option '%c'\n", myname, ch);	}	return(Yes);    }    else    {	return(No);    }}char *next_arg(){    if (argv[0][2] == '\0')    {	if (--argc > 0)	{	    return((++argv)[0]);	}	else	{	    argv++;	    return(NULL);	}    }    else    {	return(&(argv[0][2]));    }}/* *  establish_font(name, font) - break apart the parts of the string "name" *				 and fill in the structure pointed to by *				 "font".  Also, verify that the font requested *				 actually exists.  This routine also *				 understands universal font names. */establish_font(name, font)char *name;struct font *font;{    register char *unamep;    register char *ptr;    char *slashp;    register int size;    if (name[0] != '/')    {	/* not a universal name -- put the default on the front */	font->ft_universal_name = unamep =		allocate(strlen(Default_universal_prefix) +			 strlen(name) + 1);	(void) strcpy(unamep, Default_universal_prefix);	(void) strcat(unamep, name);    }    else    {	/* already is a universal name -- just allocate space for it */	font->ft_universal_name = unamep = allocate(strlen(name));	/* copy in the whole name, without the leading slash */	(void) strcpy(unamep, name + 1);    }    /* strip size off the end, if it is there */    if ((slashp = ptr = rindex(unamep, '/')) != NULL)    {	register char ch;	size = 0;	while ((ch = *++ptr) != '\0')	{	    if (ch < '0' || ch > '9')	    {		/* last element is not a number -- no point size */		size = 0;		break;	    }	    /* shift this digit in */	    size *= 10;	    size += (ch - '0');	}	/* if no point size, use default */	if (size == 0)	{	    font->ft_size = 10;	}	else	{	    font->ft_size = size;	    *slashp = '\0';	}    }    /* set pointer to last element */    if ((ptr = rindex(unamep, '/')) != NULL)    {	font->ft_leaf_name = ptr + 1;    }    else    {	font->ft_leaf_name = font->ft_universal_name;    }}do_file(file)FILE *file;{    char *src;    char *dest;    char input_line[Line_size];    char line_buffer[Line_size];    char ch;    int current_line;    int lines_on_page;    int length;    int column;    #ifndef vax11c    /* fstat it to get information displayed in the header */    if (fstat(fileno(file), &file_stat) == -1)    {	system_error("fstat botched");	return;    }#endif    /* reset essentials */    page_number = 0;    line_number = 1;    lines_on_page = 0;    curr_page_select = page_select;    if (pages != NULL)    {    	page_low  = page_select[0];    	page_high = page_select[1];    }    current_line = top_margin;    /*     *  Strangeness:  page_number is incremented by page_start and     *  line_number is incremented in the "while(fgets..." loop.     */    /* start the first page */    page_start();    /*     *  More strangeness:  we had to set line_number to 1 to trick     *  page_start into reporting the right line count in the header.  Now     *  we reset it to 0 before entering the read/print loop.     */    line_number = 0;    while (fgets(input_line, Line_size, file) != NULL)    {	/* new line */	line_number++;	/* remember the length */	length = strlen(input_line);	/* nuke any trailing newline */	if (input_line[length - 1] == '\n')	{	    input_line[--length] = '\0';	}	if (lflg ? lines_on_page >= 66 : current_line < bottom_margin)	{	    /* start a new page */	    page_end(No);	    page_start();	    lines_on_page = 0;	    /* remember, y goes backwards */	    current_line = top_margin;	}	/* make sure that the line actually contains something */	if (input_line[0] != '\0')	{	    /* set x and y for the beginning of the line */	    Setxy((double)left_margin, (double)current_line);	    /* copy from input_line to line_buffer making any necessary	       changes along the way */	    column = 0;	    src = input_line;	    dest = line_buffer;	    while ((ch = *src) != '\0')	    {		switch(ch)		{		    case '\r':		/* carriage return */			*dest = '\0';			if (line_buffer[0] != '\0')			{			    ShowString(line_buffer);			}			Setxy((double)left_margin, (double)current_line);			dest= line_buffer;			break;		    case '\f':		/* new page after this line */			current_line = bottom_margin;			lines_on_page = 66;			break;		    case '\t':		/* tab expansion */			do			{			    *dest++ = ' ';			    column++;			} while (column % tab_amount != 0);			break;		    case '$':			*dest++ = '\244';			column++;			break;		    case '-':			if (special_font == Font_Terminal)			{			    /* heavy hackery here */			    *dest = '\0';			    ShowString(line_buffer);			    Setyrel(-20.);			    ShowString("\305");			    Setyrel(20.);			    dest = line_buffer;			    column++;			    break;			}			/* else fall thru ... */		    default:			*dest++ = ch;			column++;		}		src++;	    }	    *dest = '\0';	    if (line_buffer[0] != '\0')	    {		ShowString(line_buffer);	    }	}	/* advance the line counters */	current_line -= line_spacing;	lines_on_page++;    }    /* wrap up the file */    page_end(Yes);}/* *  page handling:  a distinction is made between virtual pages and actual *  pages.  A virtual page is one series of lines from the file that appears *  vertically on the printed page.  The actual page is the page as the *  printer prints it (a printed page, if you will).  There may be several *  virtual pages on one actual page.  The page_start and page_end routines *  that follow start and terminate virtual pages.  The mapping between *  virtual and actual pages is a function of the options specified by the *  user.  If the user requests two column output then there will be two *  virtual pages for every actual page.  These pages will sit side-by-side on *  the actual page.  The mapping is accomplished by changing the variables *  left_margin and right_margin.  "page_start" also handles printing of the *  page header, since there is only one of these on every actual page. */static int current_column;page_start(){    boolean in_set;#ifdef vax11c    long bintim;#endif    /* reset the column count if starting a new file */    if (line_number == 1)    {	current_column = 0;    }    /* either move the left margin or put out a new page */    if (current_column != 0)    {	left_margin += column_separation;    }    else    {	/* increment page count and reset margin */	page_number++;	left_margin = Orig_x;	/* is it in the page specification set? */	if (page_select == NULL)	{	    /* every page is in the set if there is no specification */	    in_set = Yes;	}	else	{	    if (page_low <= page_number && page_number <= page_high)	    {		in_set = Yes;		ip_select(ipress_file);		if (page_number == page_high)		{		    /* at the top of the current range -- time to move up */		    curr_page_select += 2;		    page_low  = curr_page_select[0];		    page_high = curr_page_select[1];		}	    }	    else	    {		/* not in set -- redirect output to null device */		in_set = No;		ip_select(null_file);	    }	}	if (in_set)	{	    register char *src;	    register char *dst;	    register char ch;	    /* increment total page count */	    pages_printed++;	    /* output stuff for new ip page */	    AppendOp(OP_beginBody);		    /* set the transformation */	    Fget(F_transform);	    AppendOp(OP_concatt);	    /* build the header if we need to print it */	    if (!tflg)	    {		/* move characters from header to real_header */		/* and expand format items along the way.     */		src = header;		dst = real_header;		while ((ch = *src) != '\0')		{		    if (ch == '%')		    {			switch(ch = *++src)			{			    case 'f':		/* file name */				dst = strecpy(dst,					    filename == NULL ? 						"Standard input" :						filename);				break;    			    case 't':		/* mtime */#ifdef vax11c				time(&bintim);				strncpy(dst,ctime(&bintim), 24);				dst += 24;#else				/*				 *  ctime returns a 26 character string that				 *  has a newline and null at the end.				 *  26 - 2 == 24.				 */				if (file_stat.st_mtime != 0)				{				    (void) strncpy(dst,ctime(&file_stat.st_mtime),24);				    dst += 24;				}#endif				break;    			    case 'p':		/* page number */				dst = itoa(dst, page_number);				break;    			    case 'l':		/* line number */				dst = itoa(dst, line_number);				break;    			    case '\0':		/* end of the string */				src--;		/* maintain loop invariant */				break;    			    default:		/* copy the character */				*dst++ = ch;				/* break; */			}		    }		    else		    {			*dst++ = ch;		    }		    src++;		}    		/* terminate the real header */		*dst = '\0';	    		/* display the header */		Setxy((double)(left_margin - Header_to_orig_x),		      (double)(top_margin + Header_to_orig_y));		Setfont(F_headfont);		ShowString(real_header);	    }	}    }    /* select the body font */    Setfont(F_bodyfont);}page_end(eof)int eof;{    if ((current_column = ++current_column % columns) == 0 || eof)    {	AppendOp(OP_endBody);    }}char *strecpy(dest, src)register char *src;register char *dest;{    while (*dest++ = *src++)	;    return(--dest);}char *itoa(buff, val)char *buff;int  val;{    char tbuff[12];	/* will build number here -- max of 10 digits */    register char *ptr = tbuff + 11;    *ptr-- = '\0';    while (val != 0)    {	*ptr-- = (val % 10) + '0';	val /= 10;    }    return(strecpy(buff, ++ptr));}/* *  allocate(space) - allocate "space" bytes with sbrk.  This routine uses a *		      fairly naive algorithm.  It sbrk-s space in Break_size *		      chunks and allocates space from a chunk until a request *		      for more space than is left in the chunk is made.  Then, *		      it allocates a new chunk.  The unused space at the end *		      of the old chunk remains unused.  This does NOT depend *		      on sbrk returning contiguous chunks of memory during the *		      life of the program.  If the request is greater than *		      Break_size, the next multiple of Break_size greater *		      than the request size is chosen. */char *allocate(space)int space;{    static char *hi_water = NULL;    static char *max_alloc = NULL;    register char *ptr;    if (hi_water == NULL || max_alloc + space > hi_water)    {	int alloc_size = (space <= Break_size			  ? Break_size			  : ((space + Break_size-1) / Break_size) * Break_size);	hi_water = sbrk(alloc_size);	if ((int)hi_water == -1)	{	    system_error("out of space");	    exit(1);	}	max_alloc = hi_water + alloc_size - 1;    }    ptr = hi_water;    hi_water += space;    return(ptr);}system_error(message)char *message;{    int saved_errno;    /* value of errno not preserved by fprintf */    saved_errno = errno;    fprintf(stderr, "%s: ", myname);    errno = saved_errno;    perror(message);}#ifdef vax11cchar *rindex(string, c)char *string, c;{	register char *pos;	pos = 0;	do {		if (*string == c)			pos = string;	} while (*string++);	return(pos);}#endif

⌨️ 快捷键说明

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