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

📄 mined2.c

📁 MINED文本文件编缉器
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * MARKn sets mark n to the current line / current text pointer. */voidMARKn (c)  uchar c;{  if (hop_flag > 0) GOMAn (c);  else {	mark_n_line [c & '\17'] = cur_line;	mark_n_text [c & '\17'] = cur_text;	status_msg ("Mark set");  }}/* * GOMAn moves to the marked position n */voidGOMAn (c)  uchar c;{  if (checkmark (mark_n_line [c & '\17'], mark_n_text [c & '\17']) == NOT_VALID)	error ("Mark not set", NIL_PTR);  else	move_address (mark_n_text [c & '\17'], find_y (mark_n_line [c & '\17']));}/* * Yankie () provides a reference to the last saved buffer to be read * by other mined invocations. */voidyankie (){  delete_file (yankie_file);#ifdef unix  link (yank_file, yankie_file);#else  build_string (text_buffer, copycommand, yank_file, yankie_file);  system (text_buffer);#endif}/* * 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. */voidset_up (remove, append)  FLAG remove;	/* == DELETE if text should be deleted */  FLAG append;	/* == TRUE if text should only be appended to yank buffer */{  switch (checkmark (mark_line, mark_text)) {	case NOT_VALID :		error ("Mark not set", NIL_PTR);		return;	case SMALLER :		yank (mark_line, mark_text, cur_line, cur_text, remove, append);		yankie ();		break;	case BIGGER :		yank (cur_line, cur_text, mark_line, mark_text, remove, append);		yankie ();		break;	case SAME :		/* Ignore stupid behaviour */	/*	yank_status = EMPTY;	*/		chars_saved = 0L;		status_msg ("Nothing to save");		break;	default :		error ("Internal mark error", NIL_PTR);		return;  }}/* * YA () puts the text between the marked position and the current * in the buffer. */voidYA (){  set_up (NO_DELETE, (hop_flag > 0) ? TRUE : FALSE);}/* * DT () is essentially the same as YA (), but in DT () the text is deleted. */voidDT (){  if (viewonly == TRUE)	{viewonlyerr (); return;}  set_up (DELETE, (hop_flag > 0) ? TRUE : FALSE);}/* * 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. */FLAGcheckmark (mark_line, mark_text)  register LINE * mark_line;  register char * mark_text;{  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 (mark_line, mark_text) == 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 (mark_line, mark_text) == 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. */intlegal (mark_line, mark_text)  register LINE * mark_line;  register char * mark_text;{  register char * textp = mark_line->text;/* Locate mark_text on mark_line */  while (textp != mark_text && * textp != '\0')	textp ++;  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). */voidyank (start_line, start_textp, end_line, end_textp, remove, append)  LINE * start_line, * end_line;  char * start_textp, * end_textp;  FLAG remove;	/* == DELETE if text should be deleted */  FLAG append;	/* == TRUE if text should only be appended to yank buffer */{  register LINE * line = start_line;  register char * textp = start_textp;  int fd;/* Create file to hold buffer */  if ((fd = scratch_file (WRITE, append)) == ERRORS)	return;  chars_saved = 0L;  lines_saved = 0;  if (append == TRUE)	status_msg ("Appending text ...");  else	status_msg ("Saving text ...");/* Keep writing chars until the end_location is reached. */  while (textp != end_textp) {	if (writechar (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. In case it should,   * the following hack is used to save a lot of code.   * First move back to the start_position (this might be the current   * location) and then delete the text.   * This might look a bit confusing to the user the first time.   * Delete () will fix the screen.   */  if (remove == DELETE) {	move_to (find_x (start_line, start_textp), find_y (start_line));	if (delete_text (start_line, start_textp, end_line, end_textp)		== ERRORS) {		sleep (2) /* give time to read allocation error msg */;	}	mark_line = cur_line;	mark_text = cur_text;  }  if (append == TRUE)	status_line (num_out (chars_saved), " characters appended to buffer");  else	status_line (num_out (chars_saved), " characters saved in buffer");}/* * Scratch_file () tries to create a unique file in a temporary directory. * It tries several different filenames until one can be created * or MAXTRIALS attempts have been made. * After MAXTRIALS times, an error message is given and ERRORS is returned. */#define MAXTRIALS 99intscratch_file (mode, append)  FLAG mode;	/* Can be READ or WRITE permission */  FLAG append;	/* == TRUE if text should only be appended to yank buffer */{  static int trials = 0;	/* Keep track of trials */  int fd = 0;			/* 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. */#ifdef msdos	build_string (yank_file, "%s%d", yankie_file, trials);#else	build_string (yank_file, "%s%d-%d", yankie_file, getpid (), trials);#endif	/* Check file existence */	if (access (yank_file, 0 /* F_OK */) == 0	    || (fd = creat (yank_file, bufprot)) < 0) {		if (++ trials >= MAXTRIALS) {		    build_string (text_buffer, "Unable to create scratchfile %s: ", yank_file);		    if (fd == 0)			error (text_buffer, "File exists");		    else			error (text_buffer, serror ());		    return ERRORS;		}		else		    return scratch_file (mode, append);	/* try again */	}  }  else if (yank_status == NOT_VALID && mode == READ) {	return ERRORS;  }  else /* yank_status == VALID */	if (  (mode == READ && (fd = open (yank_file, O_RDONLY | O_BINARY, 0)) < 0)	   || (mode == WRITE &&		(fd = open (yank_file, O_WRONLY | O_CREAT |			((append == TRUE) ? O_APPEND : O_TRUNC), bufprot)) < 0)) {	yank_status = NOT_VALID;	return ERRORS;  }  clear_buffer ();  return fd;}/*  ==================================================================	* *				Search Commands				* *  ==================================================================	*//* * 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 [maxLINE_LEN];	/* Holds previous search expression *//* * SFW searches forward for an expression. */voidSFW (){  if (hop_flag > 0) SIDF (FORWARD);  else search ("Search forward:", FORWARD);}/* * SRV searches backwards for an expression. */voidSRV (){  if (hop_flag > 0) SIDF (REVERSE);  else search ("Search reverse:", REVERSE);}/* * RS searches using the last search direction and expression. */voidRS (){  if (hop_flag > 0) prev_search ();  else re_search ();}/* * 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. */char exp_buf [maxLINE_LEN];		/* Buffer for new expr. */REGEX *get_expression (message)  char * message;{  static REGEX program;			/* Program of expression */  if (get_string (message, exp_buf, FALSE) == ERRORS)	return NIL_REG;  if (exp_buf [0] == '\0' && typed_expression [0] == '\0') {	error ("No previous search 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 new expression: */	if (compile (exp_buf, & program) == ERRORS)		return NIL_REG;  }  if (program.status == REG_ERROR) {	/* Error during compiling */	error (program.result.err_mess, NIL_PTR);	return NIL_REG;  }  return & program;}/* * make_expression is only called by search_for and maintains its own,  * independant search program buffer */REGEX *make_expression (expr)  char * expr;{  static REGEX program;			/* Program of expression */  if (compile (expr, & program) == ERRORS)	/* Compile new expression */	return NIL_REG;  if (program.status == REG_ERROR) {	/* Error during compiling */	error (program.result.err_mess, NIL_PTR);	return NIL_REG;  }  return & program;}/* * Change () prompts for an expression and a substitution pattern and changes * all matches of the expression into the substitution. * change () starts looking for expressions at the current line and * continues until the end of the file if the FLAG `global' is VALID. * It prompts for each change if the FLAG `confirm' is TRUE. * For a call graph of search procedures see search (). */voidchange (message, global, confirm)  char * message;		/* Message to prompt for expression */  FLAG global, confirm;{  char mess_buf [maxLINE_LEN];		/* Buffer to hold message */  char replacement [maxLINE_LEN];	/* Buffer to hold subst. pattern */  REGEX * program;			/* Program resulting from compilation */  register LINE * line = cur_line;  register char * textp;  char * substitute ();  long lines = 0L;		/* Nr of lines on which subs occurred */  long subs = 0L;		/* Nr of subs made */  int ly = y;			/* Index to check if line is on screen */  int previousy = y;  char c;  FLAG quit_change;  if (viewonly == TRUE)	{viewonlyerr (); return;}/* Save message and get expression */  if ((program = get_expression (message)) == NIL_REG)	return;/* Get substitution pattern */  build_string (mess_buf, "%s %s by:", message, 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 */	    do {		if (confirm == TRUE) {			ly = find_y (line);			textp = program->start_ptr;			move_address (program->start_ptr, ly);			status_msg ("Replace ? (y/n)");			c = promptyn ();			clear_status ();			if (c == 'y') {			    subs ++;	/* Increment subs */			    if ((textp = substitute (line, program, replacement))							== NIL_PTR)				    return;	/* Line too long */			    set_cursor (0, ly);			    line_print (line);			}			else			    textp ++;		}		else {		    subs ++;	/* Increment subs */		    line->shift_count = 0;			/* in case line would get completely shifted out */		    if ((textp = substitute (line, program, replacement))							== NIL_PTR) {			set_cursor (0, ly);			line_print (line);			move_to (x, y);			return;	/* Line too long */		    }		}	    } while (  (program->status & BEGIN_LINE) != BEGIN_LINE		    && (program->status & END_LINE) != END_LINE		    && line_check (program, textp, FORWARD)		    && quit == FALSE);	    /* Check to see if we can print the result */	    if (confirm == FALSE && ly <= SCREENMAX) {		set_cursor (0, ly);		line_print (line);	    }	}	if (ly <= SCREENMAX)		ly ++;	line = line->next;  } while (line != tail && global == VALID && quit == FALSE);  quit_change = quit;/* Fix the status line */  if (subs == 0L && quit == FALSE)	error ("Pattern not found", NIL_PTR);  else if (lines >= REPORT || quit == TRUE) {	build_string (mess_buf, "%s %ld substitutions on %ld lines",		(quit_change == TRUE) ? "(Aborted) " : "", subs, lines);	status_msg (mess_buf);  }  else if (global == NOT_VALID && subs >= REPORT)	status_line (num_out (subs), " substitutions");  else	clear_status ();  if (confirm == TRUE) move_to (x, y);  else move_to (LINE_START, previousy);/*  if (quit == TRUE) swallow_dummy_quit_char (); */  quit = FALSE;}/* * Substitute () replaces the match on this line by the substitute pattern * as indicated by the program. Every '&' in the replacement is replaced by * the original match. A \ in the replacement escapes the next character. */char *substitute (line, program, replacement)  LINE * line;  REGEX * program;  char * replacement;	/* Contains replacement pattern */{  register char * textp = text_buffer;  register char * subp = replacement;  char * linep = line->text;  char * amp;  char * newtext;  modified = TRUE;/* Copy part of line until the beginning of the match */  while (linep != program->start_ptr)	* textp ++ = * linep ++;/* * Replace the match by the substitution pattern. Each occurrence of '&' is * replaced by the original match. A \ escapes the next character. */  while (* subp != '\0' && textp < & text_buffer [MAX_CHARS]) {	if (* subp == '&') {		/* Replace the original match */		amp = program->start_ptr;		while (amp < program->end_ptr && textp < & text_buffer [MAX_CHARS])			* textp ++ = * amp ++;		subp ++;	}	else {		if (* subp == '\\' && * (subp + 1) != '\0')			subp ++;		* textp ++ = * subp ++;	}  }  * textp = '\0';/* Check for line length not exceeding MAX_CHARS */  if (length_of (text_buffer) + length_of (program->end_ptr) >= MAX_CHARS) {	error ("Substitution failed: resulted line too long", NIL_PTR);	return NIL_PTR;  }/* Append last part of line to the newly built line */  copy_string (textp, program->end_ptr);/* Free old line and install new one */  newtext = alloc (length_of (text_buffer) + 1);  if (newtext == NIL_PTR) {	ring_bell ();	error ("Substitution failed: cannot allocate more memory", NIL_PTR);	return NIL_PTR;  }  else {	free_space (line->text);	line->text = newtext;	copy_string (line->text, text_buffer);	return (line->text + (int) (textp - text_buffer));  }}/* * GR () a replaces all matches from the current position until the end * of the file. */voidGR (){  change ("Global replace:", VALID, FALSE);}/*

⌨️ 快捷键说明

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