home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk10 / apps / sse / sseline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-11  |  5.8 KB  |  206 lines

  1. #include <ctype.h>
  2. #include <dos.h>
  3. #include "ssedefs.h"
  4.  
  5.  
  6.  
  7.  
  8. /*** addline - allocates and puts lines into segments
  9.  *
  10.  *   addline adds a line to a segment and if nessessary
  11.  *     allocates a new segment.
  12.  *
  13.  *   addline (linenum, linelength, line)
  14.  *
  15.  *   ENTRY   linenum    - the line number of 'line' in the file
  16.  *         linelength - the line length of 'line'
  17.  *         line    - the 'line' to place in the segment
  18.  *
  19.  *   EXIT    rc     - return code for allocating a segment
  20.  *
  21.  *   addline places the current line the in the segment
  22.  *     containing the previous line if possible to
  23.  *     reduce scattering, otherwise it scans other
  24.  *     segments for first fit and if this fail allocates
  25.  *     a new segment.
  26.  *
  27.  *   WARNING: do not modify the value of 'i' it is the
  28.  *          result of the segment searches.
  29.  *
  30.  *   EFFECTS: LineTable - by adding new lines
  31.  *          SegTable    - by using free space for the line
  32.  *              and via 'allocseg'
  33.  *          TotalSegs - via 'allocseg'
  34.  *          memory    - by allocating segments via 'allocseg'
  35.  */
  36.  
  37. short addline(linenum, linelength, line)
  38. unsigned short linenum;
  39. unsigned char  linelength;
  40. unsigned char  line[];
  41. {
  42.     register unsigned short i, j;
  43.     unsigned char  bytesneeded;
  44.     unsigned short selector;
  45.     short       rc;     /* return code of allocseg */
  46.  
  47.     bytesneeded = (HEADERSIZE + linelength);
  48.     rc = 0;
  49.  
  50. /*  use segment of previous line to reduce scattering */
  51.     if (linenum == 0)
  52.     selector = FP_SEG(LineTable[linenum]);
  53.     else
  54.     selector = FP_SEG(LineTable[linenum -1]);
  55.  
  56. /*  find segment contianing line number -1 */
  57.     for(i = 0; (selector != SegTable[i].segment) && (i < TotalSegs); i++);
  58.  
  59. /*  scan for first fit if not enough space in segment containing line -1 */
  60.     if (SegTable[i].free < bytesneeded) {
  61.     for(i = 0; (SegTable[i].free < bytesneeded) && (i < TotalSegs); i++);
  62. /*    allocate a segment if not eough space is found */
  63.     if (i >= TotalSegs)
  64.         rc = allocseg();
  65.     }
  66.  
  67.     if (rc == 0) {     /* no error allocating a segment */
  68. /*    point line table at segment */
  69.     FP_SEG(LineTable[linenum]) = SegTable[i].segment;
  70.     FP_OFF(LineTable[linenum]) = SEGSIZE - SegTable[i].free;
  71.  
  72. /*    place line in segment */
  73.     SegTable[i].free -= bytesneeded;
  74.     LineTable[linenum]->linelength = linelength;
  75.     for(j = 0; j < linelength; j++)
  76.     LineTable[linenum]->firstchar[j] = line[j];
  77.     }
  78.     return(rc);
  79. }
  80.  
  81.  
  82.  
  83.  
  84. /*** deleteline - marks lines as deleted
  85.  *
  86.  *   deleteline marks a line as deteted in the segment
  87.  *     it is contained in and marks the setment containing
  88.  *     the line as needing compacting.
  89.  *
  90.  *   deleteline (linenum)
  91.  *
  92.  *   Entry    linenum - line number of line to mark as deleted
  93.  *
  94.  *   EFFECTS: SegTable - by marking the segment containing the line
  95.  *               as needing compacting.
  96.  *             by marking the line in the segment as deleted.
  97.  */
  98.  
  99. void deleteline(linenum)
  100. unsigned short linenum;
  101. {
  102.     register unsigned short i;
  103.     unsigned short selector;
  104.  
  105.     LineTable[linenum]->deleted = TRUE;
  106.     selector = FP_SEG(LineTable[linenum]);
  107.  
  108.     for(i = 0; (selector != SegTable[i].segment) && (i < TotalSegs); i++);
  109.  
  110.     SegTable[i].flags = TRUE;
  111.  
  112. }
  113.  
  114.  
  115.  
  116.  
  117. /*** flushline - flushes editbuffer to segment
  118.  *
  119.  *   flushline rewrites the contents of a line to a segment
  120.  *     by using deleteline and addline.
  121.  *
  122.  *   flushline    (linenum, line)
  123.  *
  124.  *   ENTRY    linenum - linenumber of line to rewrite.
  125.  *        line    - line to be rewriten.
  126.  *
  127.  *   flushline checks if the current line is beyond the end of
  128.  *     file, if so it adds the line to the file using addline,
  129.  *     else it replaces it by deleting the the old copy of the
  130.  *     line using deleteline and then adding the line back using
  131.  *     addline. flushline will EXIT the program by calling error25
  132.  *     if it is unable to add a line to the file or the number of
  133.  *     lines in the file becomes greater than MAXLINES.
  134.  *
  135.  *   EFFECTS: TotalLines - by incrementing it
  136.  *          SegTable     - by marking the segment containing the line
  137.  *                 as needing compacting, via 'deleteline'
  138.  *               by marking the line in the segment as deleted.
  139.  *                 via 'deleteline'
  140.  *          LineTable  - by adding new lines via 'addline'
  141.  *          SegTable     - by using free space for the line via 'addline'
  142.  *               and via 'allocseg'
  143.  *          TotalSegs  - via 'allocseg'
  144.  *          memory     - by allocating segments via 'allocseg'
  145.  */
  146.  
  147. flushline(linenum, line)
  148. unsigned short linenum;
  149. unsigned char  line[];
  150. {
  151.     register unsigned char  i;
  152.  
  153. /*  delete the line if it's not beyond the end of the file */
  154.     if ( !(linenum == TotalLines))
  155.     deleteline(linenum);
  156.     else
  157.     ++TotalLines;
  158.  
  159.     for (i = (LINESIZE -1); !isgraph(line[i]) && inline(i, 0); i--);
  160.  
  161.     if ( (addline(linenum, i +1, line) != 0) || !(TotalLines < MAXLINES) )
  162.     error25(7);    /* call error message and quit */;
  163. }
  164.  
  165.  
  166.  
  167.  
  168. /*** getline - fills line from segment
  169.  *
  170.  *   getline copies a 'line' from a segment to the
  171.  *     address given by line.
  172.  *
  173.  *   getline (linenum, line)
  174.  *
  175.  *   ENTRY   linenum  -  the line number of 'line' in the file
  176.  *         line     -  address of where to copy 'line'
  177.  *
  178.  *   getline fills the line out to LINESIZE with spaces and
  179.  *     returns a line of spaces if the linenum is not a valid
  180.  *     line number.
  181.  *
  182.  *   WARNING getline does not check if the address given by line is
  183.  *         valid.
  184.  *
  185.  *   EFFECTS memory - by copying the line to the address given by line.
  186.  */
  187.  
  188. void getline(linenum, line)
  189. unsigned short linenum;
  190. unsigned char  *line;
  191. {
  192.     register unsigned short i;
  193.  
  194.     i = 0;
  195.  
  196. /*  copy 'line' to address given by line */
  197.     if (linenum < TotalLines)  /* a valid line number */
  198.     for ( ; i < (LineTable[linenum]->linelength); i++)
  199.         line[i] = LineTable[linenum]->firstchar[i];
  200.  
  201. /*  pad line with spaces out to LINESIZE */
  202.     for ( ; i < LINESIZE; i++)
  203.     line[i] = ' ';
  204.  
  205. }
  206.