📄 maha.c
字号:
"%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 + -