NoPaste

Heirloom sed0.c

von Meillo

Dein Code:
  1. /*      from Unix 7th Edition sed       */
  2. /*      Sccsid @(#)sed0.c       1.64 (gritter) 3/12/05> */
  3. /*
  4.  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *   Redistributions of source code and documentation must retain the
  10.  *    above copyright notice, this list of conditions and the following
  11.  *    disclaimer.
  12.  *   Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  *   All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *      This product includes software developed or owned by Caldera
  18.  *      International, Inc.
  19.  *   Neither the name of Caldera International, Inc. nor the names of
  20.  *    other contributors may be used to endorse or promote products
  21.  *    derived from this software without specific prior written permission.
  22.  *
  23.  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
  24.  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
  25.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
  28.  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  31.  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  32.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  33.  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  34.  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35.  */
  36. #include <unistd.h>
  37. #include <stdlib.h>
  38. #include <locale.h>
  39. #include <libgen.h>
  40. #include <stdarg.h>
  41. #include <wchar.h>
  42. #include "sed.h"
  43.  
  44. int     ABUFSIZE;
  45. struct reptr    **abuf;
  46. int     aptr;
  47. char    *genbuf;
  48. int     gbend;
  49. int     lbend;
  50. int     hend;
  51. char    *linebuf;
  52. char    *holdsp;
  53. int     nflag;
  54. long long       *tlno;
  55. char    *cp;
  56.  
  57. int     status;
  58. int     multibyte;
  59. int     invchar;
  60. int     needdol;
  61.  
  62. int     eargc;
  63.  
  64. struct  reptr *ptrspace;
  65. struct reptr    *pending;
  66. char    *badp;
  67.  
  68. static const char       CGMES[] = "\1command garbled: %s";
  69. static const char       TMMES[] = "Too much text: %s";
  70. static const char       LTL[]   = "Label too long: %s";
  71. static const char       LINTL[] = "line too long";
  72. static const char       AD0MES[]        = "No addresses allowed: %s";
  73. static const char       AD1MES[]        = "Only one address allowed: %s";
  74. static FILE     **fcode;
  75. static FILE     *fin;
  76. static char     *lastre;
  77. static wchar_t  sed_seof;
  78. static int      PTRSIZE;
  79. static int      eflag;
  80. static int      gflag;
  81. static int      nlno;
  82. static char     **fname;
  83. static int      nfiles;
  84. static int      rep;
  85. static struct label  *ltab;
  86. static int      lab;
  87. static size_t   LABSIZE;
  88. static int      labtab = 1;
  89. static int      depth;
  90. static char     **eargv;
  91. static int      *cmpend;
  92. static size_t   DEPTH;
  93. static char     bad;
  94. static char     compfl;
  95. static char     *progname;
  96. static char     *(*ycomp)(char **);
  97. static int      executing;
  98.  
  99. static void fcomp(void);
  100. static char *compsub(char **, char *);
  101. static int rline(void);
  102. static char *address(char **);
  103. static int cmp(const char *, const char *);
  104. static void text(char **);
  105. static int search(struct label *);
  106. static void dechain(void);
  107. static char *ycomp_sb(char **);
  108. static char *ycomp_mb(char **);
  109. static void lab_inc(void);
  110. static void rep_inc(void);
  111. static void depth_check(void);
  112. static void *srealloc(void *, size_t);
  113. static void *scalloc(size_t, size_t);
  114. static char *sed_compile(char **);
  115. static void wfile(void);
  116. static void morefiles(void);
  117.  
  118. static char     *null;
  119. #define check(p, buf, sz, incr, op) \
  120.         if (&p[1] >= &(buf)[sz]) { \
  121.                 size_t ppos = p - buf; \
  122.                 size_t opos = op - buf; \
  123.                 buf = srealloc(buf, (sz += incr) * sizeof *(buf)); \
  124.                 p = &(buf)[ppos]; \
  125.                 if (op != NULL) \
  126.                         op = &(buf)[opos]; \
  127.         }
  128.  
  129. int
  130. main(int argc, char **argv)
  131. {
  132.         int c;
  133.         const char optstr[] = "nf:e:g";
  134.  
  135.         sed = 1;
  136.         progname = basename(argv[0]);
  137.         eargc = argc;
  138.         eargv = argv;
  139.  
  140. #ifdef  __GLIBC__
  141.         putenv("POSIXLY_CORRECT=1");
  142. #endif  /* __GLIBC__ */
  143. #if defined (SUS) || defined (SU3) || defined (S42)
  144.         setlocale(LC_COLLATE, "");
  145. #endif  /* SUS || SU3 || S42 */
  146.         setlocale(LC_CTYPE, "");
  147.         multibyte = MB_CUR_MAX > 1;
  148.         ycomp = multibyte ? ycomp_mb : ycomp_sb;
  149.         badp = &bad;
  150.         aptr_inc();
  151.         lab_inc();
  152.         lab_inc();      /* 0 reserved for end-pointer -> labtab = 1 */
  153.         growsp(NULL);
  154.         rep_inc();
  155.         pending = 0;
  156.         depth = 0;
  157.         morefiles();
  158.         fcode[0] = stdout;
  159.         nfiles = 1;
  160.         morefiles();
  161.  
  162.         if(eargc == 1)
  163.                 exit(0);
  164.         while ((c = getopt(eargc, eargv, optstr)) != EOF) {
  165.                 switch (c) {
  166.                 case 'n':
  167.                         nflag++;
  168.                         continue;
  169.  
  170.                 case 'f':
  171.                         if((fin = fopen(optarg, "r")) == NULL)
  172.                                 fatal("Cannot open pattern-file: %s", optarg);
  173.  
  174.                         fcomp();
  175.                         fclose(fin);
  176.                         continue;
  177.  
  178.                 case 'e':
  179.                         eflag++;
  180.                         fcomp();
  181.                         eflag = 0;
  182.                         continue;
  183.  
  184.                 case 'g':
  185.                         gflag++;
  186.                         continue;
  187.  
  188.                 default:
  189.                         exit(2);
  190.                 }
  191.         }
  192.  
  193.         eargv += optind, eargc -= optind;
  194.  
  195.  
  196.         if(compfl == 0 && *eargv) {
  197.                 optarg = *eargv++;
  198.                 eargc--;
  199.                 eflag++;
  200.                 fcomp();
  201.                 eflag = 0;
  202.         }
  203.  
  204.         if(depth)
  205.                 fatal("Too many {'s");
  206.  
  207.         L(labtab)->address = rep;
  208.  
  209.         dechain();
  210.  
  211. /*      abort();        */      /*DEBUG*/
  212.  
  213.         executing++;
  214.         if(eargc <= 0)
  215.                 execute((char *)NULL);
  216.         else while(--eargc >= 0) {
  217.                 execute(*eargv++);
  218.         }
  219.         fclose(stdout);
  220.         return status;
  221. }
  222.  
  223. static void
  224. fcomp(void)
  225. {
  226.  
  227.         register char   *op, *tp, *q;
  228.         int     pt, pt1;
  229.         int     lpt;
  230.  
  231.         compfl = 1;
  232.         op = lastre;
  233.  
  234.         if(rline() < 0) return;
  235.         if(*linebuf == '#') {
  236.                 if(linebuf[1] == 'n')
  237.                         nflag = 1;
  238.         }
  239.         else {
  240.                 cp = linebuf;
  241.                 goto comploop;
  242.         }
  243.  
  244.         for(;;) {
  245.                 if(rline() < 0) break;
  246.  
  247.                 cp = linebuf;
  248.  
  249. comploop:
  250. /*      fprintf(stdout, "cp: %s\n", cp); */     /*DEBUG*/
  251.                 while(*cp == ' ' || *cp == '\t')        cp++;
  252.                 if(*cp == '\0' || *cp == '#')           continue;
  253.                 if(*cp == ';') {
  254.                         cp++;
  255.                         goto comploop;
  256.                 }
  257.  
  258.                 q = address(&P(rep)->ad1);
  259.                 if(q == badp)
  260.                         fatal(CGMES, linebuf);
  261.  
  262.                 if(q != 0 && q == P(rep)->ad1) {
  263.                         if(op)
  264.                                 P(rep)->ad1 = op;
  265.                         else
  266.                                 fatal("First RE may not be null");
  267.                 } else if(q == 0) {
  268.                         P(rep)->ad1 = 0;
  269.                 } else {
  270.                         op = P(rep)->ad1;
  271.                         if(*cp == ',' || *cp == ';') {
  272.                                 cp++;
  273.                                 q = address(&P(rep)->ad2);
  274.                                 if(q == badp || q == 0)
  275.                                         fatal(CGMES, linebuf);
  276.                                 if(q == P(rep)->ad2)
  277.                                         P(rep)->ad2 = op;
  278.                                 else
  279.                                         op = P(rep)->ad2;
  280.  
  281.                         } else
  282.                                 P(rep)->ad2 = 0;
  283.                 }
  284.  
  285.                 while(*cp == ' ' || *cp == '\t')        cp++;
  286.  
  287. swit:
  288.                 switch(*cp++) {
  289.  
  290.                         default:
  291.                                 fatal("Unrecognized command: %s", linebuf);
  292.                                 /*NOTREACHED*/
  293.  
  294.                         case '!':
  295.                                 P(rep)->negfl = 1;
  296.                                 goto swit;
  297.  
  298.                         case '{':
  299.                                 P(rep)->command = BCOM;
  300.                                 P(rep)->negfl = !(P(rep)->negfl);
  301.                                 depth_check();
  302.                                 cmpend[depth++] = rep;
  303.                                 rep_inc();
  304.                                 if(*cp == '\0') continue;
  305.  
  306.                                 goto comploop;
  307.  
  308.                         case '}':
  309.                                 if(P(rep)->ad1)
  310.                                         fatal(AD0MES, linebuf);
  311.  
  312.                                 if(--depth < 0)
  313.                                         fatal("Too many }'s");
  314.                                 P(cmpend[depth])->bptr.lb1 = rep;
  315.  
  316.                                 continue;
  317.  
  318.                         case '=':
  319.                                 P(rep)->command = EQCOM;
  320.                                 if(P(rep)->ad2)
  321.                                         fatal(AD1MES, linebuf);
  322.                                 break;
  323.  
  324.                         case ':':
  325.                                 if(P(rep)->ad1)
  326.                                         fatal(AD0MES, linebuf);
  327.  
  328.                                 while(*cp++ == ' ');
  329.                                 cp--;
  330.  
  331.  
  332.                                 tp = L(lab)->asc;
  333.                                 while((*tp++ = *cp++))
  334.                                         if(tp >= &(L(lab)->asc[sizeof
  335.                                                                 L(lab)->asc]))
  336.                                                 fatal(LTL, linebuf);
  337.                                 *--tp = '\0';
  338.  
  339.                                 if(lpt = search(L(lab))) {
  340.                                         if(L(lpt)->address)
  341.                                                 fatal("Duplicate labels: %s",
  342.                                                                 linebuf);
  343.                                 } else {
  344.                                         L(lab)->chain = 0;
  345.                                         lpt = lab;
  346.                                         lab_inc();
  347.                                 }
  348.                                 L(lpt)->address = rep;
  349.  
  350.                                 continue;
  351.  
  352.                         case 'a':
  353.                                 P(rep)->command = ACOM;
  354.                                 if(P(rep)->ad2)
  355.                                         fatal(AD1MES, linebuf);
  356.                                 if(*cp == '\\') cp++;
  357.                                 if(*cp++ != '\n')
  358.                                         fatal(CGMES, linebuf);
  359.                                 text(&P(rep)->bptr.re1);
  360.                                 break;
  361.                         case 'c':
  362.                                 P(rep)->command = CCOM;
  363.                                 if(*cp == '\\') cp++;
  364.                                 if(*cp++ != ('\n'))
  365.                                         fatal(CGMES, linebuf);
  366.                                 text(&P(rep)->bptr.re1);
  367.                                 needdol = 1;
  368.                                 break;
  369.                         case 'i':
  370.                                 P(rep)->command = ICOM;
  371.                                 if(P(rep)->ad2)
  372.                                         fatal(AD1MES, linebuf);
  373.                                 if(*cp == '\\') cp++;
  374.                                 if(*cp++ != ('\n'))
  375.                                         fatal(CGMES, linebuf);
  376.                                 text(&P(rep)->bptr.re1);
  377.                                 break;
  378.  
  379.                         case 'g':
  380.                                 P(rep)->command = GCOM;
  381.                                 break;
  382.  
  383.                         case 'G':
  384.                                 P(rep)->command = CGCOM;
  385.                                 break;
  386.  
  387.                         case 'h':
  388.                                 P(rep)->command = HCOM;
  389.                                 break;
  390.  
  391.                         case 'H':
  392.                                 P(rep)->command = CHCOM;
  393.                                 break;
  394.  
  395.                         case 't':
  396.                                 P(rep)->command = TCOM;
  397.                                 goto jtcommon;
  398.  
  399.                         case 'b':
  400.                                 P(rep)->command = BCOM;
  401. jtcommon:
  402.                                 while(*cp++ == ' ');
  403.                                 cp--;
  404.  
  405.                                 if(*cp == '\0') {
  406.                                         if((pt = L(labtab)->chain) != 0) {
  407.                                                 while((pt1 = P(pt)->bptr.lb1) != 0)
  408.                                                         pt = pt1;
  409.                                                 P(pt)->bptr.lb1 = rep;
  410.                                         } else
  411.                                                 L(labtab)->chain = rep;
  412.                                         break;
  413.                                 }
  414.                                 tp = L(lab)->asc;
  415.                                 while((*tp++ = *cp++))
  416.                                         if(tp >= &(L(lab)->asc[sizeof
  417.                                                                 L(lab)->asc]))
  418.                                                 fatal(LTL, linebuf);
  419.                                 cp--;
  420.                                 *--tp = '\0';
  421.  
  422.                                 if(lpt = search(L(lab))) {
  423.                                         if(L(lpt)->address) {
  424.                                                 P(rep)->bptr.lb1 = L(lpt)->address;
  425.                                         } else {
  426.                                                 pt = L(lpt)->chain;
  427.                                                 while((pt1 = P(pt)->bptr.lb1) != 0)
  428.                                                         pt = pt1;
  429.                                                 P(pt)->bptr.lb1 = rep;
  430.                                         }
  431.                                 } else {
  432.                                         L(lab)->chain = rep;
  433.                                         L(lab)->address = 0;
  434.                                         lab_inc();
  435.                                 }
  436.                                 break;
  437.  
  438.                         case 'n':
  439.                                 P(rep)->command = NCOM;
  440.                                 break;
  441.  
  442.                         case 'N':
  443.                                 P(rep)->command = CNCOM;
  444.                                 break;
  445.  
  446.                         case 'p':
  447.                                 P(rep)->command = PCOM;
  448.                                 break;
  449.  
  450.                         case 'P':
  451.                                 P(rep)->command = CPCOM;
  452.                                 break;
  453.  
  454.                         case 'r':
  455.                                 P(rep)->command = RCOM;
  456.                                 if(P(rep)->ad2)
  457.                                         fatal(AD1MES, linebuf);
  458. #if !defined (SUS) && !defined (SU3)
  459.                                 if(*cp++ != ' ')
  460.                                         fatal(CGMES, linebuf);
  461. #else   /* SUS, SU3 */
  462.                                 while (*cp == ' ' || *cp == '\t')
  463.                                         cp++;
  464. #endif  /* SUS, SU3 */
  465.                                 text(&P(rep)->bptr.re1);
  466.                                 break;
  467.  
  468.                         case 'd':
  469.                                 P(rep)->command = DCOM;
  470.                                 break;
  471.  
  472.                         case 'D':
  473.                                 P(rep)->command = CDCOM;
  474.                                 P(rep)->bptr.lb1 = 1;
  475.                                 break;
  476.  
  477.                         case 'q':
  478.                                 P(rep)->command = QCOM;
  479.                                 if(P(rep)->ad2)
  480.                                         fatal(AD1MES, linebuf);
  481.                                 break;
  482.  
  483.                         case 'l':
  484.                                 P(rep)->command = LCOM;
  485.                                 break;
  486.  
  487.                         case 's':
  488.                                 P(rep)->command = SCOM;
  489.                                 sed_seof = fetch(&cp);
  490.                                 q = sed_compile(&P(rep)->bptr.re1);
  491.                                 if(q == badp)
  492.                                         fatal(CGMES, linebuf);
  493.                                 if(q == P(rep)->bptr.re1) {
  494.                                         if (op == NULL)
  495.                                                 fatal("First RE may not be null");
  496.                                         P(rep)->bptr.re1 = op;
  497.                                 } else {
  498.                                         op = P(rep)->bptr.re1;
  499.                                 }
  500.  
  501.                                 if(compsub(&P(rep)->rhs, &P(rep)->nsub) == badp)
  502.                                         fatal(CGMES, linebuf);
  503.                         sloop:  if(*cp == 'g') {
  504.                                         cp++;
  505.                                         P(rep)->gfl = -1;
  506.                                         goto sloop;
  507.                                 } else if(gflag)
  508.                                         P(rep)->gfl = -1;
  509.                                 if (*cp >= '0' && *cp <= '9') {
  510.                                         while (*cp >= '0' && *cp <= '9') {
  511.                                                 if (P(rep)->gfl == -1)
  512.                                                         P(rep)->gfl = 0;
  513.                                                 P(rep)->gfl = P(rep)->gfl * 10
  514.                                                         + *cp++ - '0';
  515.                                         }
  516.                                         goto sloop;
  517.                                 }
  518. #if !defined (SUS) && !defined (SU3)
  519.                                 if (P(rep)->gfl > 0 && P(rep)->gfl > 512)
  520.                         fatal("Suffix too large - 512 max: %s", linebuf);
  521. #endif
  522.  
  523.                                 if(*cp == 'p') {
  524.                                         cp++;
  525.                                         P(rep)->pfl = 1;
  526.                                         goto sloop;
  527.                                 }
  528.  
  529.                                 if(*cp == 'P') {
  530.                                         cp++;
  531.                                         P(rep)->pfl = 2;
  532.                                         goto sloop;
  533.                                 }
  534.  
  535.                                 if(*cp == 'w') {
  536.                                         cp++;
  537.                                         wfile();
  538.                                 }
  539.                                 break;
  540.  
  541.                         case 'w':
  542.                                 P(rep)->command = WCOM;
  543.                                 wfile();
  544.                                 break;
  545.  
  546.                         case 'x':
  547.                                 P(rep)->command = XCOM;
  548.                                 break;
  549.  
  550.                         case 'y':
  551.                                 P(rep)->command = YCOM;
  552.                                 sed_seof = fetch(&cp);
  553.                                 if (ycomp(&P(rep)->bptr.re1) == badp)
  554.                                         fatal(CGMES, linebuf);
  555.                                 break;
  556.  
  557.                 }
  558.                 rep_inc();
  559.  
  560.                 if(*cp++ != '\0') {
  561.                         if(cp[-1] == ';')
  562.                                 goto comploop;
  563.                         fatal(CGMES, linebuf);
  564.                 }
  565.  
  566.         }
  567.         P(rep)->command = 0;
  568.         lastre = op;
  569. }
  570.  
  571. static char     *
  572. compsub(char **rhsbuf, char *nsubp)
  573. {
  574.         register char   *p, *op, *oq;
  575.         char    *q;
  576.         wint_t  c;
  577.         size_t  sz = 32;
  578.  
  579.         *rhsbuf = smalloc(sz);
  580.         p = *rhsbuf;
  581.         q = cp;
  582.         *nsubp = 0;
  583.         for(;;) {
  584.                 op = p;
  585.                 oq = q;
  586.                 if((c = fetch(&q)) == '\\') {
  587.                         check(p, *rhsbuf, sz, 32, op)
  588.                         *p = '\\';
  589.                         oq = q;
  590.                         c = fetch(&q);
  591.                         do {
  592.                                 check(p, *rhsbuf, sz, 32, op)
  593.                                 *++p = *oq++;
  594.                         } while (oq < q);
  595.                         if(c > nbra + '0' && c <= '9')
  596.                                 return(badp);
  597.                         if (c > *nsubp + '0' && c <= '9')
  598.                                 *nsubp = c - '0';
  599.                         check(p, *rhsbuf, sz, 32, op)
  600.                         p++;
  601.                         continue;
  602.                 } else {
  603.                         do {
  604.                                 check(p, *rhsbuf, sz, 32, op)
  605.                                 *p++ = *oq++;
  606.                         } while (oq < q);
  607.                         p--;
  608.                 }
  609.                 if(c == sed_seof) {
  610.                         check(p, *rhsbuf, sz, 32, op)
  611.                         *op++ = '\0';
  612.                         cp = q;
  613.                         return(op);
  614.                 }
  615.                 check(p, *rhsbuf, sz, 32, op)
  616.                 if(*p++ == '\0') {
  617.                         return(badp);
  618.                 }
  619.  
  620.         }
  621. }
  622.  
  623. #define rlinechk()      if (c >= lbend-2) \
  624.                                 growsp(LINTL)
  625.  
  626. static int
  627. rline(void)
  628. {
  629.         register char   *q;
  630.         register int    c;
  631.         register int    t;
  632.         static char     *saveq;
  633.  
  634.         c = -1;
  635.  
  636.         if(eflag) {
  637.                 if(eflag > 0) {
  638.                         eflag = -1;
  639.                         q = optarg;
  640.                         rlinechk();
  641.                         while(linebuf[++c] = *q++) {
  642.                                 rlinechk();
  643.                                 if(linebuf[c] == '\\') {
  644.                                         if((linebuf[++c] = *q++) == '\0') {
  645.                                                 rlinechk();
  646.                                                 saveq = 0;
  647.                                                 return(-1);
  648.                                         } else
  649.                                                 continue;
  650.                                 }
  651.                                 if(linebuf[c] == '\n') {
  652.                                         linebuf[c] = '\0';
  653.                                         saveq = q;
  654.                                         return(1);
  655.                                 }
  656.                         }
  657.                         saveq = 0;
  658.                         return(1);
  659.                 }
  660.                 if((q = saveq) == 0)    return(-1);
  661.  
  662.                 while(linebuf[++c] = *q++) {
  663.                         rlinechk();
  664.                         if(linebuf[c] == '\\') {
  665.                                 if((linebuf[++c] = *q++) == '0') {
  666.                                         rlinechk();
  667.                                         saveq = 0;
  668.                                         return(-1);
  669.                                 } else
  670.                                         continue;
  671.                         }
  672.                         if(linebuf[c] == '\n') {
  673.                                 linebuf[c] = '\0';
  674.                                 saveq = q;
  675.                                 return(1);
  676.                         }
  677.                 }
  678.                 saveq = 0;
  679.                 return(1);
  680.         }
  681.  
  682.         while((t = getc(fin)) != EOF) {
  683.                 rlinechk();
  684.                 linebuf[++c] = (char)t;
  685.                 if(linebuf[c] == '\\') {
  686.                         t = getc(fin);
  687.                         rlinechk();
  688.                         linebuf[++c] = (char)t;
  689.                 }
  690.                 else if(linebuf[c] == '\n') {
  691.                         linebuf[c] = '\0';
  692.                         return(1);
  693.                 }
  694.         }
  695.         linebuf[++c] = '\0';
  696.         return(-1);
  697. }
  698.  
  699. static char     *
  700. address(char **expbuf)
  701. {
  702.         register char   *rcp, *ep;
  703.         long long       lno;
  704.  
  705.         *expbuf = NULL;
  706.         if(*cp == '$') {
  707.                 cp++;
  708.                 ep = *expbuf = smalloc(2 * sizeof *expbuf);
  709.                 *ep++ = CEND;
  710.                 *ep++ = ceof;
  711.                 needdol = 1;
  712.                 return(ep);
  713.         }
  714.  
  715.         if(*cp == '/' || *cp == '\\') {
  716.                 if (*cp == '\\')
  717.                         cp++;
  718.                 sed_seof = fetch(&cp);
  719.                 return(sed_compile(expbuf));
  720.         }
  721.  
  722.         rcp = cp;
  723.         lno = 0;
  724.  
  725.         while(*rcp >= '0' && *rcp <= '9')
  726.                 lno = lno*10 + *rcp++ - '0';
  727.  
  728.         if(rcp > cp) {
  729.                 if (nlno > 020000000000 ||
  730.                     (tlno = realloc(tlno, (nlno+1)*sizeof *tlno)) == NULL)
  731.                         fatal("Too many line numbers");
  732.                 ep = *expbuf = smalloc(6 * sizeof *expbuf);
  733.                 *ep++ = CLNUM;
  734.                 slno(ep, nlno);
  735.                 tlno[nlno++] = lno;
  736.                 *ep++ = ceof;
  737.                 cp = rcp;
  738.                 return(ep);
  739.         }
  740.         return(0);
  741. }
  742.  
  743. static int
  744. cmp(const char *a, const char *b)
  745. {
  746.         register const char     *ra, *rb;
  747.  
  748.         ra = a - 1;
  749.         rb = b - 1;
  750.  
  751.         while(*++ra == *++rb)
  752.                 if(*ra == '\0') return(0);
  753.         return(1);
  754. }
  755.  
  756. static void
  757. text(char **textbuf)
  758. {
  759.         register char   *p, *oq;
  760.         char *q;
  761.         size_t sz = 128;
  762.  
  763.         *textbuf = smalloc(sz);
  764.         p = *textbuf;
  765.         q = cp;
  766.         for(;;) {
  767.  
  768.                 oq = q;
  769.                 if(fetch(&q) == '\\') {
  770.                         oq = q;
  771.                         fetch(&q);
  772.                 }
  773.                 while(oq < q)
  774.                         *p++ = *oq++;
  775.                 if(p[-1] == '\0') {
  776.                         cp = --q;
  777.                         return;
  778.                 }
  779.                 check(p, *textbuf, sz, 128, null)
  780.         }
  781. }
  782.  
  783. static int
  784. search(struct label *ptr)
  785. {
  786.         struct label    *rp;
  787.  
  788.         rp = L(labtab);
  789.         while(rp < ptr) {
  790.                 if(cmp(rp->asc, ptr->asc) == 0)
  791.                         return(rp - L(labtab) + 1);
  792.                 rp++;
  793.         }
  794.  
  795.         return(0);
  796. }
  797.  
  798.  
  799. static void
  800. dechain(void)
  801. {
  802.         struct label    *lptr;
  803.         int     rptr, trptr;
  804.  
  805.         for(lptr = L(labtab); lptr < L(lab); lptr++) {
  806.  
  807.                 if(lptr->address == 0)
  808.                         fatal("Undefined label: %s", lptr->asc);
  809.  
  810.                 if(lptr->chain) {
  811.                         rptr = lptr->chain;
  812.                         while((trptr = P(rptr)->bptr.lb1) != 0) {
  813.                                 P(rptr)->bptr.lb1 = lptr->address;
  814.                                 rptr = trptr;
  815.                         }
  816.                         P(rptr)->bptr.lb1 = lptr->address;
  817.                 }
  818.         }
  819. }
  820.  
  821. static char *
  822. ycomp_sb(char **expbuf)
  823. {
  824.         register int    c, d;
  825.         register char   *ep, *tsp;
  826.         char    *sp;
  827.  
  828.         *expbuf = smalloc(0400);
  829.         ep = *expbuf;
  830.         for(c = 0; !(c & 0400); c++)
  831.                 ep[c] = '\0';
  832.         sp = cp;
  833.         for(tsp = cp; *tsp != sed_seof; tsp++) {
  834.                 if(*tsp == '\\')
  835.                         tsp++;
  836.                 if(*tsp == '\n' || *tsp == '\0')
  837.                         return(badp);
  838.         }
  839.         tsp++;
  840.  
  841.         while((c = *sp++ & 0377) != sed_seof) {
  842.                 if(c == '\\') {
  843.                         c = *sp == 'n' ? '\n' : *sp;
  844.                         sp++;
  845.                 }
  846.                 if((ep[c] = d = *tsp++ & 0377) == '\\') {
  847.                         ep[c] = *tsp == 'n' ? '\n' : *tsp;
  848.                         tsp++;
  849.                 }
  850.                 if(d != '\\' && ep[c] == sed_seof || ep[c] == '\0')
  851.                         return(badp);
  852.         }
  853.         if(*tsp != sed_seof)
  854.                 return(badp);
  855.         cp = ++tsp;
  856.  
  857.         for(c = 0; !(c & 0400); c++)
  858.                 if(ep[c] == 0)
  859.                         ep[c] = (char)c;
  860.  
  861.         return(ep + 0400);
  862. }
  863.  
  864. static char *
  865. ycomp_mb(char **expbuf)
  866. {
  867.         struct yitem    **yt, *yp;
  868.         register wint_t c, d;
  869.         char    *otsp, *tsp, *sp, *mp;
  870.  
  871.         tsp = sp = cp;
  872.         while ((c = fetch(&tsp)) != sed_seof) {
  873.                 if (c == '\\')
  874.                         c = fetch(&tsp);
  875.                 if (c == '\n' || c == '\0')
  876.                         return badp;
  877.         }
  878.         yt = scalloc(200, sizeof *yt);
  879.         while ((c = fetch(&sp)) != sed_seof) {
  880.                 if (c == '\\') {
  881.                         if ((d = fetch(&sp)) == 'n')
  882.                                 c = '\n';
  883.                         else
  884.                                 c = d;
  885.                 }
  886.                 otsp = tsp;
  887.                 d = fetch(&tsp);
  888.                 yp = ylook(c, yt, 1);
  889.                 yp->y_oc = c;
  890.                 if ((yp->y_yc = d) == '\\') {
  891.                         otsp = tsp;
  892.                         if ((c = fetch(&tsp)) == 'n')
  893.                                 yp->y_yc = '\n';
  894.                         else
  895.                                 yp->y_yc = c;
  896.                 }
  897.                 if (d != '\\' && yp->y_yc == sed_seof || yp->y_yc == '\0')
  898.                         return badp;
  899.                 mp = yp->y_mc;
  900.                 if (yp->y_yc != '\n')
  901.                         while (otsp < tsp)
  902.                                 *mp++ = *otsp++;
  903.                 else
  904.                         *mp++ = '\n';
  905.                 *mp = '\0';
  906.         }
  907.         if (fetch(&tsp) != sed_seof)
  908.                 return badp;
  909.         cp = tsp;
  910.         *expbuf = (char *)yt;
  911.         return &(*expbuf)[1];
  912. }
  913.  
  914. static void
  915. rep_inc(void)
  916. {
  917.         register char   *p;
  918.         const int       chunk = 16;
  919.  
  920.         if (++rep >= PTRSIZE) {
  921.                 ptrspace = srealloc(ptrspace,
  922.                                 (PTRSIZE += chunk) * sizeof *ptrspace);
  923.                 for (p = (char *)&ptrspace[PTRSIZE - chunk];
  924.                                 p < (char *)&ptrspace[PTRSIZE]; p++)
  925.                         *p = '\0';
  926.         }
  927. }
  928.  
  929. static void
  930. lab_inc(void)
  931. {
  932.         register char   *p;
  933.         const int       chunk = 8;
  934.  
  935.         if (++lab >= LABSIZE) {
  936.                 ltab = srealloc(ltab, (LABSIZE += chunk) * sizeof *ltab);
  937.                 for (p = (char *)&ltab[LABSIZE - chunk];
  938.                                 p < (char *)&ltab[LABSIZE]; p++)
  939.                         *p = '\0';
  940.         }
  941. }
  942.  
  943. void
  944. aptr_inc(void)
  945. {
  946.         register char   *p;
  947.         const int       chunk = 8;
  948.  
  949.         if (++aptr > ABUFSIZE) {
  950.                 abuf = srealloc(abuf, (ABUFSIZE += chunk) * sizeof *abuf);
  951.                 for (p = (char *)&abuf[ABUFSIZE - chunk];
  952.                                 p < (char *)&abuf[ABUFSIZE]; p++)
  953.                         *p = '\0';
  954.         }
  955. }
  956.  
  957. static void
  958. depth_check(void)
  959. {
  960.         if (depth + 1 > DEPTH)
  961.                 cmpend = srealloc(cmpend, (DEPTH += 8) * sizeof *cmpend);
  962. }
  963.  
  964. void
  965. nonfatal(const char *afmt, ...)
  966. {
  967.         va_list ap;
  968.         const char      *fmt;
  969.  
  970.         if (*afmt == '\1') {
  971.                 fprintf(stderr, "%s: ", progname);
  972.                 fmt = &afmt[1];
  973.         } else
  974.                 fmt = afmt;
  975.         va_start(ap, afmt);
  976.         vfprintf(stderr, fmt, ap);
  977.         va_end(ap);
  978.         fputc('\n', stderr);
  979.         status |= 1;
  980. }
  981.  
  982. void
  983. fatal(const char *afmt, ...)
  984. {
  985.         va_list ap;
  986.         const char      *fmt;
  987.  
  988.         if (*afmt == '\1') {
  989.                 fprintf(stderr, "%s: ", progname);
  990.                 fmt = &afmt[1];
  991.         } else
  992.                 fmt = afmt;
  993.         va_start(ap, afmt);
  994.         vfprintf(stderr, fmt, ap);
  995.         va_end(ap);
  996.         fputc('\n', stderr);
  997.         exit(2);
  998. }
  999.  
  1000. static void *
  1001. srealloc(void *vp, size_t nbytes)
  1002. {
  1003.         void *p;
  1004.  
  1005.         if ((p = realloc(vp, nbytes)) == NULL)
  1006.                 fatal(TMMES, linebuf);
  1007.         return p;
  1008. }
  1009.  
  1010. void *
  1011. smalloc(size_t nbytes)
  1012. {
  1013.         return srealloc(NULL, nbytes);
  1014. }
  1015.  
  1016. static void *
  1017. scalloc(size_t nmemb, size_t size)
  1018. {
  1019.         void *p;
  1020.  
  1021.         if ((p = calloc(nmemb, size)) == NULL)
  1022.                 fatal(TMMES, linebuf);
  1023.         return p;
  1024. }
  1025.  
  1026. #if defined (SUS) || defined (SU3) || defined (S42)
  1027. static char *
  1028. sed_compile(char **ep)
  1029. {
  1030.         struct re_emu   *re;
  1031.         static char     *pat;
  1032.         static size_t   patsz;
  1033.         register char   *p, *oc;
  1034.         wint_t  c, d;
  1035.  
  1036.         if (*cp != sed_seof)
  1037.                 nbra = 0;
  1038.         if (patsz == 0)
  1039.                 pat = smalloc(patsz = 32);
  1040.         p = pat;
  1041.         do {
  1042.                 oc = cp;
  1043.                 if ((c = fetch(&cp)) == sed_seof)
  1044.                         *p = '\0';
  1045.                 else if (c == '\\') {
  1046.                         oc = cp;
  1047.                         if ((c = fetch(&cp)) == 'n')
  1048.                                 *p = '\n';
  1049.                         else {
  1050.                                 check(p, pat, patsz, 32, null);
  1051.                                 *p++ = '\\';
  1052.                                 if (c == '(')
  1053.                                         nbra++;
  1054.                                 goto normchar;
  1055.                         }
  1056.                 } else if (c == '[') {
  1057.                         check(p, pat, patsz, 32, null);
  1058.                         *p++ = c;
  1059.                         d = WEOF;
  1060.                         do {
  1061.                                 oc = cp;
  1062.                                 c = fetch(&cp);
  1063.                                 if (c == '\0')
  1064.                                         goto normchar;
  1065.                                 do {
  1066.                                         check(p, pat, patsz, 32, null);
  1067.                                         *p++ = *oc++;
  1068.                                 } while (oc < cp);
  1069.                                 if (d == '[' && (c == ':' || c == '.' ||
  1070.                                                         c == '=')) {
  1071.                                         d = c;
  1072.                                         do {
  1073.                                                 oc = cp;
  1074.                                                 c = fetch(&cp);
  1075.                                                 if (c == '\0')
  1076.                                                         goto normchar;
  1077.                                                 do {
  1078.                                                         check(p, pat, patsz,32,
  1079.                                                                         null);
  1080.                                                         *p++ = *oc++;
  1081.                                                 } while (oc < cp);
  1082.                                         } while (c != d || peek(&cp) != ']');
  1083.                                         oc = cp;
  1084.                                         c = fetch(&cp);
  1085.                                         do {
  1086.                                                 check(p, pat, patsz, 32, null);
  1087.                                                 *p++ = *oc++;
  1088.                                         } while (oc < cp);
  1089.                                         c = WEOF; /* == reset d and continue */
  1090.                                 }
  1091.                                 d = c;
  1092.                         } while (c != ']');
  1093.                         p--;
  1094.                 } else {
  1095.         normchar:       do {
  1096.                                 check(p, pat, patsz, 32, null)
  1097.                                 *p++ = *oc++;
  1098.                         } while (oc < cp);
  1099.                         p--;
  1100.                 }
  1101.                 check(p, pat, patsz, 32, null);
  1102.         } while (*p++ != '\0');
  1103.         re = scalloc(1, sizeof *re);
  1104.         *ep = (char *)re;
  1105.         if (*pat == '^')
  1106.                 **ep = 1;
  1107.         if (*pat != '\0') {
  1108.                 int reflags = 0;
  1109.  
  1110. #ifdef  REG_ANGLES
  1111.                 reflags |= REG_ANGLES;
  1112. #endif  /* REG_ANGLES */
  1113. #if defined (SU3) && defined (REG_AVOIDNULL)
  1114.                 reflags |= REG_AVOIDNULL;
  1115. #endif  /* SU3 && AVOIDNULL */
  1116.                 if (regcomp(&re->r_preg, pat, reflags) != 0)
  1117.                         re = (struct re_emu *)badp;
  1118.         } else
  1119.                 **ep = 2;
  1120.         p = (char *)re;
  1121.         if (p != badp && *pat)
  1122.                 p++;
  1123.         return p;
  1124. }
  1125. #else   /* !SUS, !SU3, !S42 */
  1126. static char *
  1127. sed_compile(char **ep)
  1128. {
  1129.         extern char *compile(char *, char *, char *, int);
  1130.         register char *p;
  1131.         size_t sz;
  1132.  
  1133.         for (sz = 0, p = cp; *p; p++)
  1134.                 if (*p == '[')
  1135.                         sz += 32;
  1136.         sz += 2 * (p - cp) + 5;
  1137.         *ep = smalloc(sz);
  1138.         (*ep)[1] = '\0';
  1139.         p = compile(NULL, &(*ep)[1], &(*ep)[sz], sed_seof);
  1140.         if (p == &(*ep)[1])
  1141.                 return *ep;
  1142.         **ep = circf;
  1143.         return p;
  1144. }
  1145. #endif  /* !SUS, !SU3, !S42 */
  1146.  
  1147. wint_t
  1148. wc_get(char **sc, int move)
  1149. {
  1150.         wint_t  c;
  1151.         char    *p = *sc;
  1152.         wchar_t wcbuf;
  1153.         int     len;
  1154.  
  1155.         if ((*p & 0200) == 0) {
  1156.                 c = *p;
  1157.                 p += (len = 1);
  1158.                 invchar = 0;
  1159.         } else if ((len = mbtowc(&wcbuf, p, MB_LEN_MAX)) < 0) {
  1160.                 if (!executing)
  1161.                         fatal("invalid multibyte character: %s", p);
  1162.                 c = (*p++ & 0377);
  1163.                 mbtowc(NULL, NULL, 0);
  1164.                 invchar = 1;
  1165.         } else if (len == 0) {
  1166.                 c = '\0';
  1167.                 p++;
  1168.                 invchar = 0;
  1169.         } else {
  1170.                 c = wcbuf;
  1171.                 p += len;
  1172.                 invchar = 0;
  1173.         }
  1174.         if (move)
  1175.                 *sc = p;
  1176.         return c;
  1177. }
  1178.  
  1179. /*
  1180.  * Note that this hash is not optimized to distribute the items
  1181.  * equally to all buckets. y commands typically handle only a
  1182.  * small part of the alphabet, thus most characters will have
  1183.  * no entry in the hash table. If no list exists in the bucket
  1184.  * for the hash of these characters, the function can return
  1185.  * quickly.
  1186.  */
  1187. #define yhash(c)        (c & 0177)
  1188.  
  1189. struct yitem *
  1190. ylook(wint_t c, struct yitem **yt, int make)
  1191. {
  1192.         struct yitem    *yp;
  1193.         int     h;
  1194.  
  1195.         yp = yt[h = yhash(c)];
  1196.         while (yp != NULL) {
  1197.                 if (yp->y_oc == c)
  1198.                         break;
  1199.                 yp = yp->y_nxt;
  1200.         }
  1201.         if (make && yp == NULL) {
  1202.                 yp = scalloc(1, sizeof *yp);
  1203.                 yp->y_oc = c;
  1204.                 yp->y_nxt = yt[h];
  1205.                 yt[h] = yp;
  1206.         }
  1207.         return yp;
  1208. }
  1209.  
  1210. void
  1211. growsp(const char *msg)
  1212. {
  1213.         const int       incr = 128;
  1214.         int     olbend, ogbend, ohend;
  1215.  
  1216.         olbend = lbend;
  1217.         ogbend = gbend;
  1218.         ohend = hend;
  1219.         if ((linebuf = realloc(linebuf, lbend += incr)) == NULL ||
  1220.                         (genbuf = realloc(genbuf, gbend += incr)) == NULL ||
  1221.                         (holdsp = realloc(holdsp, hend += incr)) == NULL)
  1222.                 fatal(msg ? msg : "Cannot malloc space");
  1223.         while (olbend < lbend)
  1224.                 linebuf[olbend++] = '\0';
  1225.         while (ogbend < gbend)
  1226.                 genbuf[ogbend++] = '\0';
  1227.         while (ohend < hend)
  1228.                 holdsp[ohend++] = '\0';
  1229. }
  1230.  
  1231. static void
  1232. wfile(void)
  1233. {
  1234.         int     i;
  1235.  
  1236. #if !defined (SUS) && !defined (SU3)
  1237.         if(*cp++ != ' ')
  1238.                 fatal(CGMES, linebuf);
  1239. #else   /* SUS, SU3 */
  1240.         while (*cp == ' ' || *cp == '\t')
  1241.                 cp++;
  1242. #endif  /* SUS, SU3 */
  1243.  
  1244.         text(&fname[nfiles]);
  1245.         for(i = nfiles - 1; i >= 0; i--)
  1246.                 if(fname[i] != NULL && cmp(fname[nfiles], fname[i]) == 0) {
  1247.                         P(rep)->fcode = fcode[i];
  1248.                         free(fname[nfiles]);
  1249.                         return;
  1250.                 }
  1251.  
  1252.         if((P(rep)->fcode = fopen(fname[nfiles], "w")) == NULL)
  1253.                 fatal("Cannot create %s", fname[nfiles]);
  1254.         fcode[nfiles++] = P(rep)->fcode;
  1255.         morefiles();
  1256. }
  1257.  
  1258. static void
  1259. morefiles(void)
  1260. {
  1261.         if ((fname = realloc(fname, (nfiles+1) * sizeof *fname)) == 0 ||
  1262.             (fcode = realloc(fcode, (nfiles+1) * sizeof *fcode)) == 0)
  1263.                 fatal("Too many files in w commands");
  1264.         fname[nfiles] = 0;
  1265.         fcode[nfiles] = 0;
  1266. }
  1267.  

Quellcode

Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. Alternativ kannst du den gesamten Eintrag auch als Datei herunterladen.