#include <perms.h>
static const int Lineinsert = 0x80000000;
static const int Inversevideo = 0x40000000;
static const int Hardcopy = 0;
static const int Bantam = 1;
static const int Vt52 = 2 + Lineinsert + Inversevideo;
static const int Vt100 = 3 + Lineinsert + Inversevideo;
static const int Vc404 = 4;
static const int Win32console = 5 + Lineinsert + Inversevideo;
void Vecce(int Argc, _imp_string *Argv) {
  void Getdimensions(int *Rows, int *Cols);
  void Cursorto(int Row, int Col);
  void Invert(void);
  static const int Rt = 13;
  static const int Esc = 27;
  static const int Dle = 0x10;
  static const int Maxname = 255;
  typedef struct File {
    _imp_string Name;
    int Top;
    int Lim;
    int Vmtop;
    int Vmlim;
    int Flag;
  } File;
  auto void Move(int Length, int From, int To);
  auto void Connectinput(File * F);
  void Edi(File * Old, File * Sec, File * New, int Video, int Rows, int Cols) {
    static const int Cbound = 50;
    static const int Tbound = 120;
    static const int Stopper = -10000;
    static const int Casebit = 32;
    int Cmax;
    int Ci;
    int Ti;
    int Code;
    int Ref;
    int Scope;
    int Num;
    int Sym;
    int Sym1;
    int Pend;
    int Casemask;
    int Width;
    int Dir;
    int Sin;
    int Macpos;
    int Lbeg;
    int Fp;
    int Lend;
    int Flim;
    int Gaptop;
    int Gaplim;
    int Mstart;
    int Msize;
    int Sfp;
    int Slim;
    int Newtop;
    int Newlim;
    int Line;
    int Winline;
    int Limline;
    int Breaks;
    int Joins;
    int Vrow;
    int Vcol;
    static int Zrow = 0;
    static int Mon = 1;
    int Fprow;
    static int Printline = 0;
    static int Printed = 0;
    int Wintop;
    int Winbot;
    int Winlim;
    int Minwin;
    int Changemin;
    int Changelbeg;
    int Vp;
    int Endon;
    static const _imp_string Proms[8 /*0:7*/] = {_imp_str_literal(">"),           _imp_str_literal("^X  ^I >"),
                                                 _imp_str_literal("^Y  ^x>"),     _imp_str_literal("^[rrH^[2K>"),
                                                 _imp_str_literal("see below"),   _imp_str_literal(">"),
                                                 [6 ... 7] = _imp_str_literal("")};
    static const _imp_string Gproms[8 /*0:7*/] = {_imp_str_literal(":"),  _imp_str_literal("^A "),
                                                  _imp_str_literal("^A"), _imp_str_literal("^M"),
                                                  _imp_str_literal("  "), [5 ... 7] = _imp_str_literal("")};
    unsigned char Macstore[256 /*0:255*/];
    typedef struct Commandcell {
      unsigned char Code;
      unsigned char Ref;
      short Scope;
      int Count;
    } Commandcell;
    Commandcell R[50 /*1:50*/];
    unsigned char Text[120 /*1:120*/];
    _imp_string Prom;
    _imp_string Gprom;
    _imp_string Videoinvert;
    _imp_string Videorestore;
    _imp_string Digits(int N) {
      _imp_string S;
      int J;
      S = _imp_str_literal("");
      if (N >= 100) {
        S = _imp_str_literal("1");
        N -= 100;
      }
      if (N >= 10) {
        J = N / 10;
        S = _imp_join(S, Tostring(J + '0'));
        N -= (J * 4 + J) * 2;
      }
      S = _imp_join(S, Tostring(N + '0'));
      return (S);
    }
    void Vt100cmd1(int P1, int Cmdsymbol) {
      _imp_string S = _imp_join(Tostring(Esc), _imp_str_literal("["));
      if (P1) S = _imp_join(S, Digits(P1));
      S = _imp_join(S, Tostring(Cmdsymbol));
      Printstring(S);
    }
    void Vt100cmd2(int P1, int P2, int Cmdsymbol) {
      _imp_string S = _imp_join(Tostring(Esc), _imp_str_literal("["));
      if (P1) S = _imp_join(S, Digits(P1));
      if (P2) S = _imp_join(S, _imp_join(_imp_str_literal(";"), Digits(P2)));
      S = _imp_join(S, Tostring(Cmdsymbol));
      Printstring(S);
    }
    void Clearscreen(void) {
      if (Video == Vt100) {
        Vt100cmd1(2, 'J');
        Vt100cmd2(Rows, 0, 'H');
      }
    }
    void At(int Row, int Col) {
      if (Video) {
        Vrow = Row;
        Vcol = Col;
        if (Col >= Cols) Col = Cols - 1;
        if (Video == Vt100)
          Vt100cmd2(Row + 1, Col + 1, 'H');
        else if (Video == Win32console)
          Cursorto(Row, Col);
        else if (Video == Vt52) {
          Printsymbol(Esc);
          Printsymbol('Y');
          Printsymbol(' ' + Row);
          Printsymbol(' ' + Col);
        } else if (Video == Vc404) {
          Printsymbol(Dle);
          Printsymbol(' ' + Row);
          Printsymbol(' ' + Col);
        } else {
          Printsymbol(Esc);
          Printsymbol('X');
          Printsymbol(' ' + Row);
          Printsymbol(Esc);
          Printsymbol('Y');
          Printsymbol(' ' + Col);
        }
      }
    }
    void Clearline(void) {
      void Clrline(void);
      if (Video != 0 && Vcol < Cols)
        if (Video == Vt100)
          Vt100cmd1(0, 'K');
        else if (Video == Win32console)
          Clrline();
        else if (Video == Vt52) {
          Printsymbol(Esc);
          Printsymbol('x');
        } else if (Video == Vc404) {
          Printsymbol(Esc);
          Printsymbol(0x16);
        } else {
          Printsymbol(Esc);
          Printsymbol('I');
          Printsymbol(0);
        }
    }
    void Vnewline(void) {
      Vrow++;
      Vcol = 0;
      Newline();
    }
    void Insertline(int Row) {
      void Insline(void);
      int From;
      if (Video < 0) {
        if (Vrow != Row) At(Row, 0);
        Vcol = 0;
        if (Video == Vt100) {
          Printsymbol(Esc);
          Printsymbol('7');
          Vt100cmd2(Row + 1, 0, 'r');
          Printsymbol(Esc);
          Printsymbol('8');
          Printsymbol(Esc);
          Printsymbol('M');
          Printstring(_imp_join(Tostring(Esc), _imp_str_literal("[;r")));
          Printsymbol(Esc);
          Printsymbol('8');
        } else if (Video == Win32console)
          Insline();
        else {
          Printsymbol(Esc);
          Printsymbol('L');
        }
      }
    }
    void Deleteline(int Row) {
      void Delline(void);
      if (Video < 0) {
        if (Vrow != Row) At(Row, 0);
        Vcol = 0;
        if (Video == Vt100) {
          Printsymbol(Esc);
          Printsymbol('7');
          Vt100cmd2(Row + 1, 0, 'r');
          Vt100cmd2(Rows, 0, 'H');
          Printsymbol(Esc);
          Printsymbol('D');
          Printstring(_imp_join(Tostring(Esc), _imp_str_literal("[;r")));
          Printsymbol(Esc);
          Printsymbol('8');
        } else if (Video == Win32console)
          Delline();
        else {
          Printsymbol(Esc);
          Printsymbol('M');
        }
      }
    }
    static const int Clear = 1;
    static const int Inc = 2;
    void Displayline(int Mode) {
      int K;
      if (Video << 1 > 0 && Vcol == 0) {
        Printsymbol(' ');
        Vcol = 1;
      }
      for (;;) {
        if (Vp == Gaptop) Vp = Gaplim;
        if (Vp == Flim) {
          if (!Endon) {
            Printstring(_imp_str_literal(" **END**"));
            Limline = Winline + Vrow - Wintop;
          }
          Endon = 1;
          break;
        }
        K = *Byteinteger(Vp);
        Vp++;
        if (K == Nl) break;
        if (Vcol < Cols) Printsymbol(K);
        Vcol++;
      }
      if (Mode & Clear) Clearline();
      if (Mode & Inc) Vnewline();
    }
    void Update(void) {
      int L;
      int D;
      int J;
      int Nop;
      if (Changemin == Newlim) return;
      if (!Video) return;
      Joins -= Breaks;
      L = Line - Winline + Wintop - Breaks;
      if (L >= Wintop && L < Winlim) {
        Vp = Changemin;
        Endon = 0;
        while (Changemin != Newtop && *Byteinteger(Changemin - 1) != Nl) Changemin--;
        if (Video < 0)
          At(L, Vp - Changemin);
        else
          At(L, Vp - Changemin + 1);
        Nop = 1;
        if (Changelbeg != Lbeg || Vp != Changemin) {
          Nop = 0;
          Displayline(Clear + Inc);
          L++;
        }
        if (L == Winlim) goto Done;
        if (Joins < 0 && Video < 0) {
          J = Joins;
          do {
            if (Wintop > Zrow) {
              Deleteline(Zrow);
              Wintop--;
              L--;
            } else
              Deleteline(Winbot);
            J++;
          } while (J);
          do {
            Insertline(L);
            Joins++;
          } while (Joins);
        }
        while (Vrow != Winlim && (Newtop <= Vp && Vp < Gaptop || (Vp == Gaptop && Nop == 0))) {
          Displayline(Clear + Inc);
          L++;
        }
        if (Joins) {
          D = Winlim - L - Joins;
          if (D <= 0 || Video > 0)
            while (Vrow != Winlim) Displayline(Clear + Inc);
          else {
            J = Joins;
            do {
              Deleteline(Vrow);
              J--;
            } while (J);
            do {
              do {
                if (Vp == Gaptop) Vp = Gaplim;
                if (Vp == Flim) {
                  Endon = 1;
                  break;
                }
                Vp++;
              } while (*Byteinteger(Vp - 1) != Nl);
              D--;
            } while (D);
            At(Winlim - Joins, 0);
            do {
              Insertline(Vrow);
              Displayline(Clear + Inc);
            } while (Vrow != Winlim);
          }
        }
      }
    Done:;
      Changemin = Newlim;
      Joins = 0;
      Breaks = 0;
    }
    void Display(void) {
      int Pre;
      int K;
      void Scanback(void) {
        while (Pre > 0) {
          if (Vp == Gaplim) Vp = Gaptop;
          if (Vp == Newtop) break;
          do {
            Vp--;
            if (Vp == Gaplim) Vp = Gaptop;
          } while (Vp != Newtop && *Byteinteger(Vp - 1) != Nl);
          Pre--;
        }
      }
      Update();
      Vp = Lbeg;
      Endon = 0;
      if (Vp < Gaplim && Gaplim <= Fp) Vp = Vp - Gaplim + Gaptop;
      if (!Video) {
        Vcol = 0;
        Printline = Line;
        Printed = Gaptop + Fp;
        if (Vp != Fp && Num == 1) {
          do {
            Printsymbol(*Byteinteger(Vp));
            Vp++;
            if (Vp == Gaptop) Vp = Gaplim;
          } while (Vp != Fp);
          Printsymbol('^');
        }
        Displayline(Inc);
        return;
      }
      Pre = Line - Winline;
      if (Pre < 0) {
        if (Pre > -Minwin && (Video < 0 || Wintop + Pre >= Zrow)) {
          Wintop += Pre;
          while (Wintop < Zrow) {
            Deleteline(Winbot);
            Insertline(Zrow);
            Wintop++;
          }
          if (Wintop > Zrow) {
            At(Wintop - 1, 0);
            Printsymbol('=');
            Clearline();
          }
          At(Wintop, 0);
          for (;;) {
            Displayline(Clear);
            Pre++;
            if (Pre >= 0) break;
            Vnewline();
          }
          Winline = Line;
          return;
        }
      } else {
        Pre = Pre + Wintop - Winlim;
        if (Pre < 0) return;
        if (Pre < Minwin) {
          K = Pre;
          Scanback();
          if (Video > 0) At(Winlim, 0);
          do {
            Deleteline(Zrow);
            if (Wintop > Zrow)
              Wintop--;
            else
              Winline++;
            Insertline(Winbot);
            Displayline(Clear + Inc);
            K--;
          } while (K >= 0);
          if (Video > 0) Newline();
          return;
        }
      }
      Pre = Minwin - 1;
      if (Fp != Flim) Pre = Pre / 2;
      Winline = Line - Pre;
      Scanback();
      Winline += Pre;
      Wintop = Winlim - Minwin;
      if (Wintop > Zrow) {
        At(Wintop - 1, 0);
        Printsymbol('=');
        Clearline();
        Vnewline();
      } else
        At(Zrow, 0);
      for (;;) {
        Displayline(Clear);
        if (Vrow >= Winbot) break;
        Vnewline();
      }
    }
    void Split(void) {
      int J;
      int Diff;
      int Unit;
      if (Newtop <= Fp && Fp < Gaptop) {
        if (Flim != Newlim) {
          J = Flim - Gaplim;
          if (Newlim - J < Gaptop) goto Abdn;
          Move(J, Gaplim, Newlim - J);
          Gaplim = Newlim - J;
          Flim = Newlim;
        }
        J = Gaptop - Fp;
        Diff = Gaplim - Gaptop;
        do {
          Unit = J;
          if (Diff < Unit) Unit = Diff;
          Gaptop -= Unit;
          Gaplim -= Unit;
          Move(Unit, Gaptop, Gaplim);
          J -= Unit;
        } while (J);
        if (Mstart == Fp) Mstart = Gaplim;
        Lbeg += Diff;
        Lend += Diff;
        Fp = Gaplim;
      } else {
        J = Fp - Gaplim;
        if (J > 0) {
          if (Gaptop + J >= Newlim) goto Abdn;
          Move(J, Gaplim, Gaptop);
        }
        Gaptop += J;
        Gaplim = Fp;
      }
      if (Gaptop < Changemin) {
        Changemin = Gaptop;
        Changelbeg = Lbeg;
      }
      J = Gaplim;
      if (Flim != Newlim) J = Newlim;
      if (Gaptop + 256 < J) return;
    Abdn:;
      Printstring(_imp_str_literal(" ** File too big "));
      exit(0);
    }
    void Consolidate(void) {
      int Diff;
      if (Gaptop != Newtop && *Byteinteger(Gaptop - 1) != Nl) do {
          *Byteinteger(Gaptop) = *Byteinteger(Gaplim);
          if (Gaplim == Fp) {
            Diff = Gaplim - Gaptop;
            Lbeg -= Diff;
            Fp -= Diff;
            Lend -= Diff;
            if (Mstart == Gaplim) Mstart = Fp;
          }
          Gaptop++;
          Gaplim++;
        } while (*Byteinteger(Gaptop - 1) != Nl);
    }
    void Join(void) {
      Split();
      Lbeg += Lend - Fp + 1;
      Fp = Lend + 1;
      Changelbeg = Lbeg;
      Gaplim = Fp;
      if (Line >= Winline)
        Joins++;
      else
        Winline--;
      Limline--;
    }
    void Switch(void) {
      int I;
      Split();
      if (Flim == Newlim) Newlim = Gaplim;
      I = Sfp;
      Sfp = Fp;
      Fp = I;
      I = Slim;
      Slim = Flim;
      Flim = I;
      Sin = Sin ^ 1;
      Lbeg = Lbeg - Sfp + Fp;
      Gaplim = Fp;
      if (Newlim == Gaplim) Newlim = Flim;
      Lend = Fp;
      while (Lend != Flim && *Byteinteger(Lend) != Nl) Lend++;
      Joins = 999;
      Limline = 99999;
    }
    int Type;
    int Chain;
    int Hold;
    int Echo;
    void Printcode(int K) {
      if (K >= 'a') {
        Printsymbol(K - Casebit);
        K = '-';
      }
      Printsymbol(K);
    }
    void Readsym(void) {
      if (_imp_on_event(9))
        ;
      if (Pend) {
        Sym = Pend;
        Pend = 0;
      } else {
        while (Macpos) {
          Sym = Macstore[Macpos & 255];
          Macpos++;
          if (Sym != Nl) return;
          Macpos = (unsigned)Macpos >> 8;
        }
        Readsymbol(Sym);
        if (Echo != 0 && Sym >= ' ') Printsymbol(Sym);
      }
    }
    void Ignore(void) {
      Echo = 0;
      while (Sym != Nl) Readsym();
    }
    static const unsigned char Symtype[64 /*32:95*/] = {
        0x03, 0x03, 0x03, 0x03, 0x07, 0x02, 0x03, 0x03, 0x0C, 0x0E, 0x00, 0x03, 0x0D, 0x02, 0x03, 0x03,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x02, 0x02, 0x0F,
        0x07, 0x07, 0x07, 0x17, 0x54, 0x06, 0x08, 0x07, 0x02, 0x05, 0x07, 0x07, 0x6B, 0x4A, 0x02, 0x02,
        0x0B, 0x02, 0x0B, 0x25, 0x09, 0x34, 0x49, 0x70, 0x70, 0x70, 0x70, 0x0C, 0x0F, 0x0E, 0x03, 0x03};
    void Readitem(void) {
      for (;;) {
        Type = 1;
        do
          Readsym();
        while (Sym == ' ');
        if (Sym < ' ') return;
        if (Sym >= 96) Sym = Sym & 95;
        Type = Symtype[Sym] & 15;
        if (Type) return;
        if (Sym < 'W') break;
        if ((unsigned)Macpos >> 24)
          Macpos = 0;
        else
          Macpos = (((Macpos << 2) + (Sym - 'W')) << 6) + 1;
      }
      Num = 0;
      if (Sym == '*') return;
      do {
        Num = Num * 10 + Sym - '0';
        Readsym();
      } while ('0' <= Sym && Sym <= '9');
      Pend = Sym;
    }
    void Minus(void) {
      if (Sym == '-') {
        Code += Casebit;
        Readitem();
      }
    }
    void Unchain(void) {
      do {
        Ref = Chain;
        if (!Ref) return;
        Chain = R[Ref].Ref;
        R[Ref].Ref = Ci;
      } while (R[Ref].Code != '[');
    }
    static int C_sw;
    static void *C[12 /*4:15*/] = {
        &&C_4, &&C_5, &&C_6, &&C_7, &&C_8, &&C_9, &&C_10, &&C_11, &&C_12, &&C_13, &&C_14, &&C_15,
    };
    static int Pc_sw;
    static void *Pc[8 /*0:7*/] = {
        &&Pc_0, &&Pc_1, &&Pc_2, &&Pc_3, &&Pc_4, &&Pc_5, &&Pc_6, &&Pc_7,
    };
    static int S_sw;
    static void *S[77 /*36:112*/] = {
        &&S_36,      &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default,
        &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default,
        &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default, &&S_default,
        &&S_default, &&S_default, &&S_default, &&S_63,      &&S_64,      &&S_65,      &&S_66,      &&S_67,
        &&S_68,      &&S_69,      &&S_70,      &&S_71,      &&S_default, &&S_73,      &&S_74,      &&S_75,
        &&S_76,      &&S_77,      &&S_default, &&S_default, &&S_80,      &&S_default, &&S_82,      &&S_83,
        &&S_84,      &&S_85,      &&S_86,      &&S_default, &&S_default, &&S_default, &&S_default, &&S_91,
        &&S_92,      &&S_93,      &&S_94,      &&S_default, &&S_default, &&S_default, &&S_default, &&S_default,
        &&S_default, &&S_101,     &&S_102,     &&S_default, &&S_default, &&S_default, &&S_default, &&S_default,
        &&S_default, &&S_109,     &&S_default, &&S_default, &&S_default,
    };
    int I;
    int J;
    int P;
    int Fp1;
    Mstart = 0;
    Cmax = 0;
    R[Cbound - 1] = 0;
    R[Cbound - 1].Count = 1;
    R[Cbound] = 0;
    R[Cbound].Code = ']';
    R[Cbound].Count = Stopper + 1;
    Macpos = 0;
    Macstore[1] = Nl;
    Macstore[65] = Nl;
    Macstore[129] = Nl;
    Macstore[192] = Nl;
    Casemask = ~Casebit;
    Width = 80;
    Dir = 0;
    Newtop = New.Top;
    Gaptop = Newtop;
    Newlim = New.Lim;
    Fp = Old.Top;
    Gaplim = Fp;
    Lbeg = Fp;
    Lend = Fp;
    Flim = Old.Lim;
    while (Lend != Flim && *Byteinteger(Lend) != Nl) Lend++;
    Sin = 0;
    Sfp = Sec.Top;
    Slim = Sec.Lim;
    Changemin = Newlim;
    Changelbeg = 0;
    Joins = 0;
    Breaks = 0;
    Line = 1;
    Winline = 0;
    Limline = 999999;
    Getdimensions(Rows, Cols);
    Winlim = Rows - 4;
    Cols--;
    Winlim = Rows - 2;
    Winbot = Winlim - 1;
    Wintop = Winbot;
    Minwin = Rows - 2;
    Winline = -999;
    Vrow = 999;
    if (Video) Newlines(Rows - Winlim - 2);
    {
      _imp_string S;
      P = Video & 7;
      Prom = Proms[P];
      Gprom = Gproms[P];
      if (*Charno(Gprom, 1) == '^') *Charno(Gprom, 1) = Esc;
      for (J = 1; J <= *Length(Prom); J++)
        if (*Charno(Prom, J) == '^') *Charno(Prom, J) = Esc;
      if (Video == Vt52 || Video == Bantam) {
        *Charno(Prom, 3) = ' ' + Winlim;
        Videoinvert = _imp_join(Tostring(Esc), _imp_str_literal("4"));
        Videorestore = _imp_join(Tostring(Esc), _imp_str_literal("3"));
        if (Video == Bantam) {
          *Charno(Prom, 4) = Rt;
          *Charno(Prom, 7) = Rt;
        }
      } else if (Video == Win32console) {
        Videoinvert = _imp_join(Tostring(Esc), _imp_str_literal("[7m"));
        Videorestore = _imp_join(Tostring(Esc), _imp_str_literal("[0m"));
      } else if (Video == Vt100) {
        S = Digits(Winlim + 2);
        *Charno(Prom, 3) = *Charno(S, 1);
        *Charno(Prom, 4) = *Charno(S, 2);
        Videoinvert = _imp_join(Tostring(Esc), _imp_str_literal("[1;7m"));
        Videorestore = _imp_join(Tostring(Esc), _imp_str_literal("[m"));
      } else if (Video == Vc404)
        Prom = _imp_join(Tostring(Dle),
                         _imp_join(_imp_str_literal("4"), _imp_join(Tostring(' ' + Winlim),
                                                                    _imp_join(Tostring(0x16), _imp_str_literal(">")))));
    }
    Clearscreen();
    Sym = Nl;
  Read:;
    if (!Sin)
      Prompt(Prom);
    else
      Prompt(_imp_join(Prom, _imp_str_literal(">")));
    Pend = 0;
    Sym1 = Sym;
    if (Sym == Nl) {
      if (!Video) {
        Num = 1;
        if ((Mon == 0 && Printline != Line) || (Mon > 0 && Printed != Gaptop + Fp)) Display();
      } else {
        Display();
        Fprow = Line - Winline + Wintop;
        At(Fprow, Fp - Lbeg);
        if (Video > 0) {
          if (Video == Bantam) {
            Printsymbol(Esc);
            Printsymbol(127);
          } else
            Printsymbol('^');
          Sym1 = ' ';
          if (Fp != Lbeg)
            if (Fp != Gaplim)
              Sym1 = *Byteinteger(Fp - 1);
            else
              Sym1 = *Byteinteger(Gaptop - 1);
        } else {
          Printstring(Videoinvert);
          Sym1 = ' ';
          Sym = '|';
          if (Fp != Lend && *Byteinteger(Fp) != ' ') {
            Sym1 = *Byteinteger(Fp);
            Sym = Sym1;
          }
          Printsymbol(Sym);
          Printstring(Videorestore);
        }
        Newline();
      }
      if (Video == Win32console) {
        At(Winlim, 0);
        Clearline();
      }
    } else {
      Readsym();
      if (Sym != Nl) Pend = Sym;
    }
    Ci = 0;
    Ti = 0;
    Chain = 0;
    Echo = 0;
    for (;;) {
      Readitem();
      if (Sym != '-') break;
      Dir = Dir ^ Casebit;
    }
    if (Type == 1) {
      R[Cbound - 1].Code = 'M' + Dir;
      Ci = Cbound - 2;
      goto Restore;
    }
    if (Type == 0 && Cmax != 0) {
      R[Cmax].Count = Num;
      Readitem();
      if (Type != 1) goto Er1;
      goto Restore;
    }
    if (Sym == '%') {
      Readsym();
      if (Sym < 'A') goto Erq;
      Code = Sym & 95;
      Readsym();
      goto *Pc[Pc_sw = (unsigned)Symtype[Code] >> 4 & 7];
    }
    Dir = 0;
    if (Video > 0) {
      Clearline();
      Printsymbol('=');
      Printsymbol(Sym);
      Echo = 1;
    }
  More:;
    Hold = Type;
    if (Hold < 4) goto Er2;
    if (Hold < 8 && Newtop == 0) goto Er0;
    Ci++;
    if (Ci >= Cbound - 3) goto Er6;
    Code = Sym;
    Ref = 0;
    Num = 1;
    Scope = 1;
    Readitem();
    goto *C[C_sw = (Hold)-4];
  C_8:;
    Minus();
    Scope = 0;
  C_4:;
  C_9:;
    if (!Type) {
      Scope = Num;
      Readitem();
    }
    Num = 0;
  C_5:;
    Hold = Sym;
    if (Type != 3) goto Er4;
    Ti++;
    Ref = Ti;
    for (;;) {
      Readsym();
      if (Sym == Nl) {
        if (!Num) goto Er4;
        Pend = Sym;
        Sym = Hold;
      }
      if (Sym == Hold) break;
      if (Ti > Tbound - 2) goto Er6;
      if ('a' <= Sym && Sym <= 'z' && Num == 0) Sym = Sym & Casemask;
      Text[Ti] = Sym;
      Ti++;
    }
    if (Ti == Ref && Num == 0) goto Er4;
    Text[Ti] = 0;
    Num = 1;
    Readitem();
    goto Nput;
  C_6:;
  C_10:;
    Minus();
  C_7:;
  C_11:;
    if (Type == 3) goto Er1;
    goto Nput;
  C_12:;
    Code = '[';
    goto Comma;
  C_13:;
    Code = '^';
  Comma:;
    Ref = Chain;
    Chain = Ci;
    goto Put;
  C_14:;
    Unchain();
    if (!Ref) goto Er3;
    Code = ']';
    R[Ref].Count = Num;
  Nput:;
    if (!Type) Readitem();
  C_15:;
  Put:;
    R[Ci].Code = Code;
    R[Ci].Ref = Ref;
    R[Ci].Scope = Scope;
    R[Ci].Count = Num;
    if (Type != 1) goto More;
    Ci++;
    Cmax = Ci;
    Unchain();
    if (Ref) goto Er3;
    R[Ci].Code = ']';
    R[Ci].Ref = 0;
    R[Ci].Count = 1;
    Ci = 0;
    if (Video == Win32console) At(Winlim, 0);
    Insertline(Winlim);
  Restore:;
    if (Sym1 != Nl) {
      At(Fprow, Fp - Lbeg);
      Printsymbol(Sym1);
    }
    goto Next;
  Er0:
    Printsymbol(' ');
    Printcode(Sym);
    Printstring(_imp_str_literal(" when Showing"));
    goto Erq;
  Er1:
    Printsymbol(' ');
    Printsymbol(Code);
  Er2:
    Code = Sym;
    goto Er5;
  Er3:
    Printstring(_imp_str_literal(" Brackets"));
    goto Erq;
  Er4:
    Printstring(_imp_str_literal(" Text for"));
  Pc_0:;
  Er5:
    Printsymbol(' ');
    Printcode(Code);
    goto Erq;
  Er6:
    Printstring(_imp_str_literal(" Size"));
  Erq:
    Printsymbol('?');
    if (Video)
      Clearline();
    else
      Newline();
    if (Ci > 1) Cmax = 0;
    Ignore();
    goto Read;
  Pc_1:;
    if (Sin) Switch();
    if (Changelbeg) New.Flag = 1;
    New.Lim = Gaptop;
    Old.Top = Gaplim;
    Old.Lim = Flim;
    Clearscreen();
    return;
  Pc_2:;
    if (Sin) Switch();
    if (Sym == '=') {
      I = 0;
      for (;;) {
        Readsym();
        if (Sym == ';' || Sym == Nl) break;
        if (I == Maxname) goto Er6;
        I++;
        *Charno(Sec.Name, I) = Sym;
      }
      *Length(Sec.Name) = I;
      Connectinput(*Sec);
    }
    Sfp = Sec.Top;
    Slim = Sec.Lim;
    if (Sec.Top == Sec.Lim) goto Erq;
    Switch();
    goto Read;
  Pc_3:;
    Casemask = ~Casebit;
    if (Sym == '-') {
      Casemask = ~0;
      Readsym();
    }
    goto Read;
  Pc_4:;
    if (Code == 'M') {
      Mon = 0;
      if (Sym == '+') {
        Mon = 1;
        Readsym();
      }
      if (Sym == '-') {
        Mon = -1;
        Readsym();
      }
    } else {
      Readitem();
      if (Type) goto Erq;
      Video = ((Num & 0xC) << 28) + (Num & 7);
      Winline = -99;
    }
    goto Read;
  Pc_5:;
    if (Sym == '=') {
      Readitem();
      if (Type) goto Erq;
      if (Num > Winlim) goto Er6;
      Minwin = Num;
      if (Num <= 0) Video = 0;
    }
    Winline = -99;
    goto Read;
  Pc_6:;
    if (Sym != '=') goto Erq;
    Readitem();
    if (Type) goto Erq;
    if (5 > Num || Num > 256) goto Er6;
    Width = Num;
    goto Read;
  Pc_7:;
    I = ((Code - 'W') << 6) + 1;
    if (Sym == '=')
      for (;;) {
        Readsym();
        Macstore[I] = Sym;
        if (Sym == Nl) break;
        if (I != 255) I++;
      }
    else {
      if (Sym != Nl) goto Er1;
      Printsymbol(Code);
      Printsymbol('=');
      for (;;) {
        Sym = Macstore[I];
        if (Sym == Nl) break;
        Printsymbol(Sym);
        I++;
      }
      if (Video)
        Clearline();
      else
        Newline();
    }
    goto Read;
    int Matched(void) {
      int I;
      int J;
      int K;
      I = Fp - 1;
      J = Ref - 1;
      do {
        I++;
        J++;
        K = *Byteinteger(I);
        if ('a' <= K && K <= 'z') K = K & Casemask;
      } while (K == Text[J]);
      if (Text[J]) return (0);
      Mstart = Fp;
      Msize = I - Fp;
      return (1);
    }
  Next:
  S_63:;
    Ci++;
    Code = R[Ci].Code;
    Ref = R[Ci].Ref;
    Num = R[Ci].Count;
    goto *S[S_sw = (Code)-36];
  Lok:;
    Lend = Fp;
    if (Lend != Flim)
      while (*Byteinteger(Lend) != Nl) Lend++;
  Ok:;
    Num--;
    if (!Num) goto Next;
    goto *S[S_sw = (Code)-36];
  Fail:;
    Num = 1;
  No:
  S_92:;
    do {
      if (Num <= 0) goto Next;
      Ci++;
      if (R[Ci].Code == '\\') goto Next;
      if (R[Ci].Code == '?') goto Next;
      while (R[Ci].Code != ']') {
        if (R[Ci].Code == '^') goto Next;
        if (R[Ci].Code == '[') Ci = R[Ci].Ref;
        Ci++;
      }
      Num = R[Ci].Count;
    } while (Ci < Cmax);
    if (Num <= 0) goto Read;
    At(Winlim + 1, 40);
    Printstring(_imp_str_literal(" Failure: "));
    Printcode(Code);
    if (Ref) {
      Printsymbol('\'');
      while (Text[Ref]) {
        Printsymbol(Text[Ref]);
        Ref++;
      }
      Printsymbol('\'');
    }
    if (Video)
      Clearline();
    else
      Newline();
    Ignore();
    goto Read;
  S_91:;
    R[Ref].Count = Num;
    goto Next;
  S_93:;
    Num--;
    if (Num != 0 && Num != Stopper) {
      R[Ci].Count = Num;
      Ci = Ref;
    } else if (Ci >= Cmax)
      goto Read;
    goto Next;
  S_94:;
    Ci = Ref - 1;
    goto Next;
  S_80:;
    Display();
    if (Num == 1) goto Ok;
  S_77:;
    if (Fp == Flim) goto No;
    Update();
    Fp = Lend + 1;
    if (Fp == Gaptop) Fp = Gaplim;
    Line++;
    if (Num == 0 && Code == 'M') {
      Fp = Flim;
      Line = Limline;
    }
    Lbeg = Fp;
    goto Lok;
  S_109:;
    if (Lbeg == Newtop || Sin != 0) goto No;
    Update();
    Consolidate();
    Mstart = 0;
    if (!Num) {
      Lbeg = Newtop;
      if (Lbeg == Gaptop) Lbeg = Gaplim;
      Fp = Lbeg;
      Line = 1;
      Num = 1;
      goto Lok;
    }
    if (Lbeg == Gaplim) {
      if (Gaptop == Newtop) goto No;
      Lbeg = Gaptop;
    }
    Line--;
    Lend = Lbeg - 1;
    do
      Lbeg--;
    while (Lbeg != Gaplim && Lbeg != Newtop && *Byteinteger(Lbeg - 1) != Nl);
    Fp = Lbeg;
    goto Ok;
  S_67:;
    if (Fp == Lend) goto No;
    if ('A' <= (*Byteinteger(Fp) & 95) && (*Byteinteger(Fp) & 95) <= 'Z') {
      Split();
      *Byteinteger(Gaptop) = *Byteinteger(Fp) ^ Casebit;
      Gaptop++;
      Gaplim++;
    }
  S_82:;
    if (Fp == Lend) goto No;
    Fp++;
    goto Ok;
  S_76:;
    if (Fp == Lbeg || Sin != 0) goto No;
    if (Fp == Gaplim) Consolidate();
    Mstart = 0;
    Fp--;
    goto Ok;
  S_69:;
    if (Fp == Lend) goto No;
    Split();
    Lbeg++;
    Fp++;
    Gaplim = Fp;
    goto Ok;
  S_101:;
    if (Fp == Lbeg) goto No;
    Split();
    Lbeg++;
    Gaptop--;
    if (Gaptop < Changemin) Changemin = Gaptop;
    goto Ok;
  S_86:;
    if (Fp == Lend) goto No;
    if ((*Byteinteger(Fp) ^ Text[Ref]) & Casemask) goto No;
    if (!Matched()) goto No;
    goto Next;
  S_68:;
  S_84:;
    Fp1 = Fp;
    goto Find;
  S_70:;
  S_85:;
    Fp1 = Fp;
    if (Fp == Mstart) Fp++;
  Find:;
    Scope = R[Ci].Scope;
    Sym1 = Text[Ref];
    while (Fp != Flim) {
      while (*Byteinteger(Fp) != Nl) {
        if (!((*Byteinteger(Fp) ^ Sym1) & Casemask))
          if (Matched()) goto Found;
        Fp++;
      }
      Lend = Fp;
      Scope--;
      if (!Scope) break;
      if (Code != 'U') {
        Update();
        Fp++;
        if (Fp == Gaptop) Fp = Gaplim;
        Lbeg = Fp;
        Line++;
      } else {
        Fp = Fp1;
        Join();
      }
      Fp1 = Fp;
    }
    Lend = Fp;
    Fp = Fp1;
    goto No;
  Found:;
    if (Code == 'D') {
      Split();
      Lbeg += Msize;
      Fp += Msize;
      Gaplim = Fp;
    }
    if (Code == 'T') Fp += Msize;
    if (Code == 'U') {
      I = Fp - Fp1;
      Fp = Fp1;
      Split();
      Lbeg += I;
      Fp += I;
      Gaplim = Fp;
    }
    goto Lok;
  S_102:;
    Scope = R[Ci].Scope;
    Update();
    Consolidate();
    for (;;) {
      while (Fp != Lbeg) {
        Fp--;
        if (Matched()) goto Ok;
      }
      Scope--;
      if (Scope == 0 || Fp == Newtop) goto No;
      if (Fp == Gaplim) {
        if (Gaptop == Newtop) goto No;
        Fp = Gaptop;
      }
      Lbeg = Fp;
      Fp--;
      Lend = Fp;
      Line--;
      do
        Lbeg--;
      while (Lbeg != Gaplim && Lbeg != Newtop && *Byteinteger(Lbeg - 1) != Nl);
    }
  S_83:;
    if (Fp != Mstart) goto No;
    Split();
    Lbeg += Msize;
    Fp += Msize;
    Gaplim = Fp;
  S_73:;
    if (!Text[Ref]) goto Ok;
    if (Fp - Lbeg > Width || Fp == Flim) goto No;
    Split();
    J = Ref;
    do {
      *Byteinteger(Gaptop) = Text[J];
      Gaptop++;
      J++;
    } while (Text[J]);
    Lbeg -= J - Ref;
    goto Ok;
  S_71:;
    if (Sin != 0 && Fp != Lbeg) goto No;
    Consolidate();
    Fp = Lbeg;
    Split();
    if (Video) {
      if (Video < 0) {
        Display();
        Fprow = Line - Winline + Wintop;
        Deleteline(Winlim);
        Insertline(Fprow);
      } else {
        *Byteinteger(Gaptop) = Nl;
        Gaptop++;
        Breaks++;
        Line++;
        Limline++;
        Update();
        Fp = Gaptop - 1;
        Lbeg = Fp;
        Line--;
        Display();
        Fprow = Line - Winline + Wintop;
        Gaptop--;
        Fp = Gaplim;
        Lbeg = Fp;
        Limline--;
        At(Fprow, 0);
      }
    }
    Prompt(Gprom);
    Readsym();
    Vrow = 999;
    if (Sym == ':') {
      do
        Readsym();
      while (Sym != Nl);
      if (Video)
        if (Video < 0) {
          Deleteline(Fprow);
          Insertline(Winlim);
        } else {
          Changemin = Gaptop;
          Changelbeg = Lbeg;
          Joins++;
        }
      goto No;
    }
    Line++;
    Limline++;
    for (;;) {
      *Byteinteger(Gaptop) = Sym;
      Gaptop++;
      if (Sym == Nl) break;
      Readsym();
    }
    if (Video < 0 && Fprow == Winbot) {
      Deleteline(Zrow);
      if (Wintop > Zrow)
        Wintop--;
      else
        Winline++;
      Insertline(Winlim);
    }
    goto Ok;
  S_66:;
    if (Num == 0 || Num > 66) Num = 66;
    Split();
  Break:;
    *Byteinteger(Gaptop) = Nl;
    Gaptop++;
    Breaks++;
    Line++;
    Limline++;
    Lbeg = Fp;
    goto Ok;
  S_75:;
    if (Fp == Flim) goto No;
    Fp = Lbeg;
    Join();
    goto Lok;
  S_74:;
    Fp = Lend;
    if (Fp == Flim || Fp - Lbeg > Width) goto No;
    Join();
    goto Lok;
  S_65:;
    if (Lend == Lbeg) goto *S[S_sw = ('M') - 36];
    Consolidate();
    while (Lend - Lbeg <= Width) {
      Fp = Lend + 1;
      if (Fp == Gaptop) {
        Fp = Gaplim;
        Lbeg += Gaplim - Gaptop;
      }
      Lend = Fp;
      while (Lend != Flim && *Byteinteger(Lend) != Nl) Lend++;
      if (Fp == Lend || *Byteinteger(Fp) == ' ') {
        Update();
        Lbeg = Fp;
        Line++;
        goto No;
      }
      Split();
      *Byteinteger(Gaptop - 1) = ' ';
      if (Changemin >= Gaptop) Changemin = Gaptop - 1;
      Joins++;
      Limline--;
    }
    Consolidate();
    Fp = Lbeg + Width + 1;
    do {
      Fp--;
      if (Fp == Lbeg) goto No;
    } while (*Byteinteger(Fp) != ' ');
    Split();
    Fp++;
    Gaplim = Fp;
    goto Break;
  S_64:;
    if (Lend == Flim) goto Fail;
    I = Width - (Lend - Fp);
    if (I < Num) Num = I;
    I = Fp - Lbeg - Num;
    if (!I) goto Next;
    Split();
    do
      if (I < 0) {
        *Byteinteger(Gaptop) = ' ';
        Gaptop++;
        Lbeg--;
        I++;
      } else {
        if (Fp == Lbeg || *Byteinteger(Gaptop - 1) != ' ') goto Fail;
        Gaptop--;
        Lbeg++;
        if (Gaptop < Changemin) Changemin = Gaptop;
        I--;
      }
    while (I);
    goto Next;
  S_36:;
    Switch();
    goto Next;
    goto S_skip;
  S_default:
    fprintf(stderr, "\nSwitch label 'S(%d):' not set in %s\n", S_sw + 36, __PRETTY_FUNCTION__);
    fflush(stderr);
    abort();
  S_skip:;
  }
  Selectinput(0);
  Selectoutput(0);
  void Move(int Length, int From, int To) {
    if (From == To) return;
    if (To <= From)
      while (Length > 0) {
        *Byteinteger(To) = *Byteinteger(From);
        From++;
        To++;
        Length--;
      }
    else {
      From += Length;
      To += Length;
      while (Length > 0) {
        From--;
        To--;
        *Byteinteger(To) = *Byteinteger(From);
        Length--;
      }
    }
  }
  void Connectinput(File * F) {
    void Free(int A);
    int Readin(int Fnameaddr, int Extra, int *Base, int *Top, int *Fend, int *Limit);
    _imp_string Fname;
    if (F.Vmtop) Free(F.Vmtop);
    Fname = _imp_join(F.Name, Tostring(0));
    F.Flag = Readin(Addr(Fname) + 1, F.Flag, F.Vmtop, F.Top, F.Lim, F.Vmlim);
    if (F.Flag) {
      F.Vmtop = 0;
      F.Top = 0;
      F.Lim = 0;
    }
    while (F.Lim != F.Top && *Byteinteger(F.Lim - 1) != Nl) F.Lim = F.Lim - 1;
  }
  int I;
  int F;
  int L;
  int Sym;
  int Default;
  File In;
  File Sec;
  File Out;
  In = 0;
  Sec = 0;
  Out = 0;
  L = 0;
  int /* boolean */ Null(_imp_string Fname) {
    Toupper(Fname);
    if (_imp_strcmp(Fname, _imp_str_literal("NUL")) == 0 || _imp_strcmp(Fname, _imp_str_literal("NUL:")) == 0 ||
        _imp_strcmp(Fname, _imp_str_literal("NULL:")) == 0)
      return (1);
    return (0);
  }
  int Termtype(void) {
    void Initconsole(void);
    Initconsole();
    return (Win32console);
  }
  if (Argc <= 1 || Argc > 3 || (Argc == 2 && _imp_strcmp(Argv, _imp_str_literal("/?")) == 0)) {
    Printstring(_imp_str_literal(
        "Visual version of Edinburgh Compatible Context Editor (ECCE):\n\n  VECCE infile [outfile]\n"));
    Printstring(
        _imp_str_literal("\n  VECCE nul newfile       to create newfile\n  VECCE oldfile nul       view existing "
                         "oldfile, don't modify\n  VECCE oldfile           to modify existing oldfile\n  VECCE oldfile "
                         "newfile   read oldfile, edit into newfile\n"));
    Printstring(_imp_str_literal("\nYou can use NUL: or NULL: in place of nul (case not significant).\n"));
    exit(0);
  }
  In.Name = Argv;
  if (Argc == 3) {
    Default = 0;
    Out.Name = Argv;
  } else {
    Default = 1;
    Out.Name = In.Name;
  }
  if (Null(Out.Name)) {
    Connectinput(In);
    if (In.Flag) exit(0);
    Newlines(2 * 25);
    Printstring(_imp_join(_imp_str_literal("= Showing  "), In.Name));
  } else {
    In.Flag = 100;
    Connectinput(In);
    if (In.Flag) exit(0);
    if (_imp_strcmp(Sec.Name, _imp_str_literal("")) != 0) {
      Connectinput(Sec);
      if (Sec.Flag) exit(0);
    }
    Out.Top = In.Vmtop;
    Out.Lim = In.Lim;
    Newlines(2 * 25);
    if (!Null(In.Name)) {
      Printstring(_imp_join(_imp_str_literal("= Editing  "), In.Name));
      if (!Default) {
        Printstring(_imp_str_literal("  to  "));
        Printstring(Out.Name);
      }
    } else
      Printstring(_imp_join(_imp_str_literal("= Creating  "), Out.Name));
  }
  Edi(In, Sec, Out, Termtype(), 25, 79);
  if (Default != 0 && Out.Flag == 0) {
    Printstring(_imp_str_literal(" File unchanged"));
    Spaces(79 - 15);
    Newline();
    Out.Top = 0;
  }
  if (Out.Top) {
    I = In.Lim - In.Top;
    Move(I, In.Top, Out.Lim);
    Out.Lim = Out.Lim + I;
    Openoutput(3, Out.Name);
    Selectoutput(3);
    for (I = Out.Top; I <= Out.Lim - 1; I++) Printsymbol(*Byteinteger(I));
    Closeoutput();
  }
}
