Exemple #1
0
Lisp_Object
unparesseuxify_doc_string (int fd, EMACS_INT position,
                           Ibyte *name_nonreloc, Lisp_Object name_reloc,
			   int standard_doc_file)
{
  Ibyte buf[512 * 32 + 1];
  Ibyte *buffer = buf;
  int buffer_size = sizeof (buf) - 1;
  Ibyte *from, *to;
  REGISTER Ibyte *p = buffer;
  Lisp_Object return_me;
  Lisp_Object fdstream = Qnil, instream = Qnil;
  struct gcpro gcpro1, gcpro2;

  GCPRO2 (fdstream, instream);

  if (0 > lseek (fd, position, 0))
    {
      if (name_nonreloc)
	name_reloc = build_istring (name_nonreloc);
      return_me = list3 (build_msg_string
			 ("Position out of range in doc string file"),
			  name_reloc, make_fixnum (position));
      goto done;
    }

  fdstream = make_filedesc_input_stream (fd, 0, -1, 0, NULL);
  Lstream_set_buffering (XLSTREAM (fdstream), LSTREAM_UNBUFFERED, 0);
  instream =
    make_coding_input_stream
      /* Major trouble if we are too clever when reading byte-code
	 instructions!

	 #### We should have a way of handling escape-quoted elc files
	 (i.e. files with non-ASCII/Latin-1 chars in them).  Currently this
	 is "solved" in bytecomp.el by never inserting lazy references in
	 such files. */
      (XLSTREAM (fdstream), standard_doc_file ? Qescape_quoted : Qbinary,
       CODING_DECODE, 0);
  Lstream_set_buffering (XLSTREAM (instream), LSTREAM_UNBUFFERED, 0);
  
  /* Read the doc string into a buffer.
     Use the fixed buffer BUF if it is big enough; otherwise allocate one.
     We store the buffer in use in BUFFER and its size in BUFFER_SIZE.  */

  while (1)
    {
      int space_left = buffer_size - (p - buffer);
      int nread;

      /* Switch to a bigger buffer if we need one.  */
      if (space_left == 0)
	{
          Ibyte *old_buffer = buffer;
	  buffer_size *= 2;

	  if (buffer == buf)
	    {
	      buffer = xnew_ibytes (buffer_size + 1);
	      memcpy (buffer, old_buffer, p - old_buffer);
	    }
	  else
            XREALLOC_ARRAY (buffer, Ibyte, buffer_size + 1);
          p += buffer - old_buffer;
	  space_left = buffer_size - (p - buffer);
	}

      /* Don't read too much at one go.  */
      if (space_left > 1024 * 8)
	space_left = 1024 * 8;
      nread = Lstream_read (XLSTREAM (instream), p, space_left);
      if (nread < 0)
	{
	  return_me = list1 (build_msg_string
			     ("Read error on documentation file"));
	  goto done;
	}
      p[nread] = 0;
      if (!nread)
	break;
      {
	Ibyte *p1 = qxestrchr (p, '\037'); /* End of doc string marker */
	if (p1)
	  {
	    *p1 = 0;
	    p = p1;
	    break;
	  }
      }
      p += nread;
    }

  /* Scan the text and remove quoting with ^A (char code 1).
     ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_.  */
  from = to = buffer;
  while (from < p)
    {
      if (*from != 1 /*^A*/)
	*to++ = *from++;
      else
	{
	  int c = *(++from);

	  from++;
          switch (c)
            {
            case 1:   *to++ =  c;     break;
            case '0': *to++ = '\0';   break;
            case '_': *to++ = '\037'; break;
            default:
              return_me = list2 (build_msg_string
	("Invalid data in documentation file -- ^A followed by weird code"),
                                 make_fixnum (c));
              goto done;
            }
	}
    }

  return_me = make_string (buffer, to - buffer);

 done:
  if (!NILP (instream))
    {
      Lstream_delete (XLSTREAM (instream));
      Lstream_delete (XLSTREAM (fdstream));
    }
  UNGCPRO;
  if (buffer != buf) /* We must have allocated buffer above */
    xfree (buffer);
  return return_me;
}
Exemple #2
0
static Lisp_Object
extract_object_file_name (int fd, EMACS_INT doc_pos,
			  Ibyte *name_nonreloc, Lisp_Object name_reloc,
			  int standard_doc_file)
{
  Ibyte buf[DOC_MAX_FILENAME_LENGTH+1];
  Ibyte *buffer = buf;
  int buffer_size = sizeof (buf) - 1, space_left;
  Ibyte *from, *to;
  REGISTER Ibyte *p = buffer;
  Lisp_Object return_me;
  Lisp_Object fdstream = Qnil, instream = Qnil;
  struct gcpro gcpro1, gcpro2;
  EMACS_INT position, seenS = 0;

  GCPRO2 (fdstream, instream);

  position = doc_pos > buffer_size  ? 
    doc_pos - buffer_size : 0; 

  if (0 > lseek (fd, position, 0))
    {
      if (name_nonreloc)
	name_reloc = build_istring (name_nonreloc);
      return_me = list3 (build_msg_string
			 ("Position out of range in doc string file"),
			  name_reloc, make_fixnum (position));
      goto done;
    }

  fdstream = make_filedesc_input_stream (fd, 0, -1, 0, NULL);
  Lstream_set_buffering (XLSTREAM (fdstream), LSTREAM_UNBUFFERED, 0);
  instream =
    make_coding_input_stream
      (XLSTREAM (fdstream), standard_doc_file ? Qescape_quoted : Qbinary,
       CODING_DECODE, 0);
  Lstream_set_buffering (XLSTREAM (instream), LSTREAM_UNBUFFERED, 0);

  space_left = buffer_size - (p - buffer);
  while (space_left > 0)
    {
      int nread;

      nread = Lstream_read (XLSTREAM (instream), p, space_left);
      if (nread < 0)
	{
	  return_me = list1 (build_msg_string
			     ("Read error on documentation file"));
	  goto done;
	}

      p[nread] = 0;

      if (!nread)
	break;

      p += nread;
      space_left = buffer_size - (p - buffer);
    }

  /* First, search backward for the "\037S" that marks the beginning of the
     file name, then search forward from that to the newline or to the end
     of the buffer. */
  from = p; 

  while (from > buf)
    {
      --from;
      if (seenS)
	{
	  if ('\037' == *from) 
	    {
	      /* Got a file name; adjust `from' to point to it, break out of
		 the loop.  */
	      from += 2;
	      break; 
	    }
	}
      /* Is *from 'S' ? */
      seenS = ('S' == *from);
    }

  if (buf == from)
    {
      /* We've scanned back to the beginning of the buffer without hitting
	 the file name. Either the file name plus the symbol name is longer
	 than DOC_MAX_FILENAME_LENGTH--which shouldn't happen, because it'll
	 trigger an assertion failure in make-docfile, the DOC file is
	 corrupt, or it was produced by a version of make-docfile that
	 doesn't store the file name with the symbol name and docstring.  */ 
      return_me = list1 (build_msg_string
			 ("Object file name not stored in doc file"));
      goto done;
    }

  to = from;
  /* Search for the end of the file name. */
  while (++to < p)
    {
      if ('\n' == *to || '\037' == *to)
	{
	  break;
	}
    }

  /* Don't require the file name to end in a newline. */
  return_me = make_string (from, to - from);

 done:
  if (!NILP (instream))
    {
      Lstream_delete (XLSTREAM (instream));
      Lstream_delete (XLSTREAM (fdstream));
    }

  UNGCPRO;
  return return_me;
}
Exemple #3
0
USID
event_stream_unixoid_create_stream_pair (void* inhandle, void* outhandle,
					 Lisp_Object* instream,
					 Lisp_Object* outstream,
					 int flags)
{
  int infd, outfd;
  /* Decode inhandle and outhandle. Their meaning depends on
     the process implementation being used. */
#if defined (HAVE_WIN32_PROCESSES)
  /* We're passed in Windows handles. Open new fds for them */
  if ((HANDLE)inhandle != INVALID_HANDLE_VALUE)
    {
      infd = open_osfhandle ((HANDLE)inhandle, 0);
      if (infd < 0)
	return USID_ERROR;
    }
  else
    infd = -1;

  if ((HANDLE)outhandle != INVALID_HANDLE_VALUE)
    {
      outfd = open_osfhandle ((HANDLE)outhandle, 0);
      if (outfd < 0)
	{
	  if (infd >= 0)
	    close (infd);
	  return USID_ERROR;
	}
    }
  else
    outfd = -1;

  flags = 0;
#elif defined (HAVE_UNIX_PROCESSES)
  /* We are passed plain old file descs */
  infd  = (int)inhandle;
  outfd = (int)outhandle;
#else
# error Which processes do you have?
#endif

  *instream = (infd >= 0
	       ? make_filedesc_input_stream (infd, 0, -1, 0)
	       : Qnil);

  *outstream = (outfd >= 0
		? make_filedesc_output_stream (outfd, 0, -1, LSTR_BLOCKED_OK)
		: Qnil);

#if defined(HAVE_UNIX_PROCESSES) && defined(HAVE_PTYS)
  /* FLAGS is process->pty_flag for UNIX_PROCESSES */
  if ((flags & STREAM_PTY_FLUSHING) && outfd >= 0)
    {
      Bufbyte eof_char = get_eof_char (outfd);
      int pty_max_bytes = get_pty_max_bytes (outfd);
      filedesc_stream_set_pty_flushing (XLSTREAM(*outstream), pty_max_bytes, eof_char);
    }
#endif

  return FD_TO_USID (infd);
}