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

📄 sed.c

📁 GNU Sed GNU Sed GNU Sed
💻 C
📖 第 1 页 / 共 3 页
字号:
			line.length=0;
			if(!(cur_cmd->aflags&A1_MATCHED_BIT))
				ck_fwrite(cur_cmd->x.cmd_txt.text,1,cur_cmd->x.cmd_txt.text_len,stdout);
			end_cycle++;
			break;

		case 'd':
			line.length=0;
			end_cycle++;
			break;

		case 'D':
			{
				char *tmp;
				int newlength;

				tmp=memchr(line.text,'\n',line.length);
				newlength=line.length-(tmp-line.text);
				if(newlength)
					memmove(line.text,tmp,newlength);
				line.length=newlength;
			}
			end_cycle++;
			break;

		case 'g':
			line_copy(&hold,&line);
			break;

		case 'G':
			line_append(&hold,&line);
			break;

		case 'h':
			line_copy(&line,&hold);
			break;

		case 'H':
			line_append(&line,&hold);
			break;

		case 'i':
			ck_fwrite(cur_cmd->x.cmd_txt.text,1,cur_cmd->x.cmd_txt.text_len,stdout);
			break;

		case 'l':
			{
				char *tmp;
				int n;
				int width = 0;

				n=line.length;
				tmp=line.text;
				/* Use --n so this'll skip the trailing newline */
				while(--n) {
					if(width>77) {
						width=0;
						putchar('\n');
					}
					if(*tmp == '\\') {
					        printf("\\\\");
						width+=2;
					} else if(isprint(*tmp)) {
						putchar(*tmp);
						width++;
					} else switch(*tmp) {
#if 0
  /* Should print \00 instead of \0 because (a) POSIX requires it, and
     (b) this way \01 is unambiguous.  */
					case '\0':
						printf("\\0");
						width+=2;
						break;
#endif
					case 007:
						printf("\\a");
						width+=2;
						break;
					case '\b':
						printf("\\b");
						width+=2;
						break;
					case '\f':
						printf("\\f");
						width+=2;
						break;
					case '\n':
						printf("\\n");
						width+=2;
						break;
					case '\r':
						printf("\\r");
						width+=2;
						break;
					case '\t':
						printf("\\t");
						width+=2;
						break;
					case '\v':
						printf("\\v");
						width+=2;
						break;
					default:
						printf("\\%02x",(*tmp)&0xFF);
						width+=2;
						break;
					}
					tmp++;
				}
				putchar('\n');
			}
			break;

		case 'n':
			if (feof(input_file)) goto quit;
			ck_fwrite(line.text,1,line.length,stdout);
			read_pattern_space();
			break;

		case 'N':
			if (feof(input_file)) goto quit;
			append_pattern_space();
			break;

		case 'p':
			ck_fwrite(line.text,1,line.length,stdout);
			break;

		case 'P':
			{
				char *tmp;

				tmp=memchr(line.text,'\n',line.length);
				ck_fwrite(line.text, 1,
					  tmp ? tmp - line.text + 1
					  : line.length, stdout);
			}
			break;

		case 'q': quit:
			quit_cmd++;
			end_cycle++;
			break;

		case 'r':
			{
				int n = 0;

				rewind(cur_cmd->x.io_file);
				do {
					append.length += n;
					if(append.length==append.alloc) {
						append.alloc *= 2;
						append.text = ck_realloc(append.text, append.alloc);
					}
				} while((n=fread(append.text+append.length,sizeof(char),append.alloc-append.length,cur_cmd->x.io_file))>0);
				if(ferror(cur_cmd->x.io_file))
					panic("Read error on input file to 'r' command");
			}
			break;

		case 's':
			if(!tmp.alloc) {
				tmp.alloc=50;
				tmp.text=ck_malloc(50);
			}
			count=0;
			start = 0;
			remain=line.length-1;
			tmp.length=0;
			rep = cur_cmd->x.cmd_regex.replacement;
			rep_end=rep+cur_cmd->x.cmd_regex.replace_length;

			while((offset = re_search(cur_cmd->x.cmd_regex.regx,
						  line.text,
						  line.length-1,
						  start,
						  remain,
						  &regs))>=0) {
				count++;
				if(offset-start)
					str_append(&tmp,line.text+start,offset-start);

				if(cur_cmd->x.cmd_regex.flags&S_NUM_BIT) {
					if(count!=cur_cmd->x.cmd_regex.numb) {
						str_append(&tmp,line.text+regs.start[0],regs.end[0]-regs.start[0]);
						start = (offset == regs.end[0] ? offset + 1 : regs.end[0]);
						remain = (line.length-1) - start;
						continue;
					}
				}

				for(rep_next=rep_cur=rep;rep_next<rep_end;rep_next++) {
					if(*rep_next=='&') {
						if(rep_next-rep_cur)
							str_append(&tmp,rep_cur,rep_next-rep_cur);
						str_append(&tmp,line.text+regs.start[0],regs.end[0]-regs.start[0]);
						rep_cur=rep_next+1;
					} else if(*rep_next=='\\') {
						if(rep_next-rep_cur)
							str_append(&tmp,rep_cur,rep_next-rep_cur);
						rep_next++;
						if(rep_next!=rep_end) {
							int n;

							if(*rep_next>='0' && *rep_next<='9') {
								n= *rep_next -'0';
								str_append(&tmp,line.text+regs.start[n],regs.end[n]-regs.start[n]);
							} else
								str_append(&tmp,rep_next,1);
						}
						rep_cur=rep_next+1;
					}
				}
				if(rep_next-rep_cur)
					str_append(&tmp,rep_cur,rep_next-rep_cur);
				if (offset == regs.end[0]) {
					str_append(&tmp, line.text + offset, 1);
					++regs.end[0];
				}
				start = regs.end[0];

				remain = (line.length-1) - start;
				if(remain<0)
					break;
				if(!(cur_cmd->x.cmd_regex.flags&S_GLOBAL_BIT))
					break;
			}
			if(!count)
				break;
			replaced=1;
			str_append(&tmp,line.text+start,remain+1);
			t.text=line.text;
			t.length=line.length;
			t.alloc=line.alloc;
			line.text=tmp.text;
			line.length=tmp.length;
			line.alloc=tmp.alloc;
			tmp.text=t.text;
			tmp.length=t.length;
			tmp.alloc=t.alloc;
			if(cur_cmd->x.cmd_regex.flags&S_WRITE_BIT)
				ck_fwrite(line.text,1,line.length,cur_cmd->x.cmd_regex.wio_file);
			if(cur_cmd->x.cmd_regex.flags&S_PRINT_BIT)
				ck_fwrite(line.text,1,line.length,stdout);
			break;

		case 't':
			if(replaced) {
				replaced = 0;
				if(!cur_cmd->x.jump)
					end_cycle++;
				else {
					struct sed_label *j = cur_cmd->x.jump;

					n= j->v->v_length - j->v_index;
					cur_cmd= j->v->v + j->v_index;
					goto exe_loop;
				}
			}
			break;

		case 'w':
			ck_fwrite(line.text,1,line.length,cur_cmd->x.io_file);
			break;

		case 'x':
			{
				struct line tmp;

				tmp=line;
				line=hold;
				hold=tmp;
			}
			break;

		case 'y':
			{
				unsigned char *p,*e;

				for(p=(unsigned char *)(line.text),e=p+line.length;p<e;p++)
					*p=cur_cmd->x.translate[*p];
			}
			break;

		default:
			panic("INTERNAL ERROR: Bad cmd %c",cur_cmd->cmd);
		}
		if(end_cycle)
			break;
	}
}


/* Return non-zero if the current line matches the address
   pointed to by 'addr'. */
int
match_address(addr)
struct addr *addr;
{
	switch(addr->addr_type) {
	case ADDR_NULL:
		return 1;
	case ADDR_NUM:
		return (input_line_number==addr->addr_number);

	case ADDR_REGEX:
		return (re_search(addr->addr_regex,
				  line.text,
				  line.length-1,
				  0,
				  line.length-1,
				  (struct re_registers *)0)>=0) ? 1 : 0;

	case ADDR_LAST:
		return (input_EOF) ? 1 : 0;

	default:
		panic("INTERNAL ERROR: bad address type");
		break;
	}
	return -1;
}

/* Read in the next line of input, and store it in the
   pattern space.  Return non-zero if this is the last line of input */

int
read_pattern_space()
{
	int n;
	char *p;
	int ch;

	p=line.text;
	n=line.alloc;

	if(feof(input_file))
		return 0;
	input_line_number++;
	replaced=0;
	for(;;) {
		if(n==0) {
			line.text=ck_realloc(line.text,line.alloc*2);
			p=line.text+line.alloc;
			n=line.alloc;
			line.alloc*=2;
		}
		ch=getc(input_file);
		if(ch==EOF) {
			if(n==line.alloc)
				return 0;
			*p++='\n';
			--n;
			line.length=line.alloc-n;
			if(last_input_file)
				input_EOF++;
			return 1;
		}
		*p++=ch;
		--n;
		if(ch=='\n') {
			line.length=line.alloc-n;
			break;
		}
	}
	ch=getc(input_file);
	if(ch!=EOF)
		ungetc(ch,input_file);
	else if(last_input_file)
		input_EOF++;
	return 1;
}

/* Inplement the 'N' command, which appends the next line of input to
   the pattern space. */
void
append_pattern_space()
{
	char *p;
	int n;
	int ch;

	p=line.text+line.length;
	n=line.alloc-line.length;

	input_line_number++;
	replaced=0;
	for(;;) {
		ch=getc(input_file);
		if(ch==EOF) {
			if(n==line.alloc)
				return;
			*p++='\n';
			--n;
			line.length=line.alloc-n;
			if(last_input_file)
				input_EOF++;
			return;
		}
		*p++=ch;
		--n;
		if(ch=='\n') {
			line.length=line.alloc-n;
			break;
		}
		if(n==0) {
			line.text=ck_realloc(line.text,line.alloc*2);
			p=line.text+line.alloc;
			n=line.alloc;
			line.alloc*=2;
		}
	}
	ch=getc(input_file);
	if(ch!=EOF)
		ungetc(ch,input_file);
	else if(last_input_file)
		input_EOF++;
}

/* Copy the contents of the line 'from' into the line 'to'.
   This destroys the old contents of 'to'.  It will still work
   if the line 'from' contains nulls. */
void
line_copy(from,to)
struct line *from,*to;
{
	if(from->length>to->alloc) {
		to->alloc=from->length;
		to->text=ck_realloc(to->text,to->alloc);
	}
	bcopy(from->text,to->text,from->length);
	to->length=from->length;
}

/* Append the contents of the line 'from' to the line 'to'.
   This routine will work even if the line 'from' contains nulls */
void
line_append(from,to)
struct line *from,*to;
{
	if(from->length>(to->alloc-to->length)) {
		to->alloc+=from->length;
		to->text=ck_realloc(to->text,to->alloc);
	}
	bcopy(from->text,to->text+to->length,from->length);
	to->length+=from->length;
}

/* Append 'length' bytes from 'string' to the line 'to'
   This routine *will* append bytes with nulls in them, without
   failing. */
void
str_append(to,string,length)
struct line *to;
char *string;
int length;
{
	if(length>to->alloc-to->length) {
		to->alloc+=length;
		to->text=ck_realloc(to->text,to->alloc);
	}
	bcopy(string,to->text+to->length,length);
	to->length+=length;
}

void
usage()
{
	fprintf(stderr, "\
Usage: %s [-nV] [+quiet] [+silent] [+version] [-e script] [-f script-file]\n\
       [+expression=script] [+file=script-file] [file...]\n", myname);
	exit(4);
}


#ifdef	WINDOWSNT
/*
 * a hack of yet another un*xism so that GNU stuff runs on Windows NT(tm)
 */

int
access(filename, mode)
char	*filename;
int	mode;
{
	HFILE	h;
	OFSTRUCT	o;

	if (!mode) {
		/*
		 * test for existence with OpenFile
		 */

		h = OpenFile(filename, &o, OF_EXIST);

		// what do we expect h to be?

		// will this test fail if the file exists but the caller is
		// not allowed any access to it?

		return -1;
	}

	if (mode & 4) {
		/*
		 * check read access if we need to
		 */

		h = OpenFile(filename, &o, OF_READ);

		if (h == HFILE_ERROR) {
			errno = EACCES;

			return -1;
		}
	}

	if (mode & 2) {
		/*
		 * check write access if we need to
		 */

		h = OpenFile(filename, &o, OF_WRITE);

		if (h == HFILE_ERROR) {
			errno = EACCES;

			return -1;
		}
	}

	if (mode & 1) {
		/*
		 * we're hosed; I don't know an easy way to test for this.
		 */

		// sorry...

		return -1;
	}
}
#endif

⌨️ 快捷键说明

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