home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / BROWSER.C < prev    next >
Text File  |  1995-11-02  |  38KB  |  517 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   browse.c                                                                */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*   browse any text file.                                                   */
  7. /*                                                                           */
  8. /* History:                                                                  */
  9. /*                                                                           */
  10. /*   02/08/91 Creation of 32-bit SD86, from 16-bit version.                  */
  11. /*                                                                           */
  12. /*...16->32 port.                                                            */
  13. /*...                                                                        */
  14. /*... 02/08/91  100   Philip    port to 32 bit.                              */
  15. /*... 02/08/91  101   Joe       port to 32 bit.                              */
  16. /*... 02/08/91  105   Christina port to 32 bit.                              */
  17. /*... 02/08/91  106   Srinivas  port to 32 bit.                              */
  18. /*... 02/08/91  110   Srinivas  port to 32 bit.                              */
  19. /*... 02/08/91  111   Christina port to 32 bit.                              */
  20. /*... 02/08/91  112   Joe       port to 32 bit.                              */
  21. /*...                                                                        */
  22. /*... 08/22/91  234   Joe       PL/X gives "varname" is incorrect message    */
  23. /*...                           when entering a parameter name in the data   */
  24. /*...                           window.  This happens when the cursor is on  */
  25. /*...                           an internal procedure definition statement   */
  26. /*...                           and you use F2 to get into the data window   */
  27. /*...                           and then type the name.                      */
  28. /*... 02/12/92  521   Srinivas  Port to C-Set/2.                             */
  29. /*...                                                                        */
  30. /**Includes*******************************************************************/
  31.  
  32. #include "all.h"                        /* SD86 include files                */
  33.  
  34. /**Defines *******************************************************************/
  35.  
  36.  
  37. /**External declararions******************************************************/
  38.  
  39. extern uint     LinesPer;               /* current # lines/screen for code   */
  40. extern KEY2FUNC defk2f[];               /*                                   */
  41. extern uint     TopLine;                /* current top line for code         */
  42. extern uint     VideoRows;              /*                                   */
  43. extern char     BrowseSearchBuffer[ PROMAX+1 ];
  44. extern UINT     FnameRow;               /* screen row for file name (0..N)   */
  45.  
  46. /**Static definitions ********************************************************/
  47.                                         /*                                   */
  48. static uint   prohids[] =               /*                                   */
  49. {
  50.   HELP_DLG_BROWSE,                      /* context help for filename entry   */
  51.   HELP_DLG_FIND,                        /* context help for find string.     */
  52.   HELP_WIN_BROWSE                       /* context help for browse window.   */
  53. };                                      /*                                   */
  54.                                         /*                                   */
  55. extern uint slen;                       /* length of search string        110*/
  56. extern uint str_fnd_flag;               /* flag to signal reverse video   110*/
  57.  
  58. /*****************************************************************************/
  59. /* browse                                                                    */
  60. /*                                                                           */
  61. /* Description:                                                              */
  62. /*   Browse any file.                                                        */
  63. /*   Overview:                                                               */
  64. /*    1. Prompt the user for a filename.                                     */
  65. /*    2. Build a fully qualified filespec from the filename.                 */
  66. /*    3. Allocate memory for the afile.                                      */
  67. /*    4. Allocate memory for the source and the source index.                */
  68. /*    5. Load the source and build the index.                                */
  69. /*    7. Build afile info.                                                   */
  70. /*    8. Process user input keys.                                            */
  71. /*    9. Free up temp memory allocations.                                    */
  72. /*                                                                           */
  73. /* Parameters:                                                               */
  74. /*   none                                                                    */
  75. /*                                                                           */
  76. /* Return:                                                                   */
  77. /*   ???????????????????????????????                                         */
  78. /*                                                                           */
  79. /*****************************************************************************/
  80.   int                                   /*                                   */
  81. browse( char *FileName, int InitialLineNumber  )
  82. {                                       /*                                   */
  83.  uint      n;                           /* just a number                     */
  84.  uint      Nlines;                      /* num of lines in the source buffer */
  85.  uint      Tlines;                      /* total lines in the file.          */
  86.  SEL       srcsel;                      /* source buffer selector.        110*/
  87.  SEL       offsel;                      /* offset buffer selector.        110*/
  88.  uint      srcseglen;                   /* actual size of source buffer      */
  89.  AFILE    *fp;                          /* temp afile structure.             */
  90.  uchar    *fnfull;                      /* fully qualified filespec.         */
  91.  int       fnlen;                       /* filename/filespec buffer length.  */
  92.  int       func;                        /* function associated with a key.   */
  93.  uint      rc;                          /* return code.                      */
  94.  uchar     hlight[4];                   /* attributes for find string     110*/
  95.  int       OffsetTableBufSize;          /* size alloc'd for offtab.       234*/
  96.  ushort   *offtab;                      /* table of ptrs to src txt lines 234*/
  97.                                         /*                                   */
  98. /*****************************************************************************/
  99. /* The first thing we do is get a filename from the user and build a fully   */
  100. /* qualified filespec. The search order is:                                  */
  101. /*                                                                           */
  102. /*   1. explicit filespec.                                                   */
  103. /*   2. current directory.                                                   */
  104. /*   3. SD386SRC environment variable.                                    116*/
  105. /*   4. PATH.                                                                */
  106. /*                                                                           */
  107. /*****************************************************************************/
  108.  rc = 0;                                /* assume all is well.               */
  109.  fp = NULL;                             /* intialize null afile block.       */
  110.  fnlen=CCHMAXPATH;                      /* 1 byte of len + 128 of char + \0  */
  111.  
  112.  fnfull=Talloc(fnlen);                  /* allocate space for a filespec. 521*/
  113.  rc=FindExe(FileName, fnfull+1 , fnlen);/* search for filename/build filespec*/
  114. /* Tfree( (void*)fn);  */                /* done with the file name.       521*/
  115.  if(rc)                                 /* if we could not locate the file   */
  116.  {                                      /* name then                         */
  117.   Tfree((void*)fnfull);                  /* free the storage allocated for 521*/
  118.   return(rc);                           /* file name & return with can't     */
  119.  }                                      /* find message.                     */
  120.                                         /* build a length prefixed  filespec.*/
  121.  n=strlen(fnfull+1);                    /* compute filespec length.          */
  122.  *fnfull=(uchar)n;                      /* insert length in first byte.      */
  123.  ClrScr( FnameRow, FnameRow, vaInfo);   /* clear fname row and show the user */
  124.  putrc( FnameRow, 0, fnfull+1);         /* his fully qualified filespec.     */
  125.                                         /*                                   */
  126. /*****************************************************************************/
  127. /* Now we will proceed to build an afile which can be used for browsing the  */
  128. /* file. First, we load the source into some allocated buffers for the raw   */
  129. /* source and an index of offsets to the text lines. We make an initial      */
  130. /* guess as to how big these buffers should be, then, we reallocate them     */
  131. /* after we know how big they should be for real.                            */
  132. /*                                                                           */
  133. /*****************************************************************************/
  134.  fp = (AFILE*) Talloc(SizeOfAFILE(n));  /* allocate memory for this afile.521*/
  135.  memcpy( fp->filename, fnfull, n+1 );   /* copy filename in afile struct. 101*/
  136.  Nlines = 0;                            /* initialize # of source lines      */
  137.  Tlines = 0;                            /* initialize # of file lines.       */
  138.  srcsel = 0;                            /* "        " source buffer selector.*/
  139.  offsel = 0;                            /* "        " offset buffer selector.*/
  140.  rc=DosAllocSeg(0,(PSEL)&srcsel,0);     /* allocate 64k for source buffer.   */
  141.  if(rc){rc=2;goto errorexit;}           /* error check.                      */
  142.                                         /*                                   */
  143.  rc=DosAllocSeg(20*1024,(PSEL)&offsel,0);/* allocate 20k for offset index.   */
  144.  if(rc){rc=2;goto errorexit;}           /* error check.                      */
  145.                                         /*                                   */
  146.  LoadSource(fp->filename+1  ,           /* input: source filespec.           */
  147.    ( uchar *) Sel2Flat(srcsel) ,        /* output: source buffer sel 111  110*/
  148.    ( ushort *)Sel2Flat(offsel) ,        /* output: txt line offst buf sel 110*/
  149.               0                ,        /* input: no skip lines at file start*/
  150.    (ushort *) &srcseglen       ,        /* output: # of src buf bytes used111*/
  151.               &Nlines          ,        /* output: # of src lines in buffer  */
  152.               &Tlines                   /* output: "               " file    */
  153.              );
  154.  if(Nlines == 0)                        /* if there are no source lines for  */
  155.  {rc=4;goto errorexit;}                 /* removed rc check                  */
  156.                                         /*                                   */
  157.                                         /*                                   */
  158.  fp->flags = 0x00;                      /* clear the flags.                  */
  159.  fp->Tlines = Tlines;                   /* put # of src file lines in afile. */
  160.  if( Tlines > Nlines )                  /* does compressed source exceed 64k?*/
  161.   fp->flags |= AF_HUGE;                 /* mark afile with huge file flag    */
  162.  fp->Nlines = Nlines;                   /* # of lines in buffer into afile111*/
  163.  fp->source = (uchar *)Sel2Flat(srcsel);/* -> to source text into afile111110*/
  164.  
  165. /*****************************************************************************/
  166. /* Allocate the offtab[] buffer to hold Nlines + 1 offsets. We add the    234*/
  167. /* so that we can make the offset table indices line up with the          234*/
  168. /* source line numbers.                                                   234*/
  169. /*****************************************************************************/
  170.  OffsetTableBufSize = (Nlines+1)*sizeof(ushort);                        /*234*/
  171.  offtab = (ushort*) Talloc(OffsetTableBufSize);                     /*521 234*/
  172.  memcpy(offtab + 1, (uchar*)Sel2Flat(offsel), Nlines * sizeof(ushort) );/*234*/
  173.  fp->offtab = offtab;                                                   /*234*/
  174.  
  175.  if( offsel )                           /* if there was an offset segment 234*/
  176.   DosFreeSeg(offsel);                   /* allocated then free it up      234*/
  177.  
  178.  fp->topline = 1;                       /* no. put it on the top line     234*/
  179.  fp->csrline = 1;                       /* no. put it on the top line     234*/
  180.  
  181.  if( InitialLineNumber != 0 )
  182.   fp->csrline = InitialLineNumber;
  183.  
  184.  fp->pdf = NULL;                        /*                                110*/
  185.  scrollwindow( fp, InitialLineNumber ); /* display the initial window.       */
  186.  
  187. /*****************************************************************************/
  188. /* Now, we are going to process the user's keys.                             */
  189. /*                                                                           */
  190. /*****************************************************************************/
  191.  for(;;)                                /* begin loop to process keys.       */
  192.  {                                      /*                                   */
  193.   fmtpos( fp );                         /* put "line xx of yy" message out   */
  194.   fp->csr.row = ( uchar )( fp->csrline- /* set cursor line in source buffer  */
  195.                   fp->topline +         /* - source line at top of display   */
  196.                   TopLine );            /* + topline for the code            */
  197.   PutCsr( ( CSR * )&fp->csr );          /* set the cursor position           */
  198.   if (str_fnd_flag == 1)                /* if the string found flag is    110*/
  199.   {                                     /* set by scan function then      110*/
  200.      hlight[0] = 0xFF;                  /* attribute string for highlight 110*/
  201.      hlight[1] = (uchar)slen;           /* attribute string for highlight 110*/
  202.      hlight[2] = Attrib(vaXline);       /* attribute string for highlight 110*/
  203.      hlight[3] = 0;                     /* attribute string for highlight 110*/
  204.      putrc(fp->csr.row,fp->csr.col,&hlight[0]);  /*                       110*/
  205.      str_fnd_flag = 0;                  /* highlight the string and reset 110*/
  206.   }                                     /* the flag                       110*/
  207.  
  208.   SetMenuMask( BROWSEFILE );                                            /*701*/
  209.   #define NOHANDLEESC 1                                                 /*701*/
  210.   func = GetFuncsFromEvents( NOHANDLEESC, NULL ); /*                     701*/
  211.   switch( func )                        /* switch on function selection      */
  212.   {                                     /* begin function processing         */
  213.    case QUIT:
  214.    case ESCAPE:
  215.     goto errorexit;                     /* go to exit processing.            */
  216.  
  217.    case UPCURSOR:                       /* move cursor up one line           */
  218.     fp->csrline -= 1;                   /* update afile with current csr line*/
  219.                                         /* removed call to dovcsr            */
  220.     if( !IsOnCRT(fp) )                  /* if the cursor goes off the screen */
  221.      {                                  /*                                   */
  222.       fp->csrline += 1;                 /* reset afile value before update   */
  223.       scrollwindow(fp, -1);             /* move the screen up   one line     */
  224.      }                                  /*                                   */
  225.     break;                              /*                                   */
  226.                                         /*                                   */
  227.    case DOWNCURSOR:                     /* move the cursor down one line     */
  228.                                         /* removed call to dovcsr            */
  229.     fp->csrline += 1;                   /* update afile with current csr line*/
  230.     if( !IsOnCRT(fp) )                  /* if the cursor goes off the screen */
  231.      {                                  /*                                   */
  232.       fp->csrline -= 1;                 /* reset afile value before update   */
  233.       scrollwindow(fp, 1);              /* move the screen down one line     */
  234.      }                                  /*                                   */
  235.     break;                              /*                                   */
  236.                                         /*                                   */
  237.    case PREVWINDOW:                     /* show previous screen              */
  238.     scrollwindow(fp,-(int)LinesPer);    /* display the initial window.    521*/
  239.     break;                              /*                                   */
  240.                                         /*                                   */
  241.    case NEXTWINDOW:                     /* show next screen                  */
  242.     scrollwindow( fp,  LinesPer );      /* display the initial window.       */
  243.     break;                              /*                                   */
  244.                                         /*                                   */
  245.    case FIRSTWINDOW:                    /* show top of file.                 */
  246.     scrollwindow(fp,-(int)fp->Tlines);  /* display the initial window234521*/
  247.     fp->csrline = fp->topline;          /*                                   */
  248.     break;                              /*                                   */
  249.                                         /*                                   */
  250.    case LASTWINDOW:                     /* show the bottom of the file.   234*/
  251.     scrollwindow( fp, fp->Tlines - LinesPer + 1);
  252.     fp->csrline=fp->topline+fp->Nshown-1;/* cursor on bottom line            */
  253.     break;                              /*                                   */
  254.                                         /*                                   */
  255.    case TOPOFWINDOW:                    /* move cursor to top line on screen */
  256.     fp->csrline = fp->topline;          /* update afile t put cursor on top  */
  257.     break;                              /*                                   */
  258.                                         /*                                   */
  259.    case BOTOFWINDOW:                    /* move cursor to last line on screen*/
  260.     fp->csrline=fp->topline+fp->Nshown-1;/*                                  */
  261.     break;                              /*                                   */
  262.                                         /*                                   */
  263. /*****************************************************************************/
  264. /* These are the find and repeat find functions.                             */
  265. /*                                                                           */
  266. /*****************************************************************************/
  267.    case FIND:
  268.     FindStr( fp );
  269.     scrollwindow(fp,0);
  270.     break;
  271.  
  272.    case REPEATFIND:
  273.     rc = (uint)ScanStr(fp);
  274.     scrollwindow(fp,0);
  275.     if( rc == 0 )
  276.      fmterr( "Can't find that" );
  277.     rc = 0;
  278.     break;
  279.  
  280.                                         /*                                   */
  281.    case GENHELP:                        /* General help                   701*/
  282.    {                                                                    /*701*/
  283.      Help(prohids[2]);
  284.      break;                              /*                                  */
  285.    }                                                                    /*701*/
  286.  
  287.    case HELP:                           /* move cursor to last line on scr   */
  288.      HelpScreen( );
  289.      break;                             /* for now, no context sensitive help*/
  290.   }                                     /* end of switch on user functions.  */
  291.  }                                      /* end of process key loop.          */
  292.                                         /*                                   */
  293. errorexit:                              /*                                   */
  294.  if( fp->source  &&                     /* free the DosAlloc'd source buffer.*/
  295.      DosFreeSeg(Flat2Sel(fp->source))   /* if it doesn't free then call it110*/
  296.  
  297.    )                                    /*                                   */
  298.   rc = 2;                               /* a memory allocation error.        */
  299.                                         /*                                   */
  300.  if( fp->offtab )                       /* free the DosAlloc'd offset buffer.*/
  301.      Tfree((char *)fp->offtab);          /* handle error same as above.521 234*/
  302.                                         /*                                   */
  303.  if( fnfull )                           /* free the malloc'd filespec.       */
  304.   Tfree((void*)fnfull);                  /*                                521*/
  305.  Tfree((void*)fp);                       /* free the temp afile structure. 521*/
  306.  return(rc);                            /* display error msg; ret. to caller */
  307. }                                       /*                                   */
  308.                                         /*                                   */
  309. /*****************************************************************************/
  310. /*  scrollwindow()                                                           */
  311. /*                                                                           */
  312. /* Description:                                                              */
  313. /*   move the screen vertically n lines.                                     */
  314. /*                                                                           */
  315. /* Parameters:                                                               */
  316. /*                                                                           */
  317. /*   fp        input - the afile for this dfile node.                        */
  318. /*   n         input - # of lines to scroll.                                 */
  319. /*                     a large value means move a full screen.               */
  320. /*                                                                           */
  321. /* Return:                                                                   */
  322. /*   void                                                                    */
  323. /*                                                                           */
  324. /* Assumptions:                                                              */
  325. /*                                                                           */
  326. /*****************************************************************************/
  327.  void                                   /*                                   */
  328. scrollwindow(AFILE *fp,int n)           /* number of lines to move screen    */
  329. {                                       /*                                   */
  330.  int  newtop;                           /* file line at top of screen.       */
  331.  int  csrdelta;                         /* cursor offset from topline        */
  332.  int  target;                           /* potential top line in file        */
  333.  int  bias;                             /* lines skipped in the file for     */
  334.  
  335.                                         /* HUGE files.                       */
  336.  newtop = fp->topline + n;              /* define the new top line           */
  337.  csrdelta = fp->csrline - fp->topline;  /* define lines between csr and top  */
  338.                                         /*                                   */
  339.  Recheck:                               /*                                   */
  340.                                         /*                                   */
  341.  bias = fp->Nbias;                      /*                                   */
  342. /*****************************************************************************/
  343. /*                                                                           */
  344. /* At this point we first check to see if we're going beyond the lower line  */
  345. /* boundary of the source buffer.  If we are then there could still be source*/
  346. /* left in the file above the lines contained in the source buffer.  This is */
  347. /* the case of a HUGE file meaning that the 64k source buffer could not hold */
  348. /* all of the source lines and we need to back up in the file.               */
  349. /*                                                                           */
  350. /* If we have a HUGE file and all lines have not been read in, then we need  */
  351. /* to page the source buffer down in the file replenishing the source buffer.*/
  352. /* We then need to update the afile block and resynchronize the display.     */
  353. /*****************************************************************************/
  354.  if( newtop < 1 )                       /* trying to go before first line 234*/
  355.  {                                      /*                                   */
  356.   if( (fp->flags & AF_HUGE) &&          /* is this a HUGE file and the       */
  357.        fp->Nbias                        /* buffer was previously paged down ?*/
  358.     )                                   /*                                   */
  359.   {                                     /*                                   */
  360.    target = newtop + fp->Nbias;         /* yes on both. define new target    */
  361.    if( target < 1 )                     /* if target is before file begin 234*/
  362.     target = 1;                         /* then clip it at 0.             234*/
  363.                                         /*                                   */
  364.    scrollfile( fp, target );            /* now page up in the file        234*/
  365.                                         /*                                   */
  366.    Resync:                              /*                                   */
  367.                                         /*                                   */
  368.    newtop = target - fp->Nbias;         /* define the new top of the file    */
  369.    fp->hotline += bias - fp->Nbias;     /* define the new hotline            */
  370.    goto Recheck;                        /* do it again just for being a jerk */
  371.   }                                     /*                                   */
  372.                                         /*                                   */
  373.   newtop = 1;                           /* can't move before first line   234*/
  374.                                         /*                                   */
  375.  }
  376. /*****************************************************************************/
  377. /*At this point we first check to see if we have enough lines left in the    */
  378. /*buffer to fill up the display.  If we don't, we could still have source    */
  379. /*left in the file that has not been read into the source buffer.  This is   */
  380. /*the case of a HUGE file meaning that the 64k source buffer could not hold  */
  381. /*all of the source lines and we still need to read some in.                 */
  382. /*                                                                           */
  383. /*If we have a HUGE file and all lines have not been read in, then we need   */
  384. /*to page the source buffer down in the file replenishing the source buffer. */
  385. /*We then need to update the afile block and resynchronize the display.      */
  386. /*                                                                           */
  387. /*****************************************************************************/
  388.  else                                   /*                                   */
  389.  {                                      /*                                   */
  390.   if( (uint)newtop + LinesPer -1 > fp->Nlines )
  391.   {                                     /*need more lines than in buffer  234*/
  392.    if((fp->flags & AF_HUGE) &&          /* yes. Is this a HUGE file and not  */
  393.       (fp->Nlines+fp->Nbias < fp->Tlines)/* all lines have been read?        */
  394.      )                                  /*                                   */
  395.    {                                    /*                                   */
  396.     target = newtop + fp->Nbias;        /* true again. define the target line*/
  397.     if( (uint)target > fp->Tlines )     /* is the target past end of file?   */
  398.      target = fp->Tlines - LinesPer+1;  /* yes. display last LinesPer in file*/
  399.      scrollfile(fp,target+LinesPer-1);
  400.                                         /*                                   */
  401.     goto Resync;                        /* resync the display                */
  402.  
  403.    }                                    /*                                   */
  404.    newtop = fp->Nlines - LinesPer + 1;  /* display last LinesPer in file  234*/
  405.    if( newtop < 1 )                     /* don't let the newtop go above file*/
  406.     newtop = 1;                         /* 0 is the minimum                  */
  407.   }                                     /*                                   */
  408.  }                                      /*                                   */
  409.  fp->topline = newtop;                  /* put new topline in afile          */
  410.  fmttxt( fp );                          /* format the text for this afile    */
  411.  if( IsOnCRT(fp) == FALSE )
  412.   fp->csrline = fp->topline + csrdelta; /* put new csrline in afile          */
  413. }                                       /*                                   */
  414. /*****************************************************************************/
  415. /*  scrollfile()                                                             */
  416. /*                                                                           */
  417. /* Description:                                                              */
  418. /*   move the file vertically.                                               */
  419. /*                                                                           */
  420. /* Parameters:                                                               */
  421. /*                                                                           */
  422. /*   fp        input - the afile for this dfile node.                        */
  423. /*   lno       input - file line # we're shooting for.                       */
  424. /*                                                                           */
  425. /* Return:                                                                   */
  426. /*                                                                           */
  427. /*    none                                                                   */
  428. /*                                                                           */
  429. /* Assumptions:                                                              */
  430. /*                                                                           */
  431. /*****************************************************************************/
  432.  void                                   /*                                   */
  433. scrollfile(AFILE *fp,uint lno)
  434. {                                       /*                                   */
  435.  SEL       srcsel;                      /* selector for source buffer.    110*/
  436.  SEL       offsel;                      /* selector for offset buffer.    110*/
  437.  uint      line;                        /* file line for new bias.           */
  438.  uint      Nlines;                      /* # lines in the source buffer.     */
  439.  uint      srcseglen;                   /*                                   */
  440.  uint      retry;                       /* flag for retry loadsource.        */
  441.  int       OffsetTableBufSize;          /* size alloc'd for offtab.       234*/
  442.  ushort   *offtab;                      /* table of ptrs to src txt lines 234*/
  443.  
  444. /*****************************************************************************/
  445. /* When we come in, lno is a line number beyond the range of lines currently */
  446. /* in the source buffer. The first thing we do is make a few sanity checks   */
  447. /* on lno.                                                                   */
  448. /*                                                                           */
  449. /*****************************************************************************/
  450.                                         /* check the following:              */
  451.  if( (lno == 0)  ||                     /*  1. a zero line number.           */
  452.      ((lno > fp->Nbias) &&              /*  2. the line number falls in the  */
  453.       (lno <= (fp->Nbias + fp->Nlines)) /*     bounds of the remaining file. */
  454.      ) ||                               /*                                   */
  455.      !(fp->flags & AF_HUGE)             /*  3. compressed source > 64K.      */
  456.    ) return;                            /*                                   */
  457.  
  458.     if( lno > LINESBEFORE )
  459.         line = lno - LINESBEFORE;
  460.     else
  461.         line = 1;
  462. /*****************************************************************************/
  463. /* Now, we want to allocate new segments for the source and offset buffers.  */
  464. /*                                                                           */
  465. /*                                                                           */
  466. /*                                                                           */
  467. /*****************************************************************************/
  468.  srcsel = 0;                            /*                                   */
  469.  offsel = 0;                            /*                                   */
  470.  retry  = 0;                            /*                                   */
  471.  Nlines = 0;                            /*                                   */
  472.  DosAllocSeg(0,(PSEL)&srcsel,0);        /* allocate 64k for source buffer.   */
  473.  DosAllocSeg(20*1024,(PSEL)&offsel,0);  /* allocate 20k for offset index.   */
  474.                                         /*                                   */
  475.  Retry:                                 /*                                   */
  476.  LoadSource(fp->filename+1  ,           /* input: source filespec.           */
  477.    (uchar *)  Sel2Flat(srcsel) ,        /* output: source buffer sel 111  110*/
  478.    ( ushort *)Sel2Flat(offsel) ,        /* output: txt line offst buf sel 110*/
  479.                 line - 1       ,        /* input: no skip lines at file start*/
  480.     (ushort *)&srcseglen       ,        /* output: # of src buf bytes used111*/
  481.               &Nlines          ,        /* output: # of src lines in buffer  */
  482.              NULL );                    /* output: don't cnt total lns again.*/
  483.                                         /*                                   */
  484.  fp->Nlines = Nlines;                   /* put # src buffer lines in afile.  */
  485.                                         /*                                   */
  486.  if( ( (lno+VideoRows)>(line+Nlines) )  /* this code is trying to sync the   */
  487.      && !retry )                        /* end of the buffer, the end of the */
  488.  {                                      /* file and the screen.              */
  489.   if( lno > VideoRows )                 /* ???                               */
  490.    line = lno - VideoRows;              /* ???                               */
  491.   else                                  /* ???                               */
  492.    line = 1;                            /* ???                               */
  493.   retry = 1;                            /* ???                               */
  494.   goto Retry;                           /* ???                               */
  495.  }                                      /*                                   */
  496.  fp->Nbias  = line - 1;                 /* establish the new top line in buf.*/
  497.                                         /*                                   */
  498.  if( fp->offtab )                       /* if necessary, free up the old     */
  499.      Tfree((char *)fp->offtab);          /* offset buffer.             521 234*/
  500. /*****************************************************************************/
  501. /* Allocate the offtab[] buffer to hold Nlines + 1 offsets. We add the    234*/
  502. /* so that we can make the offset table indices line up with the          234*/
  503. /* source line numbers.                                                   234*/
  504. /*****************************************************************************/
  505.  OffsetTableBufSize = (Nlines+1)*sizeof(ushort);                        /*234*/
  506.  offtab = (ushort*) Talloc(OffsetTableBufSize);                     /*521 234*/
  507.  memcpy(offtab + 1, (uchar*)Sel2Flat(offsel), Nlines * sizeof(ushort) );/*234*/
  508.  fp->offtab = offtab;                                                   /*234*/
  509.  
  510.  if( offsel )                           /* if there was an offset segment 234*/
  511.   DosFreeSeg(offsel);                   /* allocated then free it up      234*/
  512.  if( fp->source )                       /* if necessary, free up the old     */
  513.      DosFreeSeg(Flat2Sel(fp->source) ); /* source buffer.                 110*/
  514.  fp->source = (uchar *)Sel2Flat(srcsel); /* insert -> source buf into 110 111*/
  515.  return;                                /*                                   */
  516. }
  517.