Exemple #1
0
static void check_last_key_function (FVOID_STAR f)
{
   /* For syntax highlighting */
   if (Last_Key_Function != f)
     touch_window ();
#if 0
       && ((Last_Key_Function == (FVOID_STAR) ins_char_cmd)
	   || (Last_Key_Function == (FVOID_STAR) eol_cmd)
	   || (Last_Key_Function == (FVOID_STAR) delete_char_cmd)
	   || (Last_Key_Function == (FVOID_STAR) backward_delete_char_cmd)
	   || (Last_Key_Function == (FVOID_STAR) backward_delete_char_untabify)))

     register_change(0);
#endif
}
Exemple #2
0
/* Let "|" denote the window edges,
 *   "." denote text, "*" denotes the current location
 *
 *  .........|....*..........|....
 *  <---- col --->
 *  <-- wc -><-------sw------>
 * The contraints are: wc >= 0, col >= 0, sw > 0.
 * Let whs be the value of abs(Wants_HScroll).  We want to wc to satisfy
 *   wc+1 <= col <= wc + sw - 1
 * ==> col-sw+1 <= wc <= col-1
 * However, if wc does not satisfy this, then set wc such that:
 *
 *   wc + whs <= col <= wc + sw - whs
 *   col+whs-sw <= wc <= col-whs
 * Evidently, this requires:
 *    col+whs-sw < col-whs
 *    whs-sw < -whs
 *    2whs < sw ==> whs < sw/2
 *
 * As a special case, if col < sw, then set wc=0.
 */
static void set_hscroll(int col)
{
   int whs = abs(Wants_HScroll), wc = JWindow->hscroll_column - 1;
   int sw = Jed_Num_Screen_Cols-1;
   static Line *last;
   Line *tmp;
   int wc_min, wc_max;

#if JED_HAS_DISPLAY_LINE_NUMBERS
   sw -= CBuf->line_num_display_size;
#endif
   if (sw < 2)
     sw = 2;

   if (Wants_HScroll > 0)
     wc += HScroll;		       /* only this line scrolled */

   /* take care of last effect of horizontal scroll */
   if (last != NULL)
     {
	tmp = CLine;
	CLine = last;
	register_change(0);
	CLine = tmp;
	if (last != CLine)
	  HScroll = 0;

	last = NULL;
     }
   col--;			       /* use 0 origin */
   if (2*whs > sw)
     whs = sw/2;

   wc_min = col - sw + 1;
   if (wc_min < 0) wc_min = 0;
   wc_max = col - 1;
   if (wc < wc_min)
     wc = wc_min + whs;
   if (wc > wc_max)
     wc = wc_max - whs;

   if (col < sw)
     {
	if ((CBuf->modes & WRAP_MODE)
	    || (col <= sw - whs))
	  wc = 0;
     }

   if (Wants_HScroll < 0)
     {
	/* Scroll whole window */
	if (wc + 1 != JWindow->hscroll_column)
	  {
	     JWindow->hscroll_column = wc + 1;
	     touch_window();
	  }
	HScroll = 0;
     }
   else
     {
	/* Scroll just this line -- do not change hscroll_column */
	register_change(0);
	last = HScroll_Line = CLine;
	HScroll = wc - (JWindow->hscroll_column-1);
     }
}
Exemple #3
0
static void set_hscroll(int col)
{
   int hdiff, whs = abs(Wants_HScroll), wc = JWindow->hscroll_column - 1;
   int sw = Jed_Num_Screen_Cols - 1;
   static Line *last;
   Line *tmp;

#if JED_HAS_DISPLAY_LINE_NUMBERS
   sw -= CBuf->line_num_display_size;
#endif
   if (sw < 1)
     sw = 1;

   /* take care of last effect of horizontal scroll */
   if (last != NULL)
     {
	tmp = CLine;
	CLine = last;
	register_change(0);
	CLine = tmp;
	if (last != CLine)
	  {
#if 0
	     /* I need to think about this more */
	     if (Wants_HScroll < 0)
	       {
		  if (wc != 0)
		    {
		       JWindow->column = 1;
		       wc = 0;
		       touch_window ();
		    }
	       }
#endif
	     HScroll = 0;
	  }

	last = NULL;
     }

   col--;			       /* use 0 origin */
   hdiff = col - wc;
   if ((HScroll >= hdiff)
       || (HScroll <= hdiff - sw))
     {
	if (hdiff >= sw)
	  {
	     HScroll = hdiff - sw + whs;
	  }
	else if ((hdiff == 0) && (wc == 0)) HScroll = 0;
	else if (hdiff <= 1)
	  {
	     HScroll = hdiff - whs - 1;
	  }
	else HScroll = 0;
     }

   if (HScroll)
     {
	if (wc + HScroll < 0) HScroll = -wc;

	if (Wants_HScroll < 0)
	  {
	     JWindow->hscroll_column += HScroll;
	     touch_window();
	     HScroll = 0;
	  }
	else
	  {
	     register_change(0);
	     last = HScroll_Line = CLine;
	  }
     }
}
bool fs::file_changes::load(const char* filename)
{
  // If the file doesn't exist or is not a regular file...
  struct stat sbuf;
  if ((stat(filename, &sbuf) < 0) || (!S_ISREG(sbuf.st_mode))) {
    return false;
  }

  // If the file is empty...
  if (sbuf.st_size == 0) {
    return false;
  }

  // Open file for reading.
  int fd;
  if ((fd = open(filename, O_RDONLY)) < 0) {
    return false;
  }

  // Map file into memory.
  void* buf;
  if ((buf = mmap(NULL,
                  sbuf.st_size,
                  PROT_READ,
                  MAP_SHARED,
                  fd,
                  0)) == MAP_FAILED) {
    close(fd);
    return false;
  }

  const uint8_t* begin = reinterpret_cast<const uint8_t*>(buf);
  const uint8_t* end = begin + sbuf.st_size;

  size_t nline = 0;
  size_t nchanges = 0;

  do {
    nline++;

    // Search end of line.
    const uint8_t* eol;
    if ((eol = reinterpret_cast<const uint8_t*>(
                 memchr(begin, '\n', end - begin)
               )) == NULL) {
      munmap(buf, sbuf.st_size);
      close(fd);

      return false;
    }

    // If the line is too short...
    size_t linelen;
    if ((linelen = eol - begin) < 20) {
      munmap(buf, sbuf.st_size);
      close(fd);

      return false;
    }

    // First line?
    if (nline == 1) {
      if (memcmp(begin, "Number of changes: ", 19) != 0) {
        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }

      // Parse number of changes.
      begin += 19;
      size_t l = 0;
      while (begin < eol) {
        if ((*begin >= '0') && (*begin <= '9')) {
          uint64_t tmp;
          if ((tmp = (nchanges * 10) + (*begin - '0')) < nchanges) {
            munmap(buf, sbuf.st_size);
            close(fd);

            return false;
          }

          nchanges = tmp;
          l++;
        } else if ((l > 0) && (*begin == '.') && (begin + 1 == eol)) {
          break;
        } else {
          munmap(buf, sbuf.st_size);
          close(fd);

          return false;
        }

        begin++;
      }

      begin = eol + 1;
      continue;
    }

    fs::file_change::type t;

    // Get type of the file change.
    size_t skip;
    if (memcmp(begin, "Modify: ", 8) == 0) {
      t = fs::file_change::type::kModify;
      skip = 8;
    } else if (memcmp(begin, "Add: ", 5) == 0) {
      t = fs::file_change::type::kAdd;
      skip = 5;
    } else if (memcmp(begin, "Remove: ", 8) == 0) {
      t = fs::file_change::type::kRemove;
      skip = 8;
    } else {
      munmap(buf, sbuf.st_size);
      close(fd);

      return false;
    }

    begin += skip;

    // Parse offset.
    if (memcmp(begin, "offset: ", 8) != 0) {
      munmap(buf, sbuf.st_size);
      close(fd);

      return false;
    }

    begin += 8;

    uint64_t off = 0;
    size_t l = 0;
    while (begin < eol) {
      if ((*begin >= '0') && (*begin <= '9')) {
        uint64_t tmp;
        if ((tmp = (off * 10) + (*begin - '0')) < off) {
          munmap(buf, sbuf.st_size);
          close(fd);

          return false;
        }

        off = tmp;
        l++;
      } else if ((l > 0) && (*begin == ',')) {
        break;
      } else {
        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }

      begin++;
    }

    // Parse length.
    if ((begin + 10 >= eol) || (memcmp(begin, ", length: ", 10) != 0)) {
      munmap(buf, sbuf.st_size);
      close(fd);

      return false;
    }

    begin += 10;

    uint64_t len = 0;
    l = 0;
    while (begin < eol) {
      if ((*begin >= '0') && (*begin <= '9')) {
        uint64_t tmp;
        if ((tmp = (len * 10) + (*begin - '0')) < len) {
          munmap(buf, sbuf.st_size);
          close(fd);

          return false;
        }

        len = tmp;
        l++;
      } else if ((l > 0) &&
                 (*begin == '.') &&
                 (begin + 1 == eol) &&
                 (len > 0)) {
        break;
      } else {
        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }

      begin++;
    }

    begin = eol + 1;

    if (t == file_change::type::kRemove) {
      if (!remove(off, NULL, len)) {
        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }
    } else {
      if ((eol = reinterpret_cast<const uint8_t*>(
                   memchr(begin, '\n', end - begin)
                 )) == NULL) {
        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }

      if ((linelen = eol - begin) != 2 * len) {
        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }

      uint8_t* line;
      if ((line = reinterpret_cast<uint8_t*>(malloc(len))) == NULL) {
        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }

      l = 0;

      for (size_t i = 0; i < linelen; i += 2) {
        uint8_t c;
        if ((begin[i] >= '0') && (begin[i] <= '9')) {
          c = begin[i] - '0';
        } else if ((begin[i] >= 'a') && (begin[i] <= 'f')) {
          c = begin[i] - 'a' + 10;
        } else if ((begin[i] >= 'A') && (begin[i] <= 'F')) {
          c = begin[i] - 'A' + 10;
        } else {
          free(line);

          munmap(buf, sbuf.st_size);
          close(fd);

          return false;
        }

        if ((begin[i + 1] >= '0') && (begin[i + 1] <= '9')) {
          c = (c * 16) + (begin[i + 1] - '0');
        } else if ((begin[i + 1] >= 'a') && (begin[i + 1] <= 'f')) {
          c = (c * 16) + (begin[i + 1] - 'a' + 10);
        } else if ((begin[i + 1] >= 'A') && (begin[i + 1] <= 'F')) {
          c = (c * 16) + (begin[i + 1] - 'A' + 10);
        } else {
          free(line);

          munmap(buf, sbuf.st_size);
          close(fd);

          return false;
        }

        line[l++] = c;
      }

      if (!register_change(t, off, NULL, line, len)) {
        free(line);

        munmap(buf, sbuf.st_size);
        close(fd);

        return false;
      }

      free(line);

      begin = eol + 1;
    }
  } while (begin < end);

  munmap(buf, sbuf.st_size);
  close(fd);

  return (nchanges == _M_used);
}