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

📄 mined2.c

📁 MINED文本文件编缉器
💻 C
📖 第 1 页 / 共 4 页
字号:
 * Replace is substitute with confirmation dialogue. */voidREPL (){  change ("Global replace (with confirm):", VALID, TRUE);}/* * LR () replaces all matches on the current line. */voidLR (){  change ("Line replace:", NOT_VALID, FALSE);}/* * Search () calls get_expression to fetch the expression. If this went well, * the function match () is called which returns the line with the next match. * If this line is the NIL_LINE, it means that a match could not be found. * Find_x () and find_y () display the right page on the screen, and return * the right coordinates for x and y. * These coordinates are passed to move_to (). * Re_search () searches using the last search program and direction.   Call graph of search procedures:RS ------------\SFW -\		> re_search > match -----------\SRV --> search <				\	        \				 \	         > get_expression > compile	  > line_check > check_stringGR  \	        /				 /REPL > change  <--------------------------------/LR  /	        \		 \ substitute */REGEX * lastprogram = NIL_REG;FLAG lastmethod = NOT_VALID;	/* FORWARD, REVERSE */char prevexpr [maxLINE_LEN];	/* Buffer for previous expr. */FLAG prevmethod = NOT_VALID;	/* FORWARD, REVERSE */void do_search ();voidre_search (){  do_search (lastprogram, lastmethod);}voidprev_search (){  search_for (prevexpr, prevmethod);}voidsearch (message, method)  char * message;  FLAG method;{  register REGEX * program;  char prevexp_buf [maxLINE_LEN];	/* Buffer for previous expr. */  if (lastmethod != NOT_VALID) copy_string (prevexp_buf, exp_buf);/* Get the expression */  if ((program = get_expression (message)) == NIL_REG)	return;  if (program != NIL_REG && lastmethod != NOT_VALID) {	copy_string (prevexpr, prevexp_buf);	prevmethod = lastmethod;  }  lastprogram = program;  lastmethod = method;  re_search ();}voidsearch_for (expr, method)  char * expr;  FLAG method;{  register REGEX * program;/* make the expression */  if ((program = make_expression (expr)) == NIL_REG)	return;  do_search (program, method);}voiddo_search (program, method)  register REGEX * program;  FLAG method;{  register LINE * match_line;  if (method == NOT_VALID) {	error ("No previous search", NIL_PTR);	return;  }  if (program == NIL_REG) {	error ("No previous search expression", NIL_PTR);	return;  }  set_cursor (0, YMAX);  clear_status ();  flush ();/* Find the match */  if ((match_line = match (program, cur_text, method)) == NIL_LINE) {	if (quit == TRUE) {		status_msg ("Aborted");/*		swallow_dummy_quit_char (); */		quit = FALSE;	}	else		status_msg ("Pattern not found");	return;  }/*  clear_status (); */  move_address (program->start_ptr, find_y (match_line));}/* Now the search and replace utilities *//* ------------------------------------ *//* Opcodes for characters */#define	NORMAL		0x0200#define DOT		0x0400#define EOLN		0x0800#define STAR		0x1000#define BRACKET		0x2000#define NEGATE		0x0100#define DONE		0x4000/* Mask for opcodes and characters */#define LOW_BYTE	0x00FF#define HIGH_BYTE	0xFF00/* Previous is the contents of the previous address (ptr) points to */#define previous(ptr)		(* ((ptr) - 1))/* Buffer to store outcome of compilation */int exp_buffer [BLOCK_SIZE];/* Errors often used */char * too_long = "Regular expression too long";/* * Reg_error () is called by compile () if something went wrong. It sets the * status of the structure to error, and assigns the error field of the union. */#define reg_error(str)	program->status = REG_ERROR, \					program->result.err_mess = (str)/* * Bcopy copies `bytes' bytes from the `from' address into the `to' address. */#ifdef vms#define defbcopy#endif#ifdef msdos#define defbcopy#endif#ifdef defbcopy	/* otherwise also in standard library */voidbcopy (from, to, bytes)  register char * from, * to;  register int bytes;{  while (bytes --)	* to ++ = * from ++;}#else#ifdef sysV#define bcopy(from, to, len)	memcpy (to, from, len)#elseextern void bcopy ();#endif#endif/* * Finished () is called when everything went right during compilation. It * allocates space for the expression, and copies the expression buffer into * this field. */FLAGfinished (program, last_exp)  register REGEX * program;  int * last_exp;{  register int length = (int) (last_exp - exp_buffer) * sizeof (int);/* Allocate space */  program->result.expression = (int *) alloc (length);  if (program->result.expression == NIL_INT) {	ring_bell ();	error ("Cannot allocate memory for search expression", NIL_PTR);	return ERRORS;  }  else {	/* Copy expression. (expression consists of ints!) */	bcopy (exp_buffer, program->result.expression, length);	return FINE;  }}/* * Compile compiles the pattern into a more comprehensible form and returns a * REGEX structure. If something went wrong, the status field of the structure * is set to REG_ERROR and an error message is set into the err_mess field of * the union. If all went well the expression is saved and the expression * pointer is set to the saved (and compiled) expression. */FLAGcompile (pattern, program)  register uchar * pattern;	/* Pointer to pattern */  REGEX * program;{  register int * expression = exp_buffer;  int * prev_char;		/* Pointer to previous compiled atom */  int * acct_field = NIL_INT;	/* Pointer to last BRACKET start */  FLAG negate;			/* Negate flag for BRACKET */  uchar low_char;		/* Index for chars in BRACKET */  uchar c;/* Check for begin of line */  if (* pattern == '^') {	program->status = BEGIN_LINE;	pattern ++;  }  else {	program->status = 0;/* If the first character is a '*' we have to assign it here. */	if (* pattern == '*') {		* expression ++ = '*' + NORMAL;		pattern ++;	}  }  for (; ;) {	c = * pattern ++;	switch (c) {	case '.' :		* expression ++ = DOT;		break;	case '$' :		/*		 * Only means EOLN if it is the last char of the pattern		 */		if (* pattern == '\0') {			* expression ++ = EOLN | DONE;			program->status |= END_LINE;			return finished (program, expression);		}		else			* expression ++ = NORMAL + '$';		break;	case '\0' :		* expression ++ = DONE;		return finished (program, expression);	case '\\' :		/* If last char, it must! mean a normal '\' */		if (* pattern == '\0')			* expression ++ = NORMAL + '\\';		else			* expression ++ = NORMAL + * pattern ++;		break;	case '*' :		/*		 * If the previous expression was a [] find out the		 * begin of the list, and adjust the opcode.		 */		prev_char = expression - 1;		if (* prev_char & BRACKET)			* (expression - (* acct_field & LOW_BYTE)) |= STAR;		else			* prev_char |= STAR;		break;	case '[' :		/*		 * First field in expression gives information about		 * the list.		 * The opcode consists of BRACKET and if necessary		 * NEGATE to indicate that the list should be negated		 * and/or STAR to indicate a number of sequence of this		 * list.		 * The lower byte contains the length of the list.		 */		acct_field = expression ++;		if (* pattern == '^') {	/* List must be negated */			pattern ++;			negate = TRUE;		}		else			negate = FALSE;		while (* pattern != ']') {			if (* pattern == '\0') {				reg_error ("Missing ]");				return FINE;			}			if (* pattern == '\\')				pattern ++;			* expression ++ = * pattern ++;			if (* pattern == '-') {						/* Make list of chars */				low_char = previous (pattern);				pattern ++;	/* Skip '-' */				if (low_char ++ > * pattern) {					reg_error ("Bad range in [a-z]");					return FINE;				}				/* Build list */				while (low_char <= * pattern					&& low_char != '\0')				 /* avoid wrap-around beyond '\377' (loop!) */					* expression ++ = low_char ++;				pattern ++;			}			if (expression >= & exp_buffer [BLOCK_SIZE]) {				reg_error (too_long);				return FINE;			}		}		pattern ++;			/* Skip ']' */		/* Assign length of list in acct field */		if ((* acct_field = (int) (expression - acct_field)) == 1) {			reg_error ("Empty []");			return FINE;		}		/* Assign negate and bracket field */		* acct_field |= BRACKET;		if (negate == TRUE)			* acct_field |= NEGATE;		/*		 * Add BRACKET to opcode of last char in field because		 * a '*' may be following the list.		 */		previous (expression) |= BRACKET;		break;	default :		* expression ++ = c + NORMAL;	}	if (expression == & exp_buffer [BLOCK_SIZE]) {		reg_error (too_long);		return FINE;	}  }  /* NOTREACHED */}/* * Match gets as argument the program, pointer to place in current line to * start from and the method to search for (either FORWARD or REVERSE). * Match () will look through the whole file until a match is found. * NIL_LINE is returned if no match could be found. */LINE *match (program, string, method)  REGEX * program;  uchar * string;  register FLAG method;{  register LINE * line = cur_line;  uchar old_char;				/* For saving chars *//* Corrupted program */  if (program->status == REG_ERROR)	return NIL_LINE;/* Check part of text first */  if (! (program->status & BEGIN_LINE)) {	if (method == FORWARD) {		if (line_check (program, string + 1, method) == MATCH)			return cur_line;	/* Match found */	}	else if (! (program->status & END_LINE)) {		old_char = * string;	/* Save char and */		* string = '\n';	/* Assign '\n' for line_check */		if (line_check (program, line->text, method) == MATCH) {			* string = old_char; /* Restore char */			return cur_line;    /* Found match */		}		* string = old_char;	/* No match, but restore char */	}  }/* No match in last (or first) part of line. Check out rest of file */  do {	line = (method == FORWARD) ? line->next : line->prev;	if (line->text == NIL_PTR) {	/* Header/tail */		status_msg ("Search wrapped around end of file");		continue;		}	if (line_check (program, line->text, method) == MATCH)		return line;  } while (line != cur_line && quit == FALSE);/* No match found. */  return NIL_LINE;}/* * Line_check () checks the line (or rather string) for a match. Method * indicates FORWARD or REVERSE search. It scans through the whole string * until a match is found, or the end of the string is reached. */intline_check (program, string, method)  register REGEX * program;  char * string;  FLAG method;{  register char * textp = string;/* Assign start_ptr field. We might find a match right away! */  program->start_ptr = textp;/* If the match must be anchored, just check the string. */  if (program->status & BEGIN_LINE)	return check_string (program, string, NIL_INT);  if (method == REVERSE) {	/* First move to the end of the string */	for (textp = string; * textp != '\n'; textp ++)		;	/* Start checking string until the begin of the string is met */	while (textp >= string) {		program->start_ptr = textp;		if (check_string (program, textp --, NIL_INT))			return MATCH;	}  }  else {	/* Move through the string until the end of it is found */	while (quit == FALSE && * textp != '\0') {		program->start_ptr = textp;		if (check_string (program, textp, NIL_INT))			return MATCH;		if (* textp == '\n')			break;		textp ++;	}  }  return NO_MATCH;}/* * Check_string () checks if a match can be found in the given string. * Whenever a STAR is found during matching, then the begin position of * the string is marked and the maximum number of matches is performed. * Then the function star () is called which starts to finish the match * from this position of the string (and expression). * Check () returns MATCH for a match, NO_MATCH if the string * couldn't be matched or REG_ERROR for an illegal opcode in expression. */intcheck_string (program, string, expression)  REGEX * program;  register uchar * string;  int * expression;{  register int opcode;		/* Holds opcode of next expr. atom */  uchar c;			/* Char that must be matched */  uchar * mark;		/* For marking position */  int star_fl;			/* A star has been born */  if (expression == NIL_INT)	expression = program->result.expression;/* Loop until end of string or end of expression */  while (quit == FALSE && ! (* expression & DONE) &&				   * string != '\0' && * string != '\n') {	c = * expression & LOW_BYTE;	  /* Extract match char */	opcode = * expression & HIGH_BYTE; /* Extract opcode */	if ((star_fl = (opcode & STAR)) != 0) {  /* Check star occurrence */		opcode &= ~STAR;	  /* Strip opcode */		mark = string;		  /* Mark current position */	}	expression ++;		/* Increment expr. */	switch (opcode) {	case NORMAL :		if (star_fl)			while (* string ++ == c)	/* Skip all matches */				;		else if (* string ++ != c)			return NO_MATCH;		break;	case DOT :		string ++;		if (star_fl)			/* Skip to eoln */			while (* string != '\0' && * string ++ != '\n')				;		break;	case NEGATE | BRACKET :	case BRACKET :	     if (star_fl)		while (in_list (expression, * string ++, c, opcode) == MATCH)			;	     else		if (in_list (expression, * string ++, c, opcode) == NO_MATCH)			return NO_MATCH;		expression += c - 1;	/* Add length of list */		break;	default :		/* panic ("Corrupted search program", NIL_PTR); */		ring_bell ();		error ("Corrupted search program", NIL_PTR);		sleep (2);		return NO_MATCH;	}	if (star_fl)		return star (program, mark, string, expression);  }  if (* expression & DONE) {	program->end_ptr = (char *) string;	/* Match ends here */	/*	 * We might have found a match. The last thing to do is check	 * whether a '$' was given at the end of the expression, or	 * the match was found on a null string. (E.g. [a-z]* always	 * matches) unless a ^ or $ was included in the pattern.	 */	if ((* expression & EOLN) && * string != '\n' && * string != '\0')		return NO_MATCH;	if (string == (uchar *) program->start_ptr					&& ! (program->status & BEGIN_LINE)					&& ! (* expression & EOLN))		return NO_MATCH;	return MATCH;  }  return NO_MATCH;}/* * Star () calls check_string () to find out the longest match possible. * It searches backwards until the (in check_string ()) marked position * is reached, or a match is found. */intstar (program, end_position, string, expression)  REGEX * program;  register char * end_position;  register char * string;  int * expression;{  do {	string --;	if (check_string (program, string, expression))		return MATCH;  } while (string != end_position);  return NO_MATCH;}/* * In_list () checks if the given character is in the list of []. If it is * it returns MATCH. If it isn't it returns NO_MATCH. These returns values * are reversed when the NEGATE field in the opcode is present. */intin_list (list, c, list_length, opcode)  register int * list;  uchar c;  register int list_length;  int opcode;{  if (c == '\0' || c == '\n')	/* End of string, never matches */	return NO_MATCH;  while (list_length -- > 1) {	/* > 1, don't check acct_field */	if ((* list & LOW_BYTE) == c)		return (opcode & NEGATE) ? NO_MATCH : MATCH;	list ++;  }  return (opcode & NEGATE) ? MATCH : NO_MATCH;}/*  ==================================================================	* *				End					* *  ==================================================================	*/

⌨️ 快捷键说明

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