📄 mined1.c
字号:
} count += (long) length_of(line->text); } if (count > 0L && flush_buffer(fd) == ERRORS) count = -1L; (void) close(fd); if (count == -1L) return ERRORS; modified = FALSE; rpipe = FALSE; /* File name is now assigned *//* Display how many chars (and lines) were written */ fstatus("Wrote", count); return FINE;}/* Call WT and discard value returned. */void XWT(){ (void) WT();}/* * Call an interactive shell. */void SH(){ register int w; int pid, status; char *shell; if ((shell = getenv("SHELL")) == NIL_PTR) shell = "/bin/sh"; switch (pid = fork()) { case -1: /* Error */ error("Cannot fork.", NIL_PTR); return; case 0: /* This is the child */ set_cursor(0, ymax); putchar('\n'); flush(); raw_mode(OFF); if (rpipe) { /* Fix stdin */ close (0); if (open("/dev/tty", 0) < 0) exit (126); } execl(shell, shell, (char *) 0); exit(127); /* Exit with 127 */ default : /* This is the parent */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); do { w = wait(&status); } while (w != -1 && w != pid); } raw_mode(ON); RD(); if ((status >> 8) == 127) /* Child died with 127 */ error("Cannot exec ", shell); else if ((status >> 8) == 126) error("Cannot open /dev/tty as fd #0", NIL_PTR);}/* * Proceed returns the count'th line after `line'. When count is negative * it returns the count'th line before `line'. When the next (previous) * line is the tail (header) indicating EOF (tof) it stops. */LINE *proceed(line, count)register LINE *line;register int count;{ if (count < 0) while (count++ < 0 && line != header) line = line->prev; else while (count-- > 0 && line != tail) line = line->next; return line;}/* * Show concatenation of s1 and s2 on the status line (bottom of screen) * If revfl is TRUE, turn on reverse video on both strings. Set stat_visible * only if bottom_line is visible. */int bottom_line(revfl, s1, s2, inbuf, statfl)FLAG revfl;char *s1, *s2;char *inbuf;FLAG statfl;{ int ret = FINE; char buf[LINE_LEN]; register char *p = buf; *p++ = ' '; if (s1 != NIL_PTR) while (*p = *s1++) p++; if (s2 != NIL_PTR) while (*p = *s2++) p++; *p++ = ' '; *p++ = 0; if (revfl == ON && stat_visible == TRUE) clear_status (); set_cursor(0, ymax); if (revfl == ON) { /* Print rev. start sequence */#ifdef UNIX tputs(SO, 0, _putchar);#else string_print(rev_video);#endif /* UNIX */ stat_visible = TRUE; } else /* Used as clear_status() */ stat_visible = FALSE; string_print(buf); if (inbuf != NIL_PTR) ret = input(inbuf, statfl); /* Print normal video */#ifdef UNIX tputs(SE, 0, _putchar); tputs(CE, 0, _putchar);#else string_print(normal_video); string_print(blank_line); /* Clear the rest of the line */#endif /* UNIX */ if (inbuf != NIL_PTR) set_cursor(0, ymax); else set_cursor(x, y); /* Set cursor back to old position */ flush(); /* Perform the actual write */ if (ret != FINE) clear_status(); return ret;}/* * Count_chars() count the number of chars that the line would occupy on the * screen. Counting starts at the real x-coordinate of the line. */int count_chars(line)LINE *line;{ register int cnt = get_shift(line->shift_count) * -SHIFT_SIZE; register char *textp = line->text;/* Find begin of line on screen */ while (cnt < 0) { if (is_tab(*textp++)) cnt = tab(cnt); else cnt++; }/* Count number of chars left */ cnt = 0; while (*textp != '\n') { if (is_tab(*textp++)) cnt = tab(cnt); else cnt++; } return cnt;}/* * Move to coordinates nx, ny at screen. The caller must check that scrolling * is not needed. * If new_x is lower than 0 or higher than XBREAK, move_to() will check if * the line can be shifted. If it can it sets(or resets) the shift_count field * of the current line accordingly. * Move also sets cur_text to the right char. * If we're moving to the same x coordinate, try to move the the x-coordinate * used on the other previous call. */void move(new_x, new_address, new_y)register int new_x;int new_y;char *new_address;{ register LINE *line = cur_line; /* For building new cur_line */ int shift = 0; /* How many shifts to make */ static int rel_x = 0; /* Remember relative x position */ int tx = x;/* Check for illegal values */ if (new_y < 0 || new_y > last_y) return;/* Adjust y-coordinate and cur_line */ if (new_y < y) while (y != new_y) { y--; line = line->prev; } else while (y != new_y) { y++; line = line->next; }/* Set or unset relative x-coordinate */ if (new_address == NIL_PTR) { new_address = find_address(line, (new_x == x) ? rel_x : new_x , &tx); if (new_x != x) rel_x = tx; new_x = tx; } else rel_x = new_x = find_x(line, new_address);/* Adjust shift_count if new_x lower than 0 or higher than XBREAK */ if (new_x < 0 || new_x >= XBREAK) { if (new_x > XBREAK || (new_x == XBREAK && *new_address != '\n')) shift = (new_x - XBREAK) / SHIFT_SIZE + 1; else { shift = new_x / SHIFT_SIZE; if (new_x % SHIFT_SIZE) shift--; } if (shift != 0) { line->shift_count += shift; new_x = find_x(line, new_address); set_cursor(0, y); line_print(line); rel_x = new_x; } }/* Assign and position cursor */ x = new_x; cur_text = new_address; cur_line = line; set_cursor(x, y);}/* * Find_x() returns the x coordinate belonging to address. * (Tabs are expanded). */int find_x(line, address)LINE *line;char *address;{ register char *textp = line->text; register int nx = get_shift(line->shift_count) * -SHIFT_SIZE; while (textp != address && *textp != '\0') { if (is_tab(*textp++)) /* Expand tabs */ nx = tab(nx); else nx++; } return nx;}/* * Find_address() returns the pointer in the line with offset x_coord. * (Tabs are expanded). */char *find_address(line, x_coord, old_x)LINE *line;int x_coord;int *old_x;{ register char *textp = line->text; register int tx = get_shift(line->shift_count) * -SHIFT_SIZE; while (tx < x_coord && *textp != '\n') { if (is_tab(*textp)) { if (*old_x - x_coord == 1 && tab(tx) > x_coord) break; /* Moving left over tab */ else tx = tab(tx); } else tx++; textp++; } *old_x = tx; return textp;}/* * Length_of() returns the number of characters int the string `string' * excluding the '\0'. */int length_of(string)register char *string;{ register int count = 0; if (string != NIL_PTR) { while (*string++ != '\0') count++; } return count;}/* * Copy_string() copies the string `from' into the string `to'. `To' must be * long enough to hold `from'. */void copy_string(to, from)register char *to;register char *from;{ while (*to++ = *from++) ;}/* * Reset assigns bot_line, top_line and cur_line according to `head_line' * which must be the first line of the screen, and an y-coordinate, * which will be the current y-coordinate (if it isn't larger than last_y) */void reset(head_line, screen_y)LINE *head_line;int screen_y;{ register LINE *line; top_line = line = head_line;/* Search for bot_line (might be last line in file) */ for (last_y = 0; last_y < nlines - 1 && last_y < screenmax && line->next != tail; last_y++) line = line->next; bot_line = line; y = (screen_y > last_y) ? last_y : screen_y;/* Set cur_line according to the new y value */ cur_line = proceed(top_line, y);}/* * Set cursor at coordinates x, y. */void set_cursor(nx, ny)int nx, ny;{#ifdef UNIX extern char *tgoto(); tputs(tgoto(CM, nx, ny), 0, _putchar);#else char text_buffer[10]; build_string(text_buffer, pos_string, ny+1, nx+1); string_print(text_buffer);#endif /* UNIX */}/* * Routine to open terminal when mined is used in a pipeline. */void open_device(){ if ((input_fd = open("/dev/tty", 0)) < 0) panic("Cannot open /dev/tty for read");}/* * Getchar() reads one character from the terminal. The character must be * masked with 0377 to avoid sign extension. */int getchar(){#ifdef UNIX return (_getchar() & 0377);#else char c; if (read(input_fd, &c, 1) != 1 && quit == FALSE) panic("Can't read one char from fd #0"); return c & 0377;#endif /* UNIX */}/* * Display() shows count lines on the terminal starting at the given * coordinates. When the tail of the list is encountered it will fill the * rest of the screen with blank_line's. * When count is negative, a backwards print from `line' will be done. */void display(x_coord, y_coord, line, count)int x_coord, y_coord;register LINE *line;register int count;{ set_cursor(x_coord, y_coord);/* Find new startline if count is negative */ if (count < 0) { line = proceed(line, count); count = -count; }/* Print the lines */ while (line != tail && count-- >= 0) { line_print(line); line = line->next; }/* Print the blank lines (if any) */ if (loading == FALSE) { while (count-- >= 0) {#ifdef UNIX tputs(CE, 0, _putchar);#else string_print(blank_line);#endif /* UNIX */ putchar('\n'); } }}/* * Write_char does a buffered output. */int write_char(fd, c)int fd;char c;{ screen [out_count++] = c; if (out_count == SCREEN_SIZE) /* Flush on SCREEN_SIZE chars */ return flush_buffer(fd); return FINE;}/* * Writeline writes the given string on the given filedescriptor. */int writeline(fd, text)register int fd;register char *text;{ while(*text) if (write_char(fd, *text++) == ERRORS) return ERRORS; return FINE;}/* * Put_line print the given line on the standard output. If offset is not zero * printing will start at that x-coordinate. If the FLAG clear_line is TRUE, * then (screen) line will be cleared when the end of the line has been * reached. */void put_line(line, offset, clear_line)LINE *line; /* Line to print */int offset; /* Offset to start */FLAG clear_line; /* Clear to eoln if TRUE */{ register char *textp = line->text; register int count = get_shift(line->shift_count) * -SHIFT_SIZE; int tab_count; /* Used in tab expansion *//* Skip all chars as indicated by the offset and the shift_count field */ while (count < offset) { if (is_tab(*textp++)) count = tab(count); else count++; } while (*textp != '\n' && count < XBREAK) { if (is_tab(*textp)) { /* Expand tabs to spaces */ tab_count = tab(count); while (count < XBREAK && count < tab_count) { count++; putchar(' '); } textp++; } else { if (*textp >= '\01' && *textp <= '\037') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -