Heirloom sed0.c
von Meillo- SNIPPET_TEXT:
-
- /* from Unix 7th Edition sed */
- /* Sccsid @(#)sed0.c 1.64 (gritter) 3/12/05> */
- /*
- * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * Redistributions of source code and documentation must retain the
- * above copyright notice, this list of conditions and the following
- * disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed or owned by Caldera
- * International, Inc.
- * Neither the name of Caldera International, Inc. nor the names of
- * other contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
- * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
- * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <unistd.h>
- #include <stdlib.h>
- #include <locale.h>
- #include <libgen.h>
- #include <stdarg.h>
- #include <wchar.h>
- #include "sed.h"
- int ABUFSIZE;
- struct reptr **abuf;
- int aptr;
- char *genbuf;
- int gbend;
- int lbend;
- int hend;
- char *linebuf;
- char *holdsp;
- int nflag;
- long long *tlno;
- char *cp;
- int status;
- int multibyte;
- int invchar;
- int needdol;
- int eargc;
- struct reptr *ptrspace;
- struct reptr *pending;
- char *badp;
- static const char CGMES[] = "\1command garbled: %s";
- static const char TMMES[] = "Too much text: %s";
- static const char LTL[] = "Label too long: %s";
- static const char LINTL[] = "line too long";
- static const char AD0MES[] = "No addresses allowed: %s";
- static const char AD1MES[] = "Only one address allowed: %s";
- static FILE **fcode;
- static FILE *fin;
- static char *lastre;
- static wchar_t sed_seof;
- static int PTRSIZE;
- static int eflag;
- static int gflag;
- static int nlno;
- static char **fname;
- static int nfiles;
- static int rep;
- static struct label *ltab;
- static int lab;
- static size_t LABSIZE;
- static int labtab = 1;
- static int depth;
- static char **eargv;
- static int *cmpend;
- static size_t DEPTH;
- static char bad;
- static char compfl;
- static char *progname;
- static char *(*ycomp)(char **);
- static int executing;
- static void fcomp(void);
- static char *compsub(char **, char *);
- static int rline(void);
- static char *address(char **);
- static int cmp(const char *, const char *);
- static void text(char **);
- static int search(struct label *);
- static void dechain(void);
- static char *ycomp_sb(char **);
- static char *ycomp_mb(char **);
- static void lab_inc(void);
- static void rep_inc(void);
- static void depth_check(void);
- static void *srealloc(void *, size_t);
- static void *scalloc(size_t, size_t);
- static char *sed_compile(char **);
- static void wfile(void);
- static void morefiles(void);
- static char *null;
- #define check(p, buf, sz, incr, op) \
- if (&p[1] >= &(buf)[sz]) { \
- size_t ppos = p - buf; \
- size_t opos = op - buf; \
- buf = srealloc(buf, (sz += incr) * sizeof *(buf)); \
- p = &(buf)[ppos]; \
- if (op != NULL) \
- op = &(buf)[opos]; \
- }
- int
- main(int argc, char **argv)
- {
- int c;
- const char optstr[] = "nf:e:g";
- sed = 1;
- progname = basename(argv[0]);
- eargc = argc;
- eargv = argv;
- #ifdef __GLIBC__
- putenv("POSIXLY_CORRECT=1");
- #endif /* __GLIBC__ */
- #if defined (SUS) || defined (SU3) || defined (S42)
- setlocale(LC_COLLATE, "");
- #endif /* SUS || SU3 || S42 */
- setlocale(LC_CTYPE, "");
- multibyte = MB_CUR_MAX > 1;
- ycomp = multibyte ? ycomp_mb : ycomp_sb;
- badp = &bad;
- aptr_inc();
- lab_inc();
- lab_inc(); /* 0 reserved for end-pointer -> labtab = 1 */
- growsp(NULL);
- rep_inc();
- pending = 0;
- depth = 0;
- morefiles();
- fcode[0] = stdout;
- nfiles = 1;
- morefiles();
- if(eargc == 1)
- exit(0);
- while ((c = getopt(eargc, eargv, optstr)) != EOF) {
- switch (c) {
- case 'n':
- nflag++;
- continue;
- case 'f':
- if((fin = fopen(optarg, "r")) == NULL)
- fatal("Cannot open pattern-file: %s", optarg);
- fcomp();
- fclose(fin);
- continue;
- case 'e':
- eflag++;
- fcomp();
- eflag = 0;
- continue;
- case 'g':
- gflag++;
- continue;
- default:
- exit(2);
- }
- }
- eargv += optind, eargc -= optind;
- if(compfl == 0 && *eargv) {
- optarg = *eargv++;
- eargc--;
- eflag++;
- fcomp();
- eflag = 0;
- }
- if(depth)
- fatal("Too many {'s");
- L(labtab)->address = rep;
- dechain();
- /* abort(); */ /*DEBUG*/
- executing++;
- if(eargc <= 0)
- execute((char *)NULL);
- else while(--eargc >= 0) {
- execute(*eargv++);
- }
- fclose(stdout);
- return status;
- }
- static void
- fcomp(void)
- {
- register char *op, *tp, *q;
- int pt, pt1;
- int lpt;
- compfl = 1;
- op = lastre;
- if(rline() < 0) return;
- if(*linebuf == '#') {
- if(linebuf[1] == 'n')
- nflag = 1;
- }
- else {
- cp = linebuf;
- goto comploop;
- }
- for(;;) {
- if(rline() < 0) break;
- cp = linebuf;
- comploop:
- /* fprintf(stdout, "cp: %s\n", cp); */ /*DEBUG*/
- while(*cp == ' ' || *cp == '\t') cp++;
- if(*cp == '\0' || *cp == '#') continue;
- if(*cp == ';') {
- cp++;
- goto comploop;
- }
- q = address(&P(rep)->ad1);
- if(q == badp)
- fatal(CGMES, linebuf);
- if(q != 0 && q == P(rep)->ad1) {
- if(op)
- P(rep)->ad1 = op;
- else
- fatal("First RE may not be null");
- } else if(q == 0) {
- P(rep)->ad1 = 0;
- } else {
- op = P(rep)->ad1;
- if(*cp == ',' || *cp == ';') {
- cp++;
- q = address(&P(rep)->ad2);
- if(q == badp || q == 0)
- fatal(CGMES, linebuf);
- if(q == P(rep)->ad2)
- P(rep)->ad2 = op;
- else
- op = P(rep)->ad2;
- } else
- P(rep)->ad2 = 0;
- }
- while(*cp == ' ' || *cp == '\t') cp++;
- swit:
- switch(*cp++) {
- default:
- fatal("Unrecognized command: %s", linebuf);
- /*NOTREACHED*/
- case '!':
- P(rep)->negfl = 1;
- goto swit;
- case '{':
- P(rep)->command = BCOM;
- P(rep)->negfl = !(P(rep)->negfl);
- depth_check();
- cmpend[depth++] = rep;
- rep_inc();
- if(*cp == '\0') continue;
- goto comploop;
- case '}':
- if(P(rep)->ad1)
- fatal(AD0MES, linebuf);
- if(--depth < 0)
- fatal("Too many }'s");
- P(cmpend[depth])->bptr.lb1 = rep;
- continue;
- case '=':
- P(rep)->command = EQCOM;
- if(P(rep)->ad2)
- fatal(AD1MES, linebuf);
- break;
- case ':':
- if(P(rep)->ad1)
- fatal(AD0MES, linebuf);
- while(*cp++ == ' ');
- cp--;
- tp = L(lab)->asc;
- while((*tp++ = *cp++))
- if(tp >= &(L(lab)->asc[sizeof
- L(lab)->asc]))
- fatal(LTL, linebuf);
- *--tp = '\0';
- if(lpt = search(L(lab))) {
- if(L(lpt)->address)
- fatal("Duplicate labels: %s",
- linebuf);
- } else {
- L(lab)->chain = 0;
- lpt = lab;
- lab_inc();
- }
- L(lpt)->address = rep;
- continue;
- case 'a':
- P(rep)->command = ACOM;
- if(P(rep)->ad2)
- fatal(AD1MES, linebuf);
- if(*cp == '\\') cp++;
- if(*cp++ != '\n')
- fatal(CGMES, linebuf);
- text(&P(rep)->bptr.re1);
- break;
- case 'c':
- P(rep)->command = CCOM;
- if(*cp == '\\') cp++;
- if(*cp++ != ('\n'))
- fatal(CGMES, linebuf);
- text(&P(rep)->bptr.re1);
- needdol = 1;
- break;
- case 'i':
- P(rep)->command = ICOM;
- if(P(rep)->ad2)
- fatal(AD1MES, linebuf);
- if(*cp == '\\') cp++;
- if(*cp++ != ('\n'))
- fatal(CGMES, linebuf);
- text(&P(rep)->bptr.re1);
- break;
- case 'g':
- P(rep)->command = GCOM;
- break;
- case 'G':
- P(rep)->command = CGCOM;
- break;
- case 'h':
- P(rep)->command = HCOM;
- break;
- case 'H':
- P(rep)->command = CHCOM;
- break;
- case 't':
- P(rep)->command = TCOM;
- goto jtcommon;
- case 'b':
- P(rep)->command = BCOM;
- jtcommon:
- while(*cp++ == ' ');
- cp--;
- if(*cp == '\0') {
- if((pt = L(labtab)->chain) != 0) {
- while((pt1 = P(pt)->bptr.lb1) != 0)
- pt = pt1;
- P(pt)->bptr.lb1 = rep;
- } else
- L(labtab)->chain = rep;
- break;
- }
- tp = L(lab)->asc;
- while((*tp++ = *cp++))
- if(tp >= &(L(lab)->asc[sizeof
- L(lab)->asc]))
- fatal(LTL, linebuf);
- cp--;
- *--tp = '\0';
- if(lpt = search(L(lab))) {
- if(L(lpt)->address) {
- P(rep)->bptr.lb1 = L(lpt)->address;
- } else {
- pt = L(lpt)->chain;
- while((pt1 = P(pt)->bptr.lb1) != 0)
- pt = pt1;
- P(pt)->bptr.lb1 = rep;
- }
- } else {
- L(lab)->chain = rep;
- L(lab)->address = 0;
- lab_inc();
- }
- break;
- case 'n':
- P(rep)->command = NCOM;
- break;
- case 'N':
- P(rep)->command = CNCOM;
- break;
- case 'p':
- P(rep)->command = PCOM;
- break;
- case 'P':
- P(rep)->command = CPCOM;
- break;
- case 'r':
- P(rep)->command = RCOM;
- if(P(rep)->ad2)
- fatal(AD1MES, linebuf);
- #if !defined (SUS) && !defined (SU3)
- if(*cp++ != ' ')
- fatal(CGMES, linebuf);
- #else /* SUS, SU3 */
- while (*cp == ' ' || *cp == '\t')
- cp++;
- #endif /* SUS, SU3 */
- text(&P(rep)->bptr.re1);
- break;
- case 'd':
- P(rep)->command = DCOM;
- break;
- case 'D':
- P(rep)->command = CDCOM;
- P(rep)->bptr.lb1 = 1;
- break;
- case 'q':
- P(rep)->command = QCOM;
- if(P(rep)->ad2)
- fatal(AD1MES, linebuf);
- break;
- case 'l':
- P(rep)->command = LCOM;
- break;
- case 's':
- P(rep)->command = SCOM;
- sed_seof = fetch(&cp);
- q = sed_compile(&P(rep)->bptr.re1);
- if(q == badp)
- fatal(CGMES, linebuf);
- if(q == P(rep)->bptr.re1) {
- if (op == NULL)
- fatal("First RE may not be null");
- P(rep)->bptr.re1 = op;
- } else {
- op = P(rep)->bptr.re1;
- }
- if(compsub(&P(rep)->rhs, &P(rep)->nsub) == badp)
- fatal(CGMES, linebuf);
- sloop: if(*cp == 'g') {
- cp++;
- P(rep)->gfl = -1;
- goto sloop;
- } else if(gflag)
- P(rep)->gfl = -1;
- if (*cp >= '0' && *cp <= '9') {
- while (*cp >= '0' && *cp <= '9') {
- if (P(rep)->gfl == -1)
- P(rep)->gfl = 0;
- P(rep)->gfl = P(rep)->gfl * 10
- + *cp++ - '0';
- }
- goto sloop;
- }
- #if !defined (SUS) && !defined (SU3)
- if (P(rep)->gfl > 0 && P(rep)->gfl > 512)
- fatal("Suffix too large - 512 max: %s", linebuf);
- #endif
- if(*cp == 'p') {
- cp++;
- P(rep)->pfl = 1;
- goto sloop;
- }
- if(*cp == 'P') {
- cp++;
- P(rep)->pfl = 2;
- goto sloop;
- }
- if(*cp == 'w') {
- cp++;
- wfile();
- }
- break;
- case 'w':
- P(rep)->command = WCOM;
- wfile();
- break;
- case 'x':
- P(rep)->command = XCOM;
- break;
- case 'y':
- P(rep)->command = YCOM;
- sed_seof = fetch(&cp);
- if (ycomp(&P(rep)->bptr.re1) == badp)
- fatal(CGMES, linebuf);
- break;
- }
- rep_inc();
- if(*cp++ != '\0') {
- if(cp[-1] == ';')
- goto comploop;
- fatal(CGMES, linebuf);
- }
- }
- P(rep)->command = 0;
- lastre = op;
- }
- static char *
- compsub(char **rhsbuf, char *nsubp)
- {
- register char *p, *op, *oq;
- char *q;
- wint_t c;
- size_t sz = 32;
- *rhsbuf = smalloc(sz);
- p = *rhsbuf;
- q = cp;
- *nsubp = 0;
- for(;;) {
- op = p;
- oq = q;
- if((c = fetch(&q)) == '\\') {
- check(p, *rhsbuf, sz, 32, op)
- *p = '\\';
- oq = q;
- c = fetch(&q);
- do {
- check(p, *rhsbuf, sz, 32, op)
- *++p = *oq++;
- } while (oq < q);
- if(c > nbra + '0' && c <= '9')
- return(badp);
- if (c > *nsubp + '0' && c <= '9')
- *nsubp = c - '0';
- check(p, *rhsbuf, sz, 32, op)
- p++;
- continue;
- } else {
- do {
- check(p, *rhsbuf, sz, 32, op)
- *p++ = *oq++;
- } while (oq < q);
- p--;
- }
- if(c == sed_seof) {
- check(p, *rhsbuf, sz, 32, op)
- *op++ = '\0';
- cp = q;
- return(op);
- }
- check(p, *rhsbuf, sz, 32, op)
- if(*p++ == '\0') {
- return(badp);
- }
- }
- }
- #define rlinechk() if (c >= lbend-2) \
- growsp(LINTL)
- static int
- rline(void)
- {
- register char *q;
- register int c;
- register int t;
- static char *saveq;
- c = -1;
- if(eflag) {
- if(eflag > 0) {
- eflag = -1;
- q = optarg;
- rlinechk();
- while(linebuf[++c] = *q++) {
- rlinechk();
- if(linebuf[c] == '\\') {
- if((linebuf[++c] = *q++) == '\0') {
- rlinechk();
- saveq = 0;
- return(-1);
- } else
- continue;
- }
- if(linebuf[c] == '\n') {
- linebuf[c] = '\0';
- saveq = q;
- return(1);
- }
- }
- saveq = 0;
- return(1);
- }
- if((q = saveq) == 0) return(-1);
- while(linebuf[++c] = *q++) {
- rlinechk();
- if(linebuf[c] == '\\') {
- if((linebuf[++c] = *q++) == '0') {
- rlinechk();
- saveq = 0;
- return(-1);
- } else
- continue;
- }
- if(linebuf[c] == '\n') {
- linebuf[c] = '\0';
- saveq = q;
- return(1);
- }
- }
- saveq = 0;
- return(1);
- }
- while((t = getc(fin)) != EOF) {
- rlinechk();
- linebuf[++c] = (char)t;
- if(linebuf[c] == '\\') {
- t = getc(fin);
- rlinechk();
- linebuf[++c] = (char)t;
- }
- else if(linebuf[c] == '\n') {
- linebuf[c] = '\0';
- return(1);
- }
- }
- linebuf[++c] = '\0';
- return(-1);
- }
- static char *
- address(char **expbuf)
- {
- register char *rcp, *ep;
- long long lno;
- *expbuf = NULL;
- if(*cp == '$') {
- cp++;
- ep = *expbuf = smalloc(2 * sizeof *expbuf);
- *ep++ = CEND;
- *ep++ = ceof;
- needdol = 1;
- return(ep);
- }
- if(*cp == '/' || *cp == '\\') {
- if (*cp == '\\')
- cp++;
- sed_seof = fetch(&cp);
- return(sed_compile(expbuf));
- }
- rcp = cp;
- lno = 0;
- while(*rcp >= '0' && *rcp <= '9')
- lno = lno*10 + *rcp++ - '0';
- if(rcp > cp) {
- if (nlno > 020000000000 ||
- (tlno = realloc(tlno, (nlno+1)*sizeof *tlno)) == NULL)
- fatal("Too many line numbers");
- ep = *expbuf = smalloc(6 * sizeof *expbuf);
- *ep++ = CLNUM;
- slno(ep, nlno);
- tlno[nlno++] = lno;
- *ep++ = ceof;
- cp = rcp;
- return(ep);
- }
- return(0);
- }
- static int
- cmp(const char *a, const char *b)
- {
- register const char *ra, *rb;
- ra = a - 1;
- rb = b - 1;
- while(*++ra == *++rb)
- if(*ra == '\0') return(0);
- return(1);
- }
- static void
- text(char **textbuf)
- {
- register char *p, *oq;
- char *q;
- size_t sz = 128;
- *textbuf = smalloc(sz);
- p = *textbuf;
- q = cp;
- for(;;) {
- oq = q;
- if(fetch(&q) == '\\') {
- oq = q;
- fetch(&q);
- }
- while(oq < q)
- *p++ = *oq++;
- if(p[-1] == '\0') {
- cp = --q;
- return;
- }
- check(p, *textbuf, sz, 128, null)
- }
- }
- static int
- search(struct label *ptr)
- {
- struct label *rp;
- rp = L(labtab);
- while(rp < ptr) {
- if(cmp(rp->asc, ptr->asc) == 0)
- return(rp - L(labtab) + 1);
- rp++;
- }
- return(0);
- }
- static void
- dechain(void)
- {
- struct label *lptr;
- int rptr, trptr;
- for(lptr = L(labtab); lptr < L(lab); lptr++) {
- if(lptr->address == 0)
- fatal("Undefined label: %s", lptr->asc);
- if(lptr->chain) {
- rptr = lptr->chain;
- while((trptr = P(rptr)->bptr.lb1) != 0) {
- P(rptr)->bptr.lb1 = lptr->address;
- rptr = trptr;
- }
- P(rptr)->bptr.lb1 = lptr->address;
- }
- }
- }
- static char *
- ycomp_sb(char **expbuf)
- {
- register int c, d;
- register char *ep, *tsp;
- char *sp;
- *expbuf = smalloc(0400);
- ep = *expbuf;
- for(c = 0; !(c & 0400); c++)
- ep[c] = '\0';
- sp = cp;
- for(tsp = cp; *tsp != sed_seof; tsp++) {
- if(*tsp == '\\')
- tsp++;
- if(*tsp == '\n' || *tsp == '\0')
- return(badp);
- }
- tsp++;
- while((c = *sp++ & 0377) != sed_seof) {
- if(c == '\\') {
- c = *sp == 'n' ? '\n' : *sp;
- sp++;
- }
- if((ep[c] = d = *tsp++ & 0377) == '\\') {
- ep[c] = *tsp == 'n' ? '\n' : *tsp;
- tsp++;
- }
- if(d != '\\' && ep[c] == sed_seof || ep[c] == '\0')
- return(badp);
- }
- if(*tsp != sed_seof)
- return(badp);
- cp = ++tsp;
- for(c = 0; !(c & 0400); c++)
- if(ep[c] == 0)
- ep[c] = (char)c;
- return(ep + 0400);
- }
- static char *
- ycomp_mb(char **expbuf)
- {
- struct yitem **yt, *yp;
- register wint_t c, d;
- char *otsp, *tsp, *sp, *mp;
- tsp = sp = cp;
- while ((c = fetch(&tsp)) != sed_seof) {
- if (c == '\\')
- c = fetch(&tsp);
- if (c == '\n' || c == '\0')
- return badp;
- }
- yt = scalloc(200, sizeof *yt);
- while ((c = fetch(&sp)) != sed_seof) {
- if (c == '\\') {
- if ((d = fetch(&sp)) == 'n')
- c = '\n';
- else
- c = d;
- }
- otsp = tsp;
- d = fetch(&tsp);
- yp = ylook(c, yt, 1);
- yp->y_oc = c;
- if ((yp->y_yc = d) == '\\') {
- otsp = tsp;
- if ((c = fetch(&tsp)) == 'n')
- yp->y_yc = '\n';
- else
- yp->y_yc = c;
- }
- if (d != '\\' && yp->y_yc == sed_seof || yp->y_yc == '\0')
- return badp;
- mp = yp->y_mc;
- if (yp->y_yc != '\n')
- while (otsp < tsp)
- *mp++ = *otsp++;
- else
- *mp++ = '\n';
- *mp = '\0';
- }
- if (fetch(&tsp) != sed_seof)
- return badp;
- cp = tsp;
- *expbuf = (char *)yt;
- return &(*expbuf)[1];
- }
- static void
- rep_inc(void)
- {
- register char *p;
- const int chunk = 16;
- if (++rep >= PTRSIZE) {
- ptrspace = srealloc(ptrspace,
- (PTRSIZE += chunk) * sizeof *ptrspace);
- for (p = (char *)&ptrspace[PTRSIZE - chunk];
- p < (char *)&ptrspace[PTRSIZE]; p++)
- *p = '\0';
- }
- }
- static void
- lab_inc(void)
- {
- register char *p;
- const int chunk = 8;
- if (++lab >= LABSIZE) {
- ltab = srealloc(ltab, (LABSIZE += chunk) * sizeof *ltab);
- for (p = (char *)<ab[LABSIZE - chunk];
- p < (char *)<ab[LABSIZE]; p++)
- *p = '\0';
- }
- }
- void
- aptr_inc(void)
- {
- register char *p;
- const int chunk = 8;
- if (++aptr > ABUFSIZE) {
- abuf = srealloc(abuf, (ABUFSIZE += chunk) * sizeof *abuf);
- for (p = (char *)&abuf[ABUFSIZE - chunk];
- p < (char *)&abuf[ABUFSIZE]; p++)
- *p = '\0';
- }
- }
- static void
- depth_check(void)
- {
- if (depth + 1 > DEPTH)
- cmpend = srealloc(cmpend, (DEPTH += 8) * sizeof *cmpend);
- }
- void
- nonfatal(const char *afmt, ...)
- {
- va_list ap;
- const char *fmt;
- if (*afmt == '\1') {
- fprintf(stderr, "%s: ", progname);
- fmt = &afmt[1];
- } else
- fmt = afmt;
- va_start(ap, afmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fputc('\n', stderr);
- status |= 1;
- }
- void
- fatal(const char *afmt, ...)
- {
- va_list ap;
- const char *fmt;
- if (*afmt == '\1') {
- fprintf(stderr, "%s: ", progname);
- fmt = &afmt[1];
- } else
- fmt = afmt;
- va_start(ap, afmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fputc('\n', stderr);
- exit(2);
- }
- static void *
- srealloc(void *vp, size_t nbytes)
- {
- void *p;
- if ((p = realloc(vp, nbytes)) == NULL)
- fatal(TMMES, linebuf);
- return p;
- }
- void *
- smalloc(size_t nbytes)
- {
- return srealloc(NULL, nbytes);
- }
- static void *
- scalloc(size_t nmemb, size_t size)
- {
- void *p;
- if ((p = calloc(nmemb, size)) == NULL)
- fatal(TMMES, linebuf);
- return p;
- }
- #if defined (SUS) || defined (SU3) || defined (S42)
- static char *
- sed_compile(char **ep)
- {
- struct re_emu *re;
- static char *pat;
- static size_t patsz;
- register char *p, *oc;
- wint_t c, d;
- if (*cp != sed_seof)
- nbra = 0;
- if (patsz == 0)
- pat = smalloc(patsz = 32);
- p = pat;
- do {
- oc = cp;
- if ((c = fetch(&cp)) == sed_seof)
- *p = '\0';
- else if (c == '\\') {
- oc = cp;
- if ((c = fetch(&cp)) == 'n')
- *p = '\n';
- else {
- check(p, pat, patsz, 32, null);
- *p++ = '\\';
- if (c == '(')
- nbra++;
- goto normchar;
- }
- } else if (c == '[') {
- check(p, pat, patsz, 32, null);
- *p++ = c;
- d = WEOF;
- do {
- oc = cp;
- c = fetch(&cp);
- if (c == '\0')
- goto normchar;
- do {
- check(p, pat, patsz, 32, null);
- *p++ = *oc++;
- } while (oc < cp);
- if (d == '[' && (c == ':' || c == '.' ||
- c == '=')) {
- d = c;
- do {
- oc = cp;
- c = fetch(&cp);
- if (c == '\0')
- goto normchar;
- do {
- check(p, pat, patsz,32,
- null);
- *p++ = *oc++;
- } while (oc < cp);
- } while (c != d || peek(&cp) != ']');
- oc = cp;
- c = fetch(&cp);
- do {
- check(p, pat, patsz, 32, null);
- *p++ = *oc++;
- } while (oc < cp);
- c = WEOF; /* == reset d and continue */
- }
- d = c;
- } while (c != ']');
- p--;
- } else {
- normchar: do {
- check(p, pat, patsz, 32, null)
- *p++ = *oc++;
- } while (oc < cp);
- p--;
- }
- check(p, pat, patsz, 32, null);
- } while (*p++ != '\0');
- re = scalloc(1, sizeof *re);
- *ep = (char *)re;
- if (*pat == '^')
- **ep = 1;
- if (*pat != '\0') {
- int reflags = 0;
- #ifdef REG_ANGLES
- reflags |= REG_ANGLES;
- #endif /* REG_ANGLES */
- #if defined (SU3) && defined (REG_AVOIDNULL)
- reflags |= REG_AVOIDNULL;
- #endif /* SU3 && AVOIDNULL */
- if (regcomp(&re->r_preg, pat, reflags) != 0)
- re = (struct re_emu *)badp;
- } else
- **ep = 2;
- p = (char *)re;
- if (p != badp && *pat)
- p++;
- return p;
- }
- #else /* !SUS, !SU3, !S42 */
- static char *
- sed_compile(char **ep)
- {
- extern char *compile(char *, char *, char *, int);
- register char *p;
- size_t sz;
- for (sz = 0, p = cp; *p; p++)
- if (*p == '[')
- sz += 32;
- sz += 2 * (p - cp) + 5;
- *ep = smalloc(sz);
- (*ep)[1] = '\0';
- p = compile(NULL, &(*ep)[1], &(*ep)[sz], sed_seof);
- if (p == &(*ep)[1])
- return *ep;
- **ep = circf;
- return p;
- }
- #endif /* !SUS, !SU3, !S42 */
- wint_t
- wc_get(char **sc, int move)
- {
- wint_t c;
- char *p = *sc;
- wchar_t wcbuf;
- int len;
- if ((*p & 0200) == 0) {
- c = *p;
- p += (len = 1);
- invchar = 0;
- } else if ((len = mbtowc(&wcbuf, p, MB_LEN_MAX)) < 0) {
- if (!executing)
- fatal("invalid multibyte character: %s", p);
- c = (*p++ & 0377);
- mbtowc(NULL, NULL, 0);
- invchar = 1;
- } else if (len == 0) {
- c = '\0';
- p++;
- invchar = 0;
- } else {
- c = wcbuf;
- p += len;
- invchar = 0;
- }
- if (move)
- *sc = p;
- return c;
- }
- /*
- * Note that this hash is not optimized to distribute the items
- * equally to all buckets. y commands typically handle only a
- * small part of the alphabet, thus most characters will have
- * no entry in the hash table. If no list exists in the bucket
- * for the hash of these characters, the function can return
- * quickly.
- */
- #define yhash(c) (c & 0177)
- struct yitem *
- ylook(wint_t c, struct yitem **yt, int make)
- {
- struct yitem *yp;
- int h;
- yp = yt[h = yhash(c)];
- while (yp != NULL) {
- if (yp->y_oc == c)
- break;
- yp = yp->y_nxt;
- }
- if (make && yp == NULL) {
- yp = scalloc(1, sizeof *yp);
- yp->y_oc = c;
- yp->y_nxt = yt[h];
- yt[h] = yp;
- }
- return yp;
- }
- void
- growsp(const char *msg)
- {
- const int incr = 128;
- int olbend, ogbend, ohend;
- olbend = lbend;
- ogbend = gbend;
- ohend = hend;
- if ((linebuf = realloc(linebuf, lbend += incr)) == NULL ||
- (genbuf = realloc(genbuf, gbend += incr)) == NULL ||
- (holdsp = realloc(holdsp, hend += incr)) == NULL)
- fatal(msg ? msg : "Cannot malloc space");
- while (olbend < lbend)
- linebuf[olbend++] = '\0';
- while (ogbend < gbend)
- genbuf[ogbend++] = '\0';
- while (ohend < hend)
- holdsp[ohend++] = '\0';
- }
- static void
- wfile(void)
- {
- int i;
- #if !defined (SUS) && !defined (SU3)
- if(*cp++ != ' ')
- fatal(CGMES, linebuf);
- #else /* SUS, SU3 */
- while (*cp == ' ' || *cp == '\t')
- cp++;
- #endif /* SUS, SU3 */
- text(&fname[nfiles]);
- for(i = nfiles - 1; i >= 0; i--)
- if(fname[i] != NULL && cmp(fname[nfiles], fname[i]) == 0) {
- P(rep)->fcode = fcode[i];
- free(fname[nfiles]);
- return;
- }
- if((P(rep)->fcode = fopen(fname[nfiles], "w")) == NULL)
- fatal("Cannot create %s", fname[nfiles]);
- fcode[nfiles++] = P(rep)->fcode;
- morefiles();
- }
- static void
- morefiles(void)
- {
- if ((fname = realloc(fname, (nfiles+1) * sizeof *fname)) == 0 ||
- (fcode = realloc(fcode, (nfiles+1) * sizeof *fcode)) == 0)
- fatal("Too many files in w commands");
- fname[nfiles] = 0;
- fcode[nfiles] = 0;
- }
Quellcode
Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN