home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / EFFO / forum7.lzh / C / VC / sc.c < prev    next >
Text File  |  1988-09-23  |  17KB  |  892 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Main driver
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *        
  8.  *        Adapted to Os-9  August 1988 by Uwe Simon  West-Germany
  9.  */
  10.  
  11.  
  12. #include <signal.h>
  13. #include "vc.h"
  14. #include <stdio.h>
  15.  
  16. /* default column width */
  17.  
  18. #define DEFWIDTH 10
  19. #define DEFPREC   2
  20.  
  21. extern int        lines;
  22. extern int        colms;
  23.  
  24.  
  25. char curfile[1024];
  26. char field[1024];
  27. char hilf[80];          /* merker bei insertmodus */
  28. int     ins =0;            /* insertmode */
  29. int batch;
  30.  
  31. error (fmt,a,b,c,d,e) {
  32.     if (batch) fprintf(stderr,fmt,a,b,c,d,e);
  33.     else 
  34.     {
  35.         gotoXY (0,1);
  36.         printf (fmt,a,b,c,d,e);
  37.         cleoln (); 
  38.     }
  39. }
  40.  
  41. int seenerr;
  42.  
  43. yyerror (err)
  44. char *err; {
  45.     char  h[80];
  46.     
  47.     if (seenerr)
  48.         return;
  49.  
  50.     seenerr++;
  51.     gotoXY (0,1);
  52.     sprintf (h, "%%s: %%.%ds<=%%s",linelim);
  53.     printf (h, err, line, line+linelim);
  54.     cleoln ();
  55. }
  56.  
  57. struct ent *lookat(row,col){
  58.     register struct ent **p;
  59.     
  60.     p = &tbl[row][col];
  61.     if (*p==0) {
  62.         *p = (struct ent *) malloc (sizeof (struct ent));
  63.         
  64.         if (row>maxrow) 
  65.             maxrow = row;
  66.             
  67.         if (col>maxcol) 
  68.             maxcol = col;
  69.             
  70.         (*p)->label = 0;
  71.         (*p)->flags = 0;
  72.         (*p)->row = row;
  73.         (*p)->col = col;
  74.         (*p)->expr = 0;
  75.     }
  76.     return *p;
  77. }
  78.  
  79. update_field(p,r,c,row,col,opt)
  80. struct ent *p;
  81. int r;
  82. int c;
  83. int row;
  84. int col;
  85. int opt;
  86. {
  87.     char   *s;
  88.     char h[30];
  89.     
  90.     gotoXY (c, r);
  91.     if(p)
  92.     {
  93.         p-> flags &= ~is_changed;
  94.         if (p -> flags & is_valid)
  95.         {
  96.             sprintf(h,"%%%d.%df",fwidth[col],precision[col]);
  97.             printf (h, p -> v);
  98.             fflush(stdout);
  99.         }
  100.         else
  101.         if (s = p -> label)
  102.         {
  103.             strncpy(field,s,fwidth[col]);
  104.             field[fwidth[col]] = 0;
  105.             if(p->flags & is_leftflush)
  106.                 sprintf(h,"%%%ds",fwidth[col]);
  107.             else
  108.                 sprintf(h,"%-%%ds",fwidth[col]);
  109.  
  110.             printf(h,field); 
  111.             fflush(stdout);
  112.         }
  113.         else
  114.         {
  115.             sprintf(h,"%-%%ds",fwidth[col]);
  116.             printf(h," "); 
  117.             fflush(stdout);
  118.         }
  119.         return;
  120.     }    
  121.     if(opt || (p == 0))
  122.     {
  123.         sprintf(h,"%%%ds",fwidth[col]);
  124.         printf(h," ");
  125.         fflush(stdout);
  126.     }
  127.     
  128. }
  129.  
  130.  
  131. select_field(mode)
  132. int mode;
  133. {
  134.     int col;
  135.     int  lastmx;
  136.     int  lastmy;
  137.  
  138.     lastmy = currow - strow + 3;
  139.     lastmx = 4;
  140.     for (col = stcol; col <= curcol;)
  141.     lastmx += fwidth[col++];
  142.     if(mode)
  143.         sout_on();
  144.         
  145.     update_field(tbl[currow][curcol],lastmy, lastmx - fwidth[curcol], currow, curcol,1);
  146.     if(mode)
  147.         mvaddstr (lastmy, lastmx, "<");
  148.     else
  149.         mvaddstr (lastmy, lastmx, " "); 
  150.         
  151.     sout_off();
  152.     gotoXY(lastmx, lastmy);
  153.  
  154. }
  155.  
  156.  
  157. update () {
  158.     register    row,
  159.                 col;
  160.     register struct ent **p;
  161.     int     maxcol;
  162.     int     rows;
  163.     int     cols;
  164.  
  165.     rows = lines -3;
  166.     
  167.     if (curcol < stcol)
  168.     stcol = curcol, FullUpdate++;
  169.     if (currow < strow)
  170.     strow = currow, FullUpdate++;
  171.     while (1) {
  172.     register    i;
  173.     for (i = stcol, cols = 0, col = 4;
  174.          (col + fwidth[i]) < colms && i < MAXCOLS;
  175.          i++)
  176.         col += fwidth[i], cols++;
  177.     if (curcol >= stcol + cols)
  178.         stcol++, FullUpdate++;
  179.  
  180.     else
  181.         break;
  182.     }
  183.     if (currow >= strow + rows)
  184.         strow = currow - rows + 2, FullUpdate++;
  185.         
  186.     maxcol = stcol + cols - 1;
  187.  
  188.     if (FullUpdate)
  189.     {
  190.         int i,h;
  191.         gotoXY (0,2);
  192.         cleop();
  193.         unsc_on();
  194.         printf("r\\c| ");
  195.         for( i=stcol;i<=maxcol; i++)
  196.         {
  197.             char h[80];
  198.             sprintf(h,"%%%dd|",fwidth[i]-1);
  199.             printf(h,i);
  200.         }
  201.         fflush(stdout);    
  202.  
  203.         unsc_off();    
  204.     }
  205.     
  206.     for (row = strow + rows - 1; row >= strow; row--) {
  207.         register    c = 4;
  208.         register    int r;
  209.         
  210.         r = row - strow + 3;
  211.         if(FullUpdate)
  212.         {
  213.             gotoXY(0,r);
  214.             printf("%3d|",row);
  215.             fflush(stdout);
  216.         }
  217.     for (p = &tbl[row][col = stcol]; col <= maxcol; col++, p++) {
  218.         if (*p && ((*p) -> flags & is_changed || FullUpdate)) {
  219.             update_field(*p,r,c,row,col,0);
  220.         
  221.         }
  222.         c += fwidth[col];
  223.     }
  224.     }
  225.     select_field(1);
  226.     gotoXY (0, 0);
  227.     if (line[0]) 
  228.     {
  229.         printf("%s %s ", ins?">>":"->", line);
  230.     }
  231.  
  232.         
  233.     FullUpdate = 0;
  234.     
  235.     fflush(stdout);
  236. }
  237.  
  238.  
  239. #define ctl(c) ('c' & 0x1f)
  240.             /* non-meta getchar */
  241. #define nmgetch() (getchar() & 0x7f)
  242.  
  243. main (argc, argv)
  244. char  **argv; {
  245.     int     inloop;
  246.     register int   c;
  247.     int     edistate;
  248.     int     arg;
  249.     int     narg;
  250.     int     nedistate;
  251.     int        running;
  252.     char    h[80];
  253.  
  254.     inloop = 1; edistate = -1; nedistate = -1; running =1; arg = 1;
  255.     linelim = -1; changed = 0;
  256.     
  257.     {
  258.     register    i;
  259.     batch = 0;
  260.     for (i = 0; i < MAXCOLS; i++) {
  261.         fwidth[i] = DEFWIDTH;
  262.         precision[i] = DEFPREC;
  263.     }
  264.     }
  265.     curfile[0]=0;
  266.     stdin->_flag |= _UNBUF;
  267.     set_up("TERM");
  268.     
  269.     if (argc > 1 && (! strcmp(argv[1],"-b"))) {
  270.         argc--, argv++;
  271.         batch = 1;
  272.     }
  273.  
  274.     if (! batch) {
  275.         clscr();
  276. /*    initscr();
  277.     clear ();
  278.     raw (); */
  279.     filter_off (); 
  280.     }
  281.     
  282.     if (argc > 1) {
  283.         strcpy(curfile,argv[1]);
  284.         readfile (argv[1],0);    }
  285.     
  286.     modflg = 0;
  287.     FullUpdate =1;
  288.     
  289.     if (batch) exit(0);
  290.     
  291.     error ("Welcome to the Spreadsheet Calculator, type '?' for help.");
  292.     while (inloop) { running = 1;
  293.     while (running) {
  294.         nedistate = -1;
  295.         narg = 1;        if (edistate < 0 && linelim < 0 && (changed || FullUpdate))
  296.             EvalAll (), changed = 0;
  297.  
  298.         if(ins)
  299.         {
  300.             line[linelim] =0;
  301.             strcat(line,hilf);
  302.         }
  303.         else
  304.             hilf[0]=0;
  305.                     
  306.         update ();
  307. /*    refresh (); */
  308.  
  309.         if(linelim>=0)
  310.             gotoXY(linelim+3,0);
  311.         else
  312.             gotoXY(0,0);
  313.         
  314.         c = nmgetch ();
  315.         if(seenerr)
  316.         {
  317.             gotoXY(0,1);
  318.             cleoln();
  319.         }
  320.         seenerr = 0;
  321.         if(ins)
  322.         {
  323.             if(linelim >=0)
  324.                 strcpy(hilf, &line[linelim]);
  325.                else
  326.                    hilf[0]=0;
  327.            }
  328.  
  329.         if (c < ' ')
  330.         {
  331.             if((c!= ctl(v)) && (c != ctl(e)) && (c!= ctl(h)))
  332.                 select_field(0);
  333.                 
  334.         switch (c) {
  335.         case ctl (z):
  336. /*            noraw (); */
  337.             filter_on ();
  338. /*            kill(getpid(),SIGTSTP); */
  339.  
  340.             /* the pc stops here */
  341.             clscr();
  342.             exit(0);
  343. /*            raw (); */
  344.             filter_off ();
  345.             break;
  346.         case ctl (r):
  347.             FullUpdate++;
  348. /*            clearok(stdscr,1); */
  349.             break;
  350.         default:
  351.             error ("No such command  (^%c)", c + 0100);
  352.             break;
  353.         case ctl (b):
  354.             while (--arg>=0) if (curcol)
  355.             curcol--;
  356.             break;
  357.         case ctl (c):
  358.             running = 0;
  359.             break;
  360.         case ctl (f):
  361.             while (--arg>=0) if (curcol < MAXCOLS - 1)
  362.             curcol++;
  363.             break;
  364.         
  365.         case ctl (d):
  366.             if(linelim >= 0)
  367.             {
  368.                 if(line[linelim])
  369.                     strcpy(&line[linelim], &line[linelim+1]);
  370.                 else            
  371.                     linelim--;
  372.             }
  373.             break;
  374.             
  375.         case ctl ([):
  376.             ins =0;
  377.             linelim = -1;
  378.             gotoXY (0,0);
  379.             cleoln ();
  380.             gotoXY (0,1);
  381.             cleoln ();
  382.             break;
  383.             
  384.         case ctl (k):
  385.             if((linelim >= 0) &&line[linelim])
  386.                 linelim++;
  387.             break;
  388.                 
  389.         case ctl (h):
  390.             if (linelim > 0)
  391.                 linelim--;
  392.  
  393.             break;
  394.             
  395.         case ctl(i):
  396.             ins = 1-ins;
  397.             if(ins)
  398.             {
  399.                 if(linelim >=0)
  400.                     strcpy(hilf, &line[linelim]);
  401.                    else
  402.                        hilf[0]=0;
  403.                }
  404.             break;
  405.             
  406.         case ctl (j):
  407.             if (currow >= MAXCOLS - 1 || maxcol >= MAXCOLS - 1)
  408.             {
  409.                 error ("The table can't be any bigger");
  410.                 break;
  411.             }
  412.             modflg++;
  413.             currow++;
  414.             openrow (currow);
  415.             for (curcol = 0; curcol <= maxcol; curcol++) 
  416.             {
  417.                 register struct ent *p;
  418.     
  419.                 p = tbl[currow - 1][curcol];
  420.                 if (p)
  421.                 {
  422.                     register struct ent *n;
  423.                     n = lookat (currow, curcol);
  424.                     n -> v = p -> v;
  425.                     n -> flags = p -> flags;
  426.                     n -> expr = copye (p -> expr, 1, 0);
  427.                     n -> label = 0;
  428.                     if (p -> label)
  429.                     {
  430.                         n -> label = (char *)
  431.                         malloc (strlen (p -> label) + 1);
  432.                         strcpy (n -> label, p -> label);
  433.                     }
  434.                 }
  435.             }
  436.             for (curcol = 0; curcol <= maxcol; curcol++)
  437.             {
  438.                 register struct ent *p = tbl[currow][curcol];
  439.                 if (p && (p -> flags & is_valid) && !p -> expr)
  440.                     break;
  441.             }
  442.             if (curcol > maxcol)
  443.                 curcol = 0;
  444.                 
  445.             break;
  446.             
  447.         case ctl (l):
  448.             FullUpdate++;
  449.             break;
  450.         case ctl (m):
  451.             ins =0;
  452.             if (linelim < 0)
  453.                 line[linelim = 0] = 0;
  454.             else
  455.             {
  456.                 int h;
  457.                 h = linelim;
  458.                 linelim = 0;
  459.                 yyparse ();
  460.                 if(seenerr)
  461.                     linelim = h;
  462.                 else
  463.                 {
  464.                     gotoXY(0,0);
  465.                     cleoln();                
  466.                     linelim = -1;
  467.                 }
  468.             }
  469.             break;
  470.         case ctl (n):
  471.             while (--arg>=0) if (currow < MAXROWS - 1)
  472.             currow++;
  473.             break;
  474.         case ctl (p):
  475.             while (--arg>=0) if (currow)
  476.             currow--;
  477.             break;
  478.         case ctl (q):
  479.             break;    /* ignore flow control */
  480.         case ctl (s):
  481.             break;    /* ignore flow control */
  482.         case ctl (u):
  483.             narg = arg * 4;
  484.             nedistate = 1;
  485.             break;
  486.         case ctl (v):    /* insert variable name */
  487.             if (linelim > 0) {
  488.             sprintf (line + linelim, "r%dc%d", currow, curcol);
  489.             linelim = strlen (line);
  490.             }
  491.             break;
  492.         case ctl (e):    /* insert variable expression */
  493.             if (linelim > 0) editexp(currow,curcol);
  494.             break;
  495.         case ctl (a):    /* insert variable value */
  496.             if (linelim > 0) {
  497.             struct ent *p = tbl[currow][curcol];
  498.  
  499.             if (p && p -> flags & is_valid) {
  500.                 sprintf(h,"%%.%df",precision[curcol]);
  501.                 sprintf (line + linelim, h, p -> v);
  502.                 linelim = strlen (line);
  503.             }
  504.             }
  505.             break;
  506.         }
  507.     }
  508.     else
  509.         if ('0' <= c && c <= '9' && (linelim < 0 || edistate >= 0))
  510.         {
  511.             if (edistate != 0)
  512.                 arg = 0;
  513.             nedistate = 0;
  514.             narg = arg * 10 + (c - '0');
  515.         }
  516.         else
  517.         {
  518.             
  519.                
  520.             if (linelim >= 0) 
  521.             {
  522.                 if(line[linelim] == 0)
  523.                 {
  524.                     line[linelim++] = c;
  525.                     line[linelim] = 0;
  526.                 }
  527.                 else                    
  528.                     line[linelim++] = c;
  529.             }
  530.             else
  531.             {
  532.                 gotoXY(0,0);
  533.                 cleoln();
  534.                 switch (c) 
  535.                 {
  536.                     case '.':
  537.                         nedistate = 1;
  538.                         break;
  539.                         
  540.                     case '=':
  541.                         sprintf (line, "let r%dc%d = ", currow, curcol);
  542.                         linelim = strlen (line);
  543.                         break;
  544.                         
  545.                     case '?':
  546.                         help ();
  547.                         break;
  548.                         
  549.                     case '"':
  550.                         sprintf (line, "label r%dc%d = \"",    currow, curcol);
  551.                         linelim = strlen (line);
  552.                         break;
  553.                         
  554.                     case '<':
  555.                         sprintf (line, "leftstring r%dc%d = \"", currow, curcol);
  556.                         linelim = strlen (line);
  557.                         break;
  558.                         
  559.                     case '>':
  560.                         sprintf (line, "rightstring r%dc%d = \"", currow, curcol);
  561.                         linelim = strlen (line);
  562.                         break;
  563.                         
  564.                     case 'e':
  565.                         editv (currow, curcol);
  566.                         break;
  567.                         
  568.                     case 'E':
  569.                         edits (currow, curcol);
  570.                         break;
  571.                         
  572.                     case 'f':
  573.                         sprintf (line, "format [for column] %d [is] ", curcol);
  574.                         error("Current format is %d %d", fwidth[curcol],precision[curcol]);
  575.                         linelim = strlen (line);
  576.                         break;
  577.                         
  578.                     case 'p':
  579.                         sprintf (line, "put [database into] \"");
  580.                         if (*curfile)
  581.                             error("default file is '%s'",curfile);
  582.                             
  583.                         linelim = strlen (line);
  584.                         break;
  585.                         
  586.                     case 'M':
  587.                         sprintf (line, "merge [database from] \"");
  588.                         linelim = strlen (line);
  589.                         break;
  590.                         
  591.                     case 'g':
  592.                         sprintf (line, "get [database from] \"");
  593.                         if (*curfile)
  594.                             error("default file is '%s'",curfile);
  595.                             
  596.                         linelim = strlen (line);
  597.                         break;
  598.                     case 'w':
  599.                         sprintf (line, "write [listing to] \"");
  600.                         linelim = strlen (line);
  601.                         break;
  602.                         
  603.                     case 'T':    /* tbl output */
  604.                         sprintf (line, "tbl [listing to] \"");
  605.                         linelim = strlen (line);
  606.                         break;
  607.                         
  608.                     case 'r':
  609.                         while (--arg>=0) openrow (currow);
  610.                         
  611.                         break;
  612.                     case 'd':
  613.                         while (--arg>=0) closerow (currow);
  614.                         
  615.                         break;
  616.                         
  617.                     case 'c':
  618.                         while (--arg>=0) opencol (curcol);
  619.                         
  620.                         break;
  621.                     case 'D':
  622.                         while (--arg>=0) closecol (curcol);
  623.                         break;
  624.                         
  625.                     case 'C':
  626.                         clearent(lookat(currow,curcol));
  627.                         FullUpdate++;
  628.                         break;
  629.                         
  630.                     case 'Q':
  631.                         running = 0;
  632.                         break;
  633.                         
  634.                     default:
  635.                         if ((c & 0177) != c)
  636.                             error("Weird character, decimal '%d'.\n", (int) c);
  637.                         else 
  638.                             error ("No such command  (%c)", c);
  639.                         break;
  640.                     }
  641.                 }
  642.             }
  643.             edistate = nedistate;
  644.             arg = narg;
  645.         }                /* while (running) */
  646.         inloop = modcheck(" before exiting");
  647.     }                /*  while (inloop) */
  648.     gotoXY (0, lines - 1);
  649. /*    refresh ();
  650.     noraw (); */
  651.     clscr();
  652.     filter_on ();
  653. /*    endwin (); */
  654. }
  655.  
  656. modcheck(endstr) char *endstr; {
  657.     if (modflg && curfile[0]) {
  658.     char ch, lin[100];
  659.  
  660.     gotoXY (0, 0);
  661.     cleoln ();
  662.     sprintf (lin,"File '%s' is modified, save%s? ",curfile,endstr);
  663.     addstr (lin);
  664. /*    refresh(); */ 
  665.     ch = nmgetch();
  666.     if (ch == 'y' || ch == 'Y') writefile(curfile);
  667.     else if (ch == ctl (g)) return(1);
  668.     }
  669.     return(0);
  670. }
  671.     
  672. writefile (fname)
  673. char *fname; {
  674.     register FILE *f;
  675.     register struct ent **p;
  676.     register r, c;
  677.     char save[1024];
  678.  
  679.     if (*fname == 0) fname = &curfile[0];
  680.  
  681.     strcpy(save,fname);
  682.  
  683.     f = fopen (fname, "w");
  684.     if (f==0) {
  685.     error ("Can't create %s", fname);
  686.     return;
  687.     }
  688.  
  689.     fprintf (f, "# This data file was generated by the Spreadsheet ");
  690.     fprintf (f, "Calculator.\n");
  691.     fprintf (f, "# You almost certainly shouldn't edit it.\n\n");
  692.     for (c=0; c<MAXCOLS; c++)
  693.     if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC)
  694.         fprintf (f, "format %d %d %d\n",c,fwidth[c],precision[c]);
  695.     for (r=0; r<=maxrow; r++) {
  696.     p = &tbl[r][0];
  697.     for (c=0; c<=maxcol; c++, p++)
  698.         if (*p) {
  699.         if ((*p)->label)
  700.             fprintf (f, "%sstring r%dc%d = \"%s\"\n",
  701.                 (*p)->flags&is_leftflush ? "left" : "right",
  702.                 r,c,(*p)->label);
  703.         if ((*p)->flags&is_valid) {
  704.             editv (r, c);
  705.             fprintf (f, "%s\n",line);
  706.         }
  707.         }
  708.     }
  709.     fclose (f);
  710.     strcpy(curfile,save);
  711.  
  712.     modflg = 0;
  713.     error("File '%s' written.",curfile);
  714. }
  715.  
  716. readfile (fname,eraseflg)
  717. char *fname; int eraseflg; {
  718.     register FILE *f;
  719.     char save[1024];
  720.  
  721.     if (*fname == 0) fname = &curfile[0];
  722.     strcpy(save,fname);
  723.  
  724.     if (eraseflg && strcmp(fname,curfile) && modcheck(" first")) return;
  725.  
  726.     f = fopen (save, "r");
  727.     if (f==0) {
  728.     error ("Can't read %s", save);
  729.     return;
  730.     }
  731.  
  732.     if (eraseflg) erasedb ();
  733.  
  734.     while (fgets(line,sizeof line,f)) {
  735.     linelim = 0;
  736.     if (line[0] != '#') yyparse ();
  737.     }
  738.     fclose (f);
  739.     linelim = -1;
  740.     modflg++;
  741.     if (eraseflg) {
  742.     strcpy(curfile,save);
  743.     modflg = 0;
  744.     }
  745.     EvalAll();
  746. }
  747.  
  748. erasedb () {
  749.     register r, c;
  750.     for (c = 0; c<maxcol; c++) {
  751.         fwidth[c] = DEFWIDTH;
  752.         precision[c] = DEFPREC;
  753.     }
  754.  
  755.     for (r = 0; r<=maxrow; r++) {
  756.     register struct ent **p = &tbl[r][0];
  757.     for (c=0; c++<=maxcol; p++)
  758.         if (*p) {
  759.             if ((*p)->expr) efree ((*p) -> expr);
  760.             if ((*p)->label) free ((*p) -> label);
  761.             free (*p);
  762.             *p = 0;
  763.         }
  764.     }
  765.     maxrow = 0;
  766.     maxcol = 0;
  767.     FullUpdate++;
  768. }
  769.  
  770. openrow (rs) {
  771.     register    r;
  772.     register struct ent **p;
  773.     register    c;
  774.     if (maxcol >= MAXCOLS - 1) {
  775.     error ("The table can't be any bigger");
  776.     return;
  777.  
  778.     }
  779.     for (r = ++maxrow; r > rs; r--)
  780.     for (c = maxcol + 1, p = &tbl[r][0]; --c >= 0; p++)
  781.         if (p[0] = p[-MAXCOLS])
  782.         p[0] -> row++;
  783.     p = &tbl[rs][0];
  784.     for (c = maxcol + 1; --c >= 0;)
  785.     *p++ = 0;
  786.     FullUpdate++;
  787.     modflg++;
  788. }
  789.  
  790. closerow (r)
  791. register r; {
  792.     register struct ent **p;
  793.     register c;
  794.  
  795.     if (r > maxrow) return;
  796.     while (r<maxrow) {
  797.     for (c = maxcol+1, p = &tbl[r][0]; --c>=0; p++)
  798.         if (p[0] = p[MAXCOLS])
  799.         p[0]->row--;
  800.     r++;
  801.     }
  802.     p = &tbl[maxrow][0];
  803.     for (c=maxcol+1; --c>=0; ) *p++ = 0;
  804.     maxrow--;
  805.     FullUpdate++;
  806.     modflg++;
  807. }
  808.  
  809. opencol (cs) {
  810.     register r;
  811.     register struct ent **p;
  812.     register c;
  813.     register lim;
  814.     int i;
  815.     
  816.     lim = maxcol-cs+1;
  817.  
  818.     for (i = MAXCOLS - 1; i > cs; i--) {
  819.     fwidth[i] = fwidth[i-1];
  820.     precision[i] = precision[i-1];
  821.     }
  822.     /* fwidth[cs] = DEFWIDTH;
  823.     precision[i] =  DEFPREC;  */
  824.  
  825.     for (r=0; r<=maxrow; r++) {
  826.     p = &tbl[r][maxcol+1];
  827.     for (c=lim; --c>=0; p--)
  828.         if (p[0] = p[-1])
  829.         p[0]->col++;
  830.     p[0] = 0;
  831.     }
  832.     maxcol++;
  833.     FullUpdate++;
  834.     modflg++;
  835. }
  836.  
  837. closecol (cs) {
  838.     register r;
  839.     register struct ent **p;
  840.     register c;
  841.     register lim;
  842.     int i;
  843.  
  844.     lim = maxcol-cs;
  845.     if (lim < 0) return;
  846.  
  847.     for (r=0; r<=maxrow; r++) {
  848.     p = &tbl[r][cs];
  849.     for (c=lim; --c>=0; p++)
  850.         if (p[0] = p[1])
  851.         p[0]->col++;
  852.     p[0] = 0;
  853.     }
  854.  
  855.     for (i = cs; i < MAXCOLS - 1; i++) {
  856.     fwidth[i] = fwidth[i+1];
  857.     precision[i] = precision[i+1];
  858.     }
  859.  
  860.     maxcol--;
  861.     FullUpdate++;
  862.     modflg++;
  863. }
  864.  
  865. debugout(g,fmt,args) FILE *g; char *fmt; {
  866.     int i,op;
  867.  
  868.     if (g == 0) g = fopen("debug","a"),op = 1;
  869.     if (g == 0) return;
  870.  
  871.     fprintf(g, fmt, &args);
  872.  
  873.     fflush(g);
  874.     if (op) fclose(g);
  875. }
  876.  
  877.  
  878. mvaddstr(row, col, s)
  879. int row, col;
  880. char *s;
  881. {
  882.     gotoXY(col, row);
  883.     addstr(s);
  884. }
  885.  
  886. addstr(s)
  887. char *s;
  888. {
  889.     printf("%s",s);
  890.     fflush(stdout);
  891. }
  892.