Пример #1
0
/* Calculate the line number in buffer B at position POS.  If CACHEP
   is non-zero, initialize and facilitate the line-number cache.  The
   line number of the first line is 0.  If narrowing is in effect,
   count the lines are counted from the beginning of the visible
   portion of the buffer.

   The cache works as follows: To calculate the line number, we need
   two positions: position of point (POS) and the position from which
   to count newlines (BEG).  We start by setting BEG to BUF_BEGV.  If
   this would require too much searching (i.e. pos - BUF_BEGV >
   LINE_NUMBER_FAR), try to find a closer position in the ring.  If it
   is found, use that position for BEG, and increment the line number
   appropriately.

   If the calculation (with or without the cache lookup) required more
   than LINE_NUMBER_FAR characters of traversal, update the cache.  */
EMACS_INT
buffer_line_number (struct buffer *b, Charbpos pos, Boolint cachep,
                    Boolint respect_narrowing)
{
  Charbpos beg = respect_narrowing ? BUF_BEGV (b) : BUF_BEG (b);
  EMACS_INT cached_lines = 0;
  EMACS_INT shortage, line;

  if ((pos > beg ? pos - beg : beg - pos) <= LINE_NUMBER_FAR)
    cachep = 0;

  if (cachep && (respect_narrowing || BUF_BEG (b) == BUF_BEGV (b)))
    {
      if (NILP (b->text->line_number_cache))
	allocate_line_number_cache (b);
      /* If we don't know the line number of BUF_BEGV, calculate it now.  */
      if (XFIXNUM (LINE_NUMBER_BEGV (b)) == -1)
	{
	  LINE_NUMBER_BEGV (b) = Qzero;
	  /* #### This has a side-effect of changing the cache.  */
	  LINE_NUMBER_BEGV (b) =
	    make_fixnum (buffer_line_number (b, BUF_BEGV (b), 1, 0));
	}
      cached_lines = XFIXNUM (LINE_NUMBER_BEGV (b));
      get_nearest_line_number (b, &beg, pos, &cached_lines);
    }

  scan_buffer (b, '\n', beg, pos,
               pos > beg ? MOST_POSITIVE_FIXNUM : -MOST_POSITIVE_FIXNUM,
	       &shortage, 0);

  line = MOST_POSITIVE_FIXNUM - shortage;
  if (beg > pos)
    line = -line;
  line += cached_lines;

  if (cachep && (respect_narrowing || BUF_BEG (b) == BUF_BEGV (b)))
    {
      /* If too far, update the cache. */
      if ((pos > beg ? pos - beg : beg - pos) > LINE_NUMBER_FAR)
	add_position_to_cache (b, pos, line);
      /* Account for narrowing.  If cache is not used, this is
	 unnecessary, because we counted from BUF_BEGV anyway.  */
      line -= XFIXNUM (LINE_NUMBER_BEGV (b));
    }

  return line;
}
Пример #2
0
/* Get the nearest known position we know the line number of
   (i.e. BUF_BEGV, and cached positions).  The return position will be
   either closer than BEG, or BEG.  The line of this known position
   will be stored in LINE.

   *LINE should be initialized to the line number of BEG (normally,
   BEG will be BUF_BEGV, and *LINE will be XFIXNUM (LINE_NUMBER_BEGV).
   This will initialize the cache, if necessary.  */
static void
get_nearest_line_number (struct buffer *b, Charbpos *beg, Charbpos pos,
			 EMACS_INT *line)
{
  EMACS_INT i;
  Lisp_Object *ring = XVECTOR_DATA (LINE_NUMBER_RING (b));
  Charcount length = pos - *beg;

  if (length < 0)
    length = -length;

  /* Find the ring entry closest to POS, if it is closer than BEG. */
  for (i = 0; i < LINE_NUMBER_RING_SIZE && CONSP (ring[i]); i++)
    {
      Charbpos newpos = marker_position (XCAR (ring[i]));
      Charcount howfar = newpos - pos;
      if (howfar < 0)
	howfar = -howfar;
      if (howfar < length)
	{
	  length = howfar;
	  *beg = newpos;
	  *line = XFIXNUM (XCDR (ring[i]));
	}
    }
}
Пример #3
0
static int
plist_get_margin (Lisp_Object plist, Lisp_Object prop, int mm_p)
{
  Lisp_Object val =
    Fplist_get (plist, prop, make_fixnum (mswindows_get_default_margin (prop)));
  if (!FIXNUMP (val))
    invalid_argument ("Margin value must be an integer", val);

  return MulDiv (XFIXNUM (val), mm_p ? 254 : 100, 144);
}
Пример #4
0
DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
       doc: /* Call specific MS-DOS interrupt number INTERRUPT with REGISTERS.
Return the updated REGISTER vector.

INTERRUPT should be an integer in the range 0 to 255.
REGISTERS should be a vector produced by `make-register' and
`set-register-value'.  */)
  (Lisp_Object interrupt, Lisp_Object registers)
{
  register int i;
  int no;
  union REGS inregs, outregs;

  CHECK_FIXNUM (interrupt);
  no = (unsigned long) XFIXNUM (interrupt);
  CHECK_VECTOR (registers);
  if (no < 0 || no > 0xff || ASIZE (registers) != 8)
    return Qnil;
  for (i = 0; i < 8; i++)
    CHECK_FIXNUM (AREF (registers, i));

  inregs.x.ax    = (unsigned long) XFIXNAT (AREF (registers, 0));
  inregs.x.bx    = (unsigned long) XFIXNAT (AREF (registers, 1));
  inregs.x.cx    = (unsigned long) XFIXNAT (AREF (registers, 2));
  inregs.x.dx    = (unsigned long) XFIXNAT (AREF (registers, 3));
  inregs.x.si    = (unsigned long) XFIXNAT (AREF (registers, 4));
  inregs.x.di    = (unsigned long) XFIXNAT (AREF (registers, 5));
  inregs.x.cflag = (unsigned long) XFIXNAT (AREF (registers, 6));
  inregs.x.flags = (unsigned long) XFIXNAT (AREF (registers, 7));
Пример #5
0
static Lisp_Object
get_object_file_name (Lisp_Object filepos)
{
  REGISTER int fd;
  REGISTER Ibyte *name_nonreloc = 0;
  EMACS_INT position;
  Lisp_Object file, tem;
  Lisp_Object name_reloc = Qnil;
  int standard_doc_file = 0;

  if (FIXNUMP (filepos))
    {
      file = Vinternal_doc_file_name;
      standard_doc_file = 1;
      position = XFIXNUM (filepos);
    }
  else if (CONSP (filepos) && FIXNUMP (XCDR (filepos)))
    {
      file = XCAR (filepos);
      position = XFIXNUM (XCDR (filepos));
      if (position < 0)
	position = - position;
    }
  else
    return Qnil;

  if (!STRINGP (file))
    return Qnil;

  /* Put the file name in NAME as a C string.
     If it is relative, combine it with Vdoc_directory.  */

  tem = Ffile_name_absolute_p (file);
  if (NILP (tem))
    {
      Bytecount minsize;
      /* XEmacs: Move this check here.  OK if called during loadup to
	 load byte code instructions. */
      if (!STRINGP (Vdoc_directory))
	return Qnil;

      minsize = XSTRING_LENGTH (Vdoc_directory);
      /* sizeof ("../lib-src/") == 12 */
      if (minsize < 12)
	minsize = 12;
      name_nonreloc = alloca_ibytes (minsize + XSTRING_LENGTH (file) + 8);
      string_join (name_nonreloc, Vdoc_directory, file);
    }
  else
    name_reloc = file;

  fd = qxe_open (name_nonreloc ? name_nonreloc :
		 XSTRING_DATA (name_reloc), O_RDONLY | OPEN_BINARY, 0);
  if (fd < 0)
    {
      if (purify_flag)
	{
	    /* sizeof ("../lib-src/") == 12 */
	  name_nonreloc = alloca_ibytes (12 + XSTRING_LENGTH (file) + 8);
	  /* Preparing to dump; DOC file is probably not installed.
	     So check in ../lib-src. */
	  qxestrcpy_ascii (name_nonreloc, "../lib-src/");
	  qxestrcat (name_nonreloc, XSTRING_DATA (file));

	  fd = qxe_open (name_nonreloc, O_RDONLY | OPEN_BINARY, 0);
	}

      if (fd < 0)
	report_file_error ("Cannot open doc string file",
			   name_nonreloc ? build_istring (name_nonreloc) :
			   name_reloc);
    }

  tem = extract_object_file_name (fd, position, name_nonreloc, name_reloc,
			      standard_doc_file);
  retry_close (fd);

  if (!STRINGP (tem))
    signal_error_1 (Qinvalid_byte_code, tem);

  return tem;
}