📄 sed.c
字号:
}}static int substitute(ipc)/* Perform s command */sedcmd *ipc; /* ptr to s command struct */{ int nullmatch; if (match(ipc->u.lhs, 0)) { /* if no match */ nullmatch = (loc1 == loc2); dosub(ipc->rhs); /* perform it once */ } else return(FALSE); /* command fails */ if (ipc->flags.global) /* if global flag enabled */ while (*loc2) { /* cycle through possibles */ if (nullmatch) loc2++; if (match(ipc->u.lhs, 1)) { /* found another */ nullmatch = (loc1 == loc2); dosub(ipc->rhs); /* so substitute */ } else /* otherwise, */ break; /* we're done */ } return(TRUE); /* we succeeded */}static void dosub(rhsbuf) /* uses linebuf, genbuf, spend */ /* Generate substituted right-hand side (of s command) */char *rhsbuf; /* where to put the result */{ register char *lp, *sp, *rp; int c; /* Copy linebuf to genbuf up to location 1 */ lp = linebuf; sp = genbuf; while (lp < loc1) *sp++ = *lp++; for (rp = rhsbuf; c = *rp++;) { if (c == '&') { sp = place(sp, loc1, loc2); continue; } else if (c & 0200 && (c &= 0177) >= '1' && c < MAXTAGS + '1') { sp = place(sp, brastart[c - '1'], bracend[c - '1']); continue; } *sp++ = c & 0177; if (sp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG); } lp = loc2; loc2 = sp - genbuf + linebuf; while (*sp++ = *lp++) if (sp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG); lp = linebuf; sp = genbuf; while (*lp++ = *sp++); spend = lp - 1;}static char *place(asp, al1, al2) /* uses genbuf */ /* Place chars at *al1...*(al1 - 1) at asp... in genbuf[] */register char *asp, *al1, *al2;{ while (al1 < al2) { *asp++ = *al1++; if (asp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG); } return(asp);}static void listto(p1, fp)/* Write a hex dump expansion of *p1... to fp */register char *p1; /* the source */FILE *fp; /* output stream to write to */{ p1--; while (*p1++) if (isprint(*p1)) putc(*p1, fp); /* pass it through */ else { putc('\\', fp); /* emit a backslash */ switch (*p1) { case '\b': putc('b', fp); break; /* BS */ case '\t': putc('t', fp); break; /* TAB */ case '\n': putc('n', fp); break; /* NL */ case '\r': putc('r', fp); break; /* CR */ case '\33': putc('e', fp); break; /* ESC */ default: fprintf(fp, "%02x", *p1 & 0xFF); } } putc('\n', fp);}static void truncated(h)int h;{ static long last = 0L; if (lnum == last) return; last = lnum; fprintf(stderr, "sed: "); fprintf(stderr, h ? "hold space" : "line %ld", lnum); fprintf(stderr, " truncated to %d characters\n", MAXBUF);}static void command(ipc)/* Execute compiled command pointed at by ipc */sedcmd *ipc;{ static char holdsp[MAXHOLD + 1]; /* the hold space */ static char *hspend = holdsp; /* hold space end pointer */ register char *p1, *p2; char *execp; int didsub; /* true if last s succeeded */ switch (ipc->command) { case ACMD: /* append */ *aptr++ = ipc; if (aptr >= appends + MAXAPPENDS) fprintf(stderr, "sed: too many appends after line %ld\n", lnum); *aptr = 0; break; case CCMD: /* change pattern space */ delete = TRUE; if (!ipc->flags.inrange || lastline) printf("%s\n", ipc->u.lhs); break; case DCMD: /* delete pattern space */ delete++; break; case CDCMD: /* delete a line in hold space */ p1 = p2 = linebuf; while (*p1 != '\n') if (delete = (*p1++ == 0)) return; p1++; while (*p2++ = *p1++) continue; spend = p2 - 1; jump++; break; case EQCMD: /* show current line number */ fprintf(stdout, "%ld\n", lnum); break; case GCMD: /* copy hold space to pattern space */ p1 = linebuf; p2 = holdsp; while (*p1++ = *p2++); spend = p1 - 1; break; case CGCMD: /* append hold space to pattern space */ *spend++ = '\n'; p1 = spend; p2 = holdsp; do if (p1 > linebuf + MAXBUF) { truncated(0); p1[-1] = 0; break; } while (*p1++ = *p2++); spend = p1 - 1; break; case HCMD: /* copy pattern space to hold space */ p1 = holdsp; p2 = linebuf; while (*p1++ = *p2++); hspend = p1 - 1; break; case CHCMD: /* append pattern space to hold space */ *hspend++ = '\n'; p1 = hspend; p2 = linebuf; do if (p1 > holdsp + MAXBUF) { truncated(1); p1[-1] = 0; break; } while (*p1++ = *p2++); hspend = p1 - 1; break; case ICMD: /* insert text */ printf("%s\n", ipc->u.lhs); break; case BCMD: /* branch to label */ jump = TRUE; break; case LCMD: /* list text */ listto(linebuf, (ipc->fout != NULL) ? ipc->fout : stdout); break; case NCMD: /* read next line into pattern space */ if (!nflag) puts(linebuf); /* flush out the current line */ if (aptr > appends) readout(); /* do pending a, r commands */ if ((execp = getline(linebuf)) == BAD) { delete = TRUE; break; } spend = execp; anysub = FALSE; break; case CNCMD: /* append next line to pattern space */ if (aptr > appends) readout(); *spend++ = '\n'; if ((execp = getline(spend)) == BAD) { *--spend = 0; break; } spend = execp; anysub = FALSE; break; case PCMD: /* print pattern space */ puts(linebuf); break; case CPCMD: /* print one line from pattern space */cpcom: /* so s command can jump here */ for (p1 = linebuf; *p1 != '\n' && *p1 != '\0';) putc(*p1++, stdout); putc('\n', stdout); break; case QCMD: /* quit the stream editor */ if (!nflag) puts(linebuf); /* flush out the current line */ if (aptr > appends) readout(); /* do any pending a and r commands */ quit(0); case RCMD: /* read a file into the stream */ *aptr++ = ipc; if (aptr >= appends + MAXAPPENDS) fprintf(stderr, "sed: too many reads after line %ld\n", lnum); *aptr = 0; break; case SCMD: /* substitute RE */ didsub = substitute(ipc); if (didsub) anysub = TRUE; if (ipc->flags.print && didsub) if (ipc->flags.print == TRUE) puts(linebuf); else goto cpcom; if (didsub && ipc->fout) fprintf(ipc->fout, "%s\n", linebuf); break; case TCMD: /* branch on any s successful */ case CTCMD: /* branch on any s failed */ if (anysub == (ipc->command == CTCMD)) break; /* no branch if any s failed, else */ anysub = FALSE; jump = TRUE; /* set up to jump to assoc'd label */ break; case CWCMD: /* write one line from pattern space */ for (p1 = linebuf; *p1 != '\n' && *p1 != '\0';) putc(*p1++, ipc->fout); putc('\n', ipc->fout); break; case WCMD: /* write pattern space to file */ fprintf(ipc->fout, "%s\n", linebuf); break; case XCMD: /* exchange pattern and hold spaces */ p1 = linebuf; p2 = genbuf; while (*p2++ = *p1++) continue; p1 = holdsp; p2 = linebuf; while (*p2++ = *p1++) continue; spend = p2 - 1; p1 = genbuf; p2 = holdsp; while (*p2++ = *p1++) continue; hspend = p2 - 1; break; case YCMD: p1 = linebuf; p2 = ipc->u.lhs; while (*p1 = p2[*p1]) p1++; break; }}static void openfile(file)char *file;/* Replace stdin by given file */{ if (freopen(file, "r", stdin) == NULL) { fprintf(stderr, "sed: can't open %s\n", file); quit(1); }}static int c; /* Will be the next char to read, a kind of * lookahead */static void get()/* Read next character into c treating all argument files as run through cat */{ while ((c = getchar()) == EOF && --eargc >= 0) openfile(*eargv++);}static void initget()/* Initialise character input */{ if (--eargc >= 0) openfile(*eargv++); /* else input == stdin */ get();}static char *getline(buf)/* Get next line of text to be edited, return pointer to end */register char *buf; /* where to send the input */{ if (c == EOF) return BAD; lnum++; /* we can read a new line */ do { if (c == '\n') { get(); break; } if (buf <= linebuf + MAXBUF) *buf++ = c; get(); } while (c != EOF); if (c == EOF) lastline = TRUE; if (buf > linebuf + MAXBUF) { truncated(0); --buf; } *buf = 0; return buf;}static int Memcmp(a, b, count)/* Return TRUE if *a... == *b... for count chars, FALSE otherwise */register char *a, *b;int count;{ while (count--) /* look at count characters */ if (*a++ != *b++) /* if any are nonequal */ return(FALSE); /* return FALSE for false */ return(TRUE); /* compare succeeded */}static void readout()/* Write file indicated by r command to output */{ register int t; /* hold input char or EOF */ FILE *fi; /* ptr to file to be read */ aptr = appends - 1; /* arrange for pre-increment to work right */ while (*++aptr) if ((*aptr)->command == ACMD) /* process "a" cmd */ printf("%s\n", (*aptr)->u.lhs); else { /* process "r" cmd */ if ((fi = fopen((*aptr)->u.lhs, "r")) == NULL) { fprintf(stderr, "sed: can't open %s\n", (*aptr)->u.lhs); continue; } while ((t = getc(fi)) != EOF) putc((char) t, stdout); fclose(fi); } aptr = appends; /* reset the append ptr */ *aptr = 0;}/* Sedexec.c ends here */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -