Seppo Mustonen : Programming Survo in C

4. Edit field

One important link between the main program of SURVO 84C and its modules is the edit field. It materializes our idea of the editorial approach.
     Most of the modules read something from the edit field and write results in it. This is done by using certain global variables and library functions.

After the s_init call we have the access to the edit field through the following global variables:

char *z;            /* pointer to edit field */
int ed1;            /* length of edit line + control column */
int ed2;            /* number of lines in edit field */
int edshad;         /* max. # of shadow lines in edit field */
int *zs;            /* indices of shadow lines */
int r;              /* current line on the screen */
int r1;             /* first visible edit line on the screen */
int r2;             /* =ed2 */
int r3;             /* # number of edit lines on the screen */
int c;              /* current column on the screen */
int c1;             /* first visible column on the screen */
int c2;             /* =ed1-1 (length of edit line) */
int c3;             /* # of columns on the screen */

The edit field is simply a sequence of ed1*ed2 characters starting from a character pointed to by z. Thus the jth line in the edit field consists of characters *(z+(j-1)*ed1+i), i=0,1,...,ed1-1, where the first one, *(z+(j-1)*ed1), is the control character.
     Use of direct references through z should, however, be avoided, since we do not guarantee that this setup will be valid in future implementations. Therefore we recommend that the library functions edread and edwrite should always be employed in reading and writing.
     Their current listings could be the following:

    #include <stdio.h> 
    #include <conio.h> 
    #include <string.h> 
    #include "survo.h"

    extern char *z;
    extern int ed1,ed2;

    edread(x,lin)
    char x[];       /* result as a null terminated string */
    int lin;        /* line number */
            {
            strncpy(x,z+(lin-1)*ed1,ed1);
            x[ed1]=EOS;
            }

    edwrite(x,lin,col)
    char x[];      /* string to be written */
    int lin;       /* line number */
    int col;       /* first column in writing */
            {
            int i,h;
            int len=strlen(x);

            if (len>ed1-col) len=ed1-col;
            for (i=0, h=(lin-1)*ed1+col; i<len; ++i, ++h)
                z[h]=x[i];
            }

The window on the screen (i.e. the visible part of the edit field) is maintained by the variables r, r1, r3, c, c1, c3.
     The current size of the window is r3 lines and c3 columns (plus the control column). In that window the location of the cursor is (r,c), the first visible edit line is r1 and the first column is c1. Hence the current position of the cursor in the edit field is line=r1+r-1 and column=c1+c-1.

For example, the character indicated by the cursor can be read as follows:

    char ch;
    char x[LLENGTH];
    edread(x,r1+r-1);
    ch=x[c1+c-1];

The module can change the position of the cursor and even the position of the window by updating variables r, c, r1, c1. In that case the s_end function must be called once before the return to the main program.

For example, the following !SEEK module finds the first edit line starting with a selected word and places the cursor to the first position on that line. When necessary, the window is moved. If the word is not found, an error message is displayed and the original display restored.

  1 /* !seek.c 28.3.1986/SM (28.3.1986)
  2 **   SEEK <word> 
  3 */
  4
  5 #include "survo.h"
  6 #include "survoext.h"
  7
  8 main(argc,argv)
  9 int argc; char *argv[];
 10     {
 11     int i,j;
 12     char x[LLENGTH];
 13     char *w[1];
 14
 15     if (argc==1) return;
 16     s_init(argv[1]);
 17
 18     if (g<2)
 19         {
 20         sur_print("\nUsage: SEEK <word>");
 21         WAIT; return;
 22         }
 23     for (j=1; j<r2; ++j)
 24         {
 25         edread(x,j);
 26         i=split(x+1,w,1);
 27         if (strcmp(w[0],word[1])==0)
 28             {
 29             if (j<r1) r1=j;
 30             else if (j>r1+r3-1)
 31                 {
 32                 r1=j;
 33                 if (r1>r2-r3+1) r1=r2-r3+1;
 34                 }
 35             r=j-r1+1;
 36             c1=c=1;
 37             s_end(argv[1]);
 38             return;
 39             }
 40         }
 41     sprintf(sbuf,"\nWord %s not as the first word of any line!"
 42                   ,word[1]);  sur_print(sbuf);
 43     WAIT;
 44     }

All the edit lines are scanned (until success) by the loop starting from line 23. The current line is read as string x (line 25) and the actual line (x+1) without the control character is divided into words by the library function split (line 26). Here only the first word (w[0]) is of interest.
     On line 27 strcmp compares w[0] with word[1] (the word given by the user). If they are the same, a proper window for displaying the line is selected (29-36) and the module ends by updating the parameters by the s_end call. If the words are not the same, the search continues and in an entirely unsuccessful case an error message is displayed (on lines 41-43).


Previous: Example of a SURVO 84C module
Next: Shadow lines


Front page of Programming Survo in C