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

📄 mined2.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Decrement nlines */  nlines--;  return next_line;}/* * Delete() deletes all the characters (including newlines) between the * startposition and endposition and fixes the screen accordingly. It * returns the number of lines deleted. */void delete(start_line, start_textp, end_line, end_textp)register LINE *start_line;LINE *end_line;char *start_textp, *end_textp;{  register char *textp = start_line->text;  register char *bufp = text_buffer;	/* Storage for new line->text */  LINE *line, *stop;  int line_cnt = 0;			/* Nr of lines deleted */  int count = 0;  int shift = 0;				/* Used in shift calculation */  int nx = x;  modified = TRUE;			/* File has been modified *//* Set up new line. Copy first part of start line until start_position. */  while (textp < start_textp) {  	*bufp++ = *textp++;  	count++;  }/* Check if line doesn't exceed MAX_CHARS */  if (count + length_of(end_textp) >= MAX_CHARS) {  	error("Line too long", NIL_PTR);  	return;  }/* Copy last part of end_line if end_line is not tail */  copy_string(bufp, (end_textp != NIL_PTR) ? end_textp : "\n");/* Delete all lines between start and end_position (including end_line) */  line = start_line->next;  stop = end_line->next;  while (line != stop && line != tail) {  	line = line_delete(line);  	line_cnt++;  }/* Check if last line of file should be deleted */  if (end_textp == NIL_PTR && length_of(start_line->text) == 1 && nlines > 1) {  	start_line = start_line->prev;  	(void) line_delete(start_line->next);  	line_cnt++;  }  else {	/* Install new text */  	free_space(start_line->text);  	start_line->text = alloc(length_of(text_buffer) + 1);  	copy_string(start_line->text, text_buffer);  }/* Fix screen. First check if line is shifted. Perhaps we should shift it back*/  if (get_shift(start_line->shift_count)) {  	shift = (XBREAK - count_chars(start_line)) / SHIFT_SIZE;  	if (shift > 0) {		/* Shift line `shift' back */  		if (shift >= get_shift(start_line->shift_count))  			start_line->shift_count = 0;  		else  			start_line->shift_count -= shift;  		nx += shift * SHIFT_SIZE;/* Reset x value */  	}  }  if (line_cnt == 0) {		    /* Check if only one line changed */  	if (shift > 0) {	    /* Reprint whole line */  		set_cursor(0, y);  		line_print(start_line);  	}  	else {			    /* Just display last part of line */  		set_cursor(x, y);  		put_line(start_line, x, TRUE);  	}  	move_to(nx, y);	   /* Reset cur_text */  	return;  }  shift = last_y;	   /* Save value */  reset(top_line, y);  display(0, y, start_line, shift - y);  move_to((line_cnt == 1) ? nx : 0, y);}/*  ========================================================================  * *				Yank Commands				      *	 *  ========================================================================  */LINE *mark_line;			/* For marking position. */char *mark_text;int lines_saved;			/* Nr of lines in buffer *//* * PT() inserts the buffer at the current location. */void PT(){  register int fd;		/* File descriptor for buffer */  if ((fd = scratch_file(READ)) == ERRORS)  	error("Buffer is empty.", NIL_PTR);  else {  	file_insert(fd, FALSE);/* Insert the buffer */  	(void) close(fd);  }}/* * IF() prompt for a filename and inserts the file at the current location  * in the file. */void IF(){  register int fd;		/* File descriptor of file */  char name[LINE_LEN];		/* Buffer for file name *//* Get the file name */  if (get_file("Get and insert file:", name) != FINE)  	return;    if ((fd = open(name, 0)) < 0)  	error("Cannot open ", name);  else {  	file_insert(fd, TRUE);	/* Insert the file */  	(void) close(fd);  }}/* * File_insert() inserts a an opened file (as given by filedescriptor fd) * at the current location. */void file_insert(fd, old_pos)int fd;FLAG old_pos;{  char line_buffer[MAX_CHARS];		/* Buffer for next line */  register LINE *line = cur_line;  register int line_count = nlines;	/* Nr of lines inserted */  LINE *page = cur_line;  int ret = ERRORS;  /* Get the first piece of text (might be ended with a '\n') from fd */  if (get_line(fd, line_buffer) == ERRORS)  	return;				/* Empty file *//* Insert this text at the current location. */  if (insert(line, cur_text, line_buffer) == ERRORS)  	return;/* Repeat getting lines (and inserting lines) until EOF is reached */  while ((ret = get_line(fd, line_buffer)) != ERRORS && ret != NO_LINE)  	line = line_insert(line, line_buffer, ret);    if (ret == NO_LINE) {		/* Last line read not ended by a '\n' */  	line = line->next;  	(void) insert(line, line->text, line_buffer);  }/* Calculate nr of lines added */  line_count = nlines - line_count;/* Fix the screen */  if (line_count == 0) {		/* Only one line changed */  	set_cursor(0, y);  	line_print(line);  	move_to((old_pos == TRUE) ? x : x + length_of(line_buffer), y);  }  else {				/* Several lines changed */  	reset(top_line, y);	/* Reset pointers */  	while (page != line && page != bot_line->next)  		page = page->next;  	if (page != bot_line->next || old_pos == TRUE)  		display(0, y, cur_line, screenmax - y);  	if (old_pos == TRUE)  		move_to(x, y);  	else if (ret == NO_LINE)		move_to(length_of(line_buffer), find_y(line));	else 		move_to(0, find_y(line->next));  }/* If nr of added line >= REPORT, print the count */  if (line_count >= REPORT)  	status_line(num_out((long) line_count), " lines added.");}/* * WB() writes the buffer (yank_file) into another file, which * is prompted for. */void WB(){  register int new_fd;		/* Filedescriptor to copy file */  int yank_fd;			/* Filedescriptor to buffer */  register int cnt;		/* Count check for read/write */  int ret = 0;			/* Error check for write */  char file[LINE_LEN];		/* Output file */  /* Checkout the buffer */  if ((yank_fd = scratch_file(READ)) == ERRORS) {  	error("Buffer is empty.", NIL_PTR);  	return;  }/* Get file name */  if (get_file("Write buffer to file:", file) != FINE)  	return;  /* Creat the new file */  if ((new_fd = creat(file, 0644)) < 0) {  	error("Cannot create ", file);  	return;  }  status_line("Writing ", file);  /* Copy buffer into file */  while ((cnt = read(yank_fd, text_buffer, sizeof(text_buffer))) > 0)  	if (write(new_fd, text_buffer, cnt) != cnt) {  		bad_write(new_fd);  		ret = ERRORS;  		break;  	}/* Clean up open files and status_line */  (void) close(new_fd);  (void) close(yank_fd);  if (ret != ERRORS)			/* Bad write */  	file_status("Wrote", chars_saved, file, lines_saved, TRUE, FALSE);}/* * MA sets mark_line (mark_text) to the current line (text pointer).  */void MA(){  mark_line = cur_line;  mark_text = cur_text;  status_line("Mark set", NIL_PTR);}/* * YA() puts the text between the marked position and the current * in the buffer. */void YA(){  set_up(NO_DELETE);}/* * DT() is essentially the same as YA(), but in DT() the text is deleted. */void DT(){  set_up(DELETE);}/* * Set_up is an interface to the actual yank. It calls checkmark () to check * if the marked position is still valid. If it is, yank is called with the * arguments in the right order. */void set_up(remove)FLAG remove;				/* DELETE if text should be deleted */{  switch (checkmark()) {  	case NOT_VALID :  		error("Mark not set.", NIL_PTR);  		return;  	case SMALLER :  		yank(mark_line, mark_text, cur_line, cur_text, remove);  		break;  	case BIGGER :  		yank(cur_line, cur_text, mark_line, mark_text, remove);  		break;  	case SAME :		/* Ignore stupid behaviour */  		yank_status = EMPTY;  		chars_saved = 0L;  		status_line("0 characters saved in buffer.", NIL_PTR);  		break;  }}/* * Check_mark() checks if mark_line and mark_text are still valid pointers. If * they are it returns SMALLER if the marked position is before the current, * BIGGER if it isn't or SAME if somebody didn't get the point. * NOT_VALID is returned when mark_line and/or mark_text are no longer valid. * Legal() checks if mark_text is valid on the mark_line. */FLAG checkmark(){  register LINE *line;  FLAG cur_seen = FALSE;/* Special case: check is mark_line and cur_line are the same. */  if (mark_line == cur_line) {  	if (mark_text == cur_text)	/* Even same place */  		return SAME;  	if (legal() == ERRORS)		/* mark_text out of range */  		return NOT_VALID;  	return (mark_text < cur_text) ? SMALLER : BIGGER;  }/* Start looking for mark_line in the line structure */  for (line = header->next; line != tail; line = line->next) {  	if (line == cur_line)  		cur_seen = TRUE;  	else if (line == mark_line)  		break;  }/* If we found mark_line (line != tail) check for legality of mark_text */  if (line == tail || legal() == ERRORS)  	return NOT_VALID;/* cur_seen is TRUE if cur_line is before mark_line */  return (cur_seen == TRUE) ? BIGGER : SMALLER;}/* * Legal() checks if mark_text is still a valid pointer. */int legal(){  register char *textp = mark_line->text;/* Locate mark_text on mark_line */  while (textp != mark_text && *textp++ != '\0')  	;  return (*textp == '\0') ? ERRORS : FINE;}/* * Yank puts all the text between start_position and end_position into * the buffer. * The caller must check that the arguments to yank() are valid. (E.g. in * the right order) */void yank(start_line, start_textp, end_line, end_textp, remove)LINE *start_line, *end_line;char *start_textp, *end_textp;FLAG remove;				/* DELETE if text should be deleted */{  register LINE *line = start_line;  register char *textp = start_textp;  int fd;/* Creat file to hold buffer */  if ((fd = scratch_file(WRITE)) == ERRORS)  	return;    chars_saved = 0L;  lines_saved = 0;  status_line("Saving text.", NIL_PTR);/* Keep writing chars until the end_location is reached. */  while (textp != end_textp) {  	if (write_char(fd, *textp) == ERRORS) {  		(void) close(fd);  		return;  	}  	if (*textp++ == '\n') {	/* Move to the next line */  		line = line->next;  		textp = line->text;  		lines_saved++;  	}  	chars_saved++;  }/* Flush the I/O buffer and close file */  if (flush_buffer(fd) == ERRORS) {  	(void) close(fd);  	return;  }  (void) close(fd);  yank_status = VALID;/* * Check if the text should be deleted as well. If it should, the following * hack is used to save a lot of code. First move back to the start_position. * (This might be the location we're on now!) and them delete the text. * It might be a bit confusing the first time somebody uses it. * Delete() will fix the screen. */  if (remove == DELETE) {  	move_to(find_x(start_line, start_textp), find_y(start_line));  	delete(start_line, start_textp, end_line, end_textp);  }  status_line(num_out(chars_saved), " characters saved in buffer.");}/* * Scratch_file() creates a uniq file in /usr/tmp. If the file couldn't * be created other combinations of files are tried until a maximum * of MAXTRAILS times. After MAXTRAILS times, an error message is given * and ERRORS is returned. */#define MAXTRAILS	26int scratch_file(mode)FLAG mode;				/* Can be READ or WRITE permission */{  static int trials = 0;		/* Keep track of trails */  register char *y_ptr, *n_ptr;  int fd;				/* Filedescriptor to buffer *//* If yank_status == NOT_VALID, scratch_file is called for the first time */  if (yank_status == NOT_VALID && mode == WRITE) { /* Create new file */  	/* Generate file name. */	y_ptr = &yank_file[11];	n_ptr = num_out((long) getpid());	while ((*y_ptr = *n_ptr++) != '\0')		y_ptr++;	*y_ptr++ = 'a' + trials;	*y_ptr = '\0';  	/* Check file existence */  	if (access(yank_file, 0) == 0 || (fd = creat(yank_file, 0644)) < 0) {  		if (trials++ >= MAXTRAILS) {  			error("Unable to creat scratchfile.", NIL_PTR);  			return ERRORS;  		}  		else  			return scratch_file(mode);/* Have another go */  	}  }  else if ((mode == READ && (fd = open(yank_file, 0)) < 0) ||			(mode == WRITE && (fd = creat(yank_file, 0644)) < 0)) {  	yank_status = NOT_VALID;  	return ERRORS;  }  clear_buffer();  return fd;}/*  ========================================================================  * *				Search Routines				      *	 *  ========================================================================  *//* * A regular expression consists of a sequence of: * 	1. A normal character matching that character. * 	2. A . matching any character. * 	3. A ^ matching the begin of a line. * 	4. A $ (as last character of the pattern) mathing the end of a line. * 	5. A \<character> matching <character>. * 	6. A number of characters enclosed in [] pairs matching any of these * 	   characters. A list of characters can be indicated by a '-'. So * 	   [a-z] matches any letter of the alphabet. If the first character * 	   after the '[' is a '^' then the set is negated (matching none of * 	   the characters).  * 	   A ']', '^' or '-' can be escaped by putting a '\' in front of it. * 	7. If one of the expressions as described in 1-6 is followed by a * 	   '*' than that expressions matches a sequence of 0 or more of * 	   that expression. */char typed_expression[LINE_LEN];	/* Holds previous expr. *//* * SF searches forward for an expression. */void SF(){  search("Search forward:", FORWARD);}/* * SF searches backwards for an expression. */void SR(){  search("Search reverse:", REVERSE);}/* * Get_expression() prompts for an expression. If just a return is typed, the * old expression is used. If the expression changed, compile() is called and * the returning REGEX structure is returned. It returns NIL_REG upon error. * The save flag indicates whether the expression should be appended at the * message pointer. */REGEX *get_expression(message)char *message;{  static REGEX program;			/* Program of expression */  char exp_buf[LINE_LEN];			/* Buffer for new expr. */  if (get_string(message, exp_buf, FALSE) == ERRORS)  	return NIL_REG;    if (exp_buf[0] == '\0' && typed_expression[0] == '\0') {  	error("No previous expression.", NIL_PTR);  	return NIL_REG;  }  if (exp_buf[0] != '\0') {		/* A new expr. is typed */  	copy_string(typed_expression, exp_buf);/* Save expr. */  	compile(exp_buf, &program);	/* Compile new expression */  }  if (program.status == REG_ERROR) {	/* Error during compiling */  	error(program.result.err_mess, NIL_PTR);  	return NIL_REG;  }  return &program;}/* * GR() a replaces all matches from the current position until the end * of the file. */void GR(){  change("Global replace:", VALID);}/* * LR() replaces all matches on the current line. */void LR(){  change("Line replace:", NOT_VALID);}/* * Change() prompts for an expression and a substitution pattern and changes * all matches of the expression into the substitution. change() start looking * for expressions at the current line and continues until the end of the file * if the FLAG file is VALID. */void change(message, file)char *message;				/* Message to prompt for expression */FLAG file;{  char mess_buf[LINE_LEN];	/* Buffer to hold message */  char replacement[LINE_LEN];	/* Buffer to hold subst. pattern */  REGEX *program;			/* Program resulting from compilation */  register LINE *line = cur_line;  register char *textp;  long lines = 0L;		/* Nr of lines on which subs occurred */  long subs = 0L;			/* Nr of subs made */  int page = y;			/* Index to check if line is on screen*//* Save message and get expression */  copy_string(mess_buf, message);  if ((program = get_expression(mess_buf)) == NIL_REG)  	return;  /* Get substitution pattern */  build_string(mess_buf, "%s %s by:", mess_buf, typed_expression);  if (get_string(mess_buf, replacement, FALSE) == ERRORS)  	return;    set_cursor(0, ymax);  flush();/* Substitute until end of file */  do {  	if (line_check(program, line->text, FORWARD)) {  		lines++;  		/* Repeat sub. on this line as long as we find a match*/

⌨️ 快捷键说明

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