[BACK]Return to linenum.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Diff for /src/usr.bin/less/linenum.c between version 1.7 and 1.8

version 1.7, 2014/04/25 13:38:21 version 1.8, 2015/11/05 22:08:44
Line 6 
Line 6 
  *   *
  * For more information, see the README file.   * For more information, see the README file.
  */   */
   /*
    * Modified for use with illumos.
    * Copyright 2014 Garrett D'Amore <garrett@damore.org>
    */
   
   
 /*  /*
  * Code to handle displaying line numbers.   * Code to handle displaying line numbers.
  *   *
Line 42 
Line 45 
 {  {
         struct linenum_info *next;      /* Link to next in the list */          struct linenum_info *next;      /* Link to next in the list */
         struct linenum_info *prev;      /* Line to previous in the list */          struct linenum_info *prev;      /* Line to previous in the list */
         POSITION pos;                   /* File position */          off_t pos;                      /* File position */
         POSITION gap;                   /* Gap between prev and next */          off_t gap;                      /* Gap between prev and next */
         LINENUM line;                   /* Line number */          LINENUM line;                   /* Line number */
 };  };
 /*  /*
Line 62 
Line 65 
 static struct linenum_info anchor;      /* Anchor of the list */  static struct linenum_info anchor;      /* Anchor of the list */
 static struct linenum_info *freelist;   /* Anchor of the unused entries */  static struct linenum_info *freelist;   /* Anchor of the unused entries */
 static struct linenum_info pool[NPOOL]; /* The pool itself */  static struct linenum_info pool[NPOOL]; /* The pool itself */
 static struct linenum_info *spare;              /* We always keep one spare entry */  static struct linenum_info *spare;      /* We always keep one spare entry */
   
 extern int linenums;  extern int linenums;
 extern volatile sig_atomic_t sigs;  extern volatile sig_atomic_t sigs;
Line 72 
Line 75 
 /*  /*
  * Initialize the line number structures.   * Initialize the line number structures.
  */   */
         public void  void
 clr_linenum()  clr_linenum(void)
 {  {
         register struct linenum_info *p;          struct linenum_info *p;
   
         /*          /*
          * Put all the entries on the free list.           * Put all the entries on the free list.
Line 93 
Line 96 
          */           */
         anchor.next = anchor.prev = &anchor;          anchor.next = anchor.prev = &anchor;
         anchor.gap = 0;          anchor.gap = 0;
         anchor.pos = (POSITION)0;          anchor.pos = 0;
         anchor.line = 1;          anchor.line = 1;
 }  }
   
 /*  /*
  * Calculate the gap for an entry.   * Calculate the gap for an entry.
  */   */
         static void  static void
 calcgap(p)  calcgap(struct linenum_info *p)
         register struct linenum_info *p;  
 {  {
         /*          /*
          * Don't bother to compute a gap for the anchor.           * Don't bother to compute a gap for the anchor.
Line 120 
Line 122 
  * The specified position (pos) should be the file position of the   * The specified position (pos) should be the file position of the
  * FIRST character in the specified line.   * FIRST character in the specified line.
  */   */
         public void  void
 add_lnum(linenum, pos)  add_lnum(LINENUM linenum, off_t pos)
         LINENUM linenum;  
         POSITION pos;  
 {  {
         register struct linenum_info *p;          struct linenum_info *p;
         register struct linenum_info *new;          struct linenum_info *new;
         register struct linenum_info *nextp;          struct linenum_info *nextp;
         register struct linenum_info *prevp;          struct linenum_info *prevp;
         register POSITION mingap;          off_t mingap;
   
         /*          /*
          * Find the proper place in the list for the new one.           * Find the proper place in the list for the new one.
Line 142 
Line 142 
         nextp = p;          nextp = p;
         prevp = p->prev;          prevp = p->prev;
   
         if (freelist != NULL)          if (freelist != NULL) {
         {  
                 /*                  /*
                  * We still have free (unused) entries.                   * We still have free (unused) entries.
                  * Use one of them.                   * Use one of them.
                  */                   */
                 new = freelist;                  new = freelist;
                 freelist = freelist->next;                  freelist = freelist->next;
         } else          } else {
         {  
                 /*                  /*
                  * No free entries.                   * No free entries.
                  * Use the "spare" entry.                   * Use the "spare" entry.
Line 179 
Line 177 
         calcgap(nextp);          calcgap(nextp);
         calcgap(prevp);          calcgap(prevp);
   
         if (spare == NULL)          if (spare == NULL) {
         {  
                 /*                  /*
                  * We have used the spare entry.                   * We have used the spare entry.
                  * Scan the list to find the one with the smallest                   * Scan the list to find the one with the smallest
Line 191 
Line 188 
                  * not computed by calcgap.                   * not computed by calcgap.
                  */                   */
                 mingap = anchor.next->gap;                  mingap = anchor.next->gap;
                 for (p = anchor.next;  p->next != &anchor;  p = p->next)                  for (p = anchor.next;  p->next != &anchor;  p = p->next) {
                 {                          if (p->gap <= mingap) {
                         if (p->gap <= mingap)  
                         {  
                                 spare = p;                                  spare = p;
                                 mingap = p->gap;                                  mingap = p->gap;
                         }                          }
Line 208 
Line 203 
  * If we get stuck in a long loop trying to figure out the   * If we get stuck in a long loop trying to figure out the
  * line number, print a message to tell the user what we're doing.   * line number, print a message to tell the user what we're doing.
  */   */
         static void  static void
 longloopmessage()  longloopmessage(void)
 {  {
         ierror("Calculating line numbers", NULL_PARG);          ierror("Calculating line numbers", NULL_PARG);
 }  }
   
 static int loopcount;  static int loopcount;
 #if HAVE_TIME  
 static long startime;  static long startime;
 #endif  
   
         static void  static void
 longish()  longish(void)
 {  {
 #if HAVE_TIME          if (loopcount >= 0 && ++loopcount > 100) {
         if (loopcount >= 0 && ++loopcount > 100)  
         {  
                 loopcount = 0;                  loopcount = 0;
                 if (get_time() >= startime + LONGTIME)                  if (get_time() >= startime + LONGTIME) {
                 {  
                         longloopmessage();                          longloopmessage();
                         loopcount = -1;                          loopcount = -1;
                 }                  }
         }          }
 #else  
         if (loopcount >= 0 && ++loopcount > LONGLOOP)  
         {  
                 longloopmessage();  
                 loopcount = -1;  
         }  
 #endif  
 }  }
   
 /*  /*
  * Turn off line numbers because the user has interrupted   * Turn off line numbers because the user has interrupted
  * a lengthy line number calculation.   * a lengthy line number calculation.
  */   */
         static void  static void
 abort_long()  abort_long(void)
 {  {
         if (linenums == OPT_ONPLUS)          if (linenums == OPT_ONPLUS)
                 /*                  /*
Line 261 
Line 244 
  * Find the line number associated with a given position.   * Find the line number associated with a given position.
  * Return 0 if we can't figure it out.   * Return 0 if we can't figure it out.
  */   */
         public LINENUM  LINENUM
 find_linenum(pos)  find_linenum(off_t pos)
         POSITION pos;  
 {  {
         register struct linenum_info *p;          struct linenum_info *p;
         register LINENUM linenum;          LINENUM linenum;
         POSITION cpos;          off_t cpos;
   
         if (!linenums)          if (!linenums)
                 /*                  /*
                  * We're not using line numbers.                   * We're not using line numbers.
                  */                   */
                 return (0);                  return (0);
         if (pos == NULL_POSITION)          if (pos == -1)
                 /*                  /*
                  * Caller doesn't know what he's talking about.                   * Caller doesn't know what he's talking about.
                  */                   */
Line 300 
Line 282 
          * reading the file forward or backward till we           * reading the file forward or backward till we
          * get to the place we want.           * get to the place we want.
          *           *
          * First decide whether we should go forward from the           * First decide whether we should go forward from the
          * previous one or backwards from the next one.           * previous one or backwards from the next one.
          * The decision is based on which way involves           * The decision is based on which way involves
          * traversing fewer bytes in the file.           * traversing fewer bytes in the file.
          */           */
 #if HAVE_TIME  
         startime = get_time();          startime = get_time();
 #endif          if (p == &anchor || pos - p->prev->pos < p->pos - pos) {
         if (p == &anchor || pos - p->prev->pos < p->pos - pos)  
         {  
                 /*                  /*
                  * Go forward.                   * Go forward.
                  */                   */
Line 317 
Line 296 
                 if (ch_seek(p->pos))                  if (ch_seek(p->pos))
                         return (0);                          return (0);
                 loopcount = 0;                  loopcount = 0;
                 for (linenum = p->line, cpos = p->pos;  cpos < pos;  linenum++)                  for (linenum = p->line, cpos = p->pos; cpos < pos; linenum++) {
                 {  
                         /*                          /*
                          * Allow a signal to abort this loop.                           * Allow a signal to abort this loop.
                          */                           */
                         cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL);                          cpos = forw_raw_line(cpos, NULL, NULL);
                         if (ABORT_SIGS()) {                          if (ABORT_SIGS()) {
                                 abort_long();                                  abort_long();
                                 return (0);                                  return (0);
                         }                          }
                         if (cpos == NULL_POSITION)                          if (cpos == -1)
                                 return (0);                                  return (0);
                         longish();                          longish();
                 }                  }
Line 341 
Line 319 
                  */                   */
                 if (cpos > pos)                  if (cpos > pos)
                         linenum--;                          linenum--;
         } else          } else {
         {  
                 /*                  /*
                  * Go backward.                   * Go backward.
                  */                   */
                 if (ch_seek(p->pos))                  if (ch_seek(p->pos))
                         return (0);                          return (0);
                 loopcount = 0;                  loopcount = 0;
                 for (linenum = p->line, cpos = p->pos;  cpos > pos;  linenum--)                  for (linenum = p->line, cpos = p->pos; cpos > pos; linenum--) {
                 {  
                         /*                          /*
                          * Allow a signal to abort this loop.                           * Allow a signal to abort this loop.
                          */                           */
                         cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL);                          cpos = back_raw_line(cpos, NULL, NULL);
                         if (ABORT_SIGS()) {                          if (ABORT_SIGS()) {
                                 abort_long();                                  abort_long();
                                 return (0);                                  return (0);
                         }                          }
                         if (cpos == NULL_POSITION)                          if (cpos == -1)
                                 return (0);                                  return (0);
                         longish();                          longish();
                 }                  }
Line 374 
Line 350 
   
 /*  /*
  * Find the position of a given line number.   * Find the position of a given line number.
  * Return NULL_POSITION if we can't figure it out.   * Return -1 if we can't figure it out.
  */   */
         public POSITION  off_t
 find_pos(linenum)  find_pos(LINENUM linenum)
         LINENUM linenum;  
 {  {
         register struct linenum_info *p;          struct linenum_info *p;
         POSITION cpos;          off_t cpos;
         LINENUM clinenum;          LINENUM clinenum;
   
         if (linenum <= 1)          if (linenum <= 1)
Line 399 
Line 374 
                 /* Found it exactly. */                  /* Found it exactly. */
                 return (p->pos);                  return (p->pos);
   
         if (p == &anchor || linenum - p->prev->line < p->line - linenum)          if (p == &anchor || linenum - p->prev->line < p->line - linenum) {
         {  
                 /*                  /*
                  * Go forward.                   * Go forward.
                  */                   */
                 p = p->prev;                  p = p->prev;
                 if (ch_seek(p->pos))                  if (ch_seek(p->pos))
                         return (NULL_POSITION);                          return (-1);
                 for (clinenum = p->line, cpos = p->pos;  clinenum < linenum;  clinenum++)                  for (clinenum = p->line, cpos = p->pos;
                 {                      clinenum < linenum;
                       clinenum++) {
                         /*                          /*
                          * Allow a signal to abort this loop.                           * Allow a signal to abort this loop.
                          */                           */
                         cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL);                          cpos = forw_raw_line(cpos, NULL, NULL);
                         if (ABORT_SIGS())                          if (ABORT_SIGS())
                                 return (NULL_POSITION);                                  return (-1);
                         if (cpos == NULL_POSITION)                          if (cpos == -1)
                                 return (NULL_POSITION);                                  return (-1);
                 }                  }
         } else          } else {
         {  
                 /*                  /*
                  * Go backward.                   * Go backward.
                  */                   */
                 if (ch_seek(p->pos))                  if (ch_seek(p->pos))
                         return (NULL_POSITION);                          return (-1);
                 for (clinenum = p->line, cpos = p->pos;  clinenum > linenum;  clinenum--)                  for (clinenum = p->line, cpos = p->pos;
                 {                      clinenum > linenum;
                       clinenum--) {
                         /*                          /*
                          * Allow a signal to abort this loop.                           * Allow a signal to abort this loop.
                          */                           */
                         cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL);                          cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL);
                         if (ABORT_SIGS())                          if (ABORT_SIGS())
                                 return (NULL_POSITION);                                  return (-1);
                         if (cpos == NULL_POSITION)                          if (cpos == -1)
                                 return (NULL_POSITION);                                  return (-1);
                 }                  }
         }          }
         /*          /*
Line 449 
Line 424 
  * The argument "where" tells which line is to be considered   * The argument "where" tells which line is to be considered
  * the "current" line (e.g. TOP, BOTTOM, MIDDLE, etc).   * the "current" line (e.g. TOP, BOTTOM, MIDDLE, etc).
  */   */
         public LINENUM  LINENUM
 currline(where)  currline(int where)
         int where;  
 {  {
         POSITION pos;          off_t pos;
         POSITION len;          off_t len;
         LINENUM linenum;          LINENUM linenum;
   
         pos = position(where);          pos = position(where);
         len = ch_length();          len = ch_length();
         while (pos == NULL_POSITION && where >= 0 && where < sc_height)          while (pos == -1 && where >= 0 && where < sc_height)
                 pos = position(++where);                  pos = position(++where);
         if (pos == NULL_POSITION)          if (pos == -1)
                 pos = len;                  pos = len;
         linenum = find_linenum(pos);          linenum = find_linenum(pos);
         if (pos == len)          if (pos == len)

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8