コード例 #1
0
static void *
check_nonnull (void *p)
{
  if (! p)
    memory_exhausted (errno);
  return p;
}
コード例 #2
0
ファイル: make-docfile.c プロジェクト: cpitclaudel/emacs
static struct global *
add_global (enum global_type type, char const *name, int value,
	    char const *svalue)
{
  /* Ignore the one non-symbol that can occur.  */
  if (strcmp (name, "..."))
    {
      if (num_globals == num_globals_allocated)
	{
	  ptrdiff_t num_globals_max = (min (PTRDIFF_MAX, SIZE_MAX)
				       / sizeof *globals);
	  if (num_globals_allocated == num_globals_max)
	    memory_exhausted ();
	  if (num_globals_allocated < num_globals_max / 2)
	    num_globals_allocated = 2 * num_globals_allocated + 1;
	  else
	    num_globals_allocated = num_globals_max;
	  globals = xrealloc (globals, num_globals_allocated * sizeof *globals);
	}

      ++num_globals;

      ptrdiff_t namesize = strlen (name) + 1;
      char *buf = xmalloc (namesize + (svalue ? strlen (svalue) + 1 : 0));
      globals[num_globals - 1].type = type;
      globals[num_globals - 1].name = strcpy (buf, name);
      if (svalue)
	globals[num_globals - 1].v.svalue = strcpy (buf + namesize, svalue);
      else
	globals[num_globals - 1].v.value = value;
      globals[num_globals - 1].flags = 0;
      return globals + num_globals - 1;
    }
  return NULL;
}
コード例 #3
0
ファイル: make-docfile.c プロジェクト: cpitclaudel/emacs
static void *
xrealloc (void *arg, ptrdiff_t size)
{
  void *result = realloc (arg, size);
  if (result == NULL)
    memory_exhausted ();
  return result;
}
コード例 #4
0
ファイル: make-docfile.c プロジェクト: cpitclaudel/emacs
static void *
xmalloc (ptrdiff_t size)
{
  void *result = malloc (size);
  if (result == NULL)
    memory_exhausted ();
  return result;
}
コード例 #5
0
void *
checked_grow_alloc (void *ptr, size_t *size)
{
  size_t max = -1;
  if (*size == max)
    memory_exhausted (0);
  *size = *size < max / 2 ? 2 * *size : max;
  return checked_realloc (ptr, *size);
}
コード例 #6
0
ファイル: make-docfile.c プロジェクト: cpitclaudel/emacs
static void
scan_lisp_file (const char *filename, const char *mode)
{
  FILE *infile;
  int c;
  char *saved_string = 0;
  /* These are the only files that are loaded uncompiled, and must
     follow the conventions of the doc strings expected by this
     function.  These conventions are automatically followed by the
     byte compiler when it produces the .elc files.  */
  static struct {
    const char *fn;
    int fl;
  } const uncompiled[] = {
    DEF_ELISP_FILE (loaddefs.el),
    DEF_ELISP_FILE (loadup.el),
    DEF_ELISP_FILE (charprop.el),
    DEF_ELISP_FILE (cp51932.el),
    DEF_ELISP_FILE (eucjp-ms.el)
  };
  int i;
  int flen = strlen (filename);

  if (generate_globals)
    fatal ("scanning lisp file when -g specified");
  if (flen > 3 && !strcmp (filename + flen - 3, ".el"))
    {
      bool match = false;
      for (i = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]); i++)
	{
	  if (uncompiled[i].fl <= flen
	      && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn)
	      && (flen == uncompiled[i].fl
		  || IS_SLASH (filename[flen - uncompiled[i].fl - 1])))
	    {
	      match = true;
	      break;
	    }
	}
      if (!match)
	fatal ("uncompiled lisp file %s is not supported", filename);
    }

  infile = fopen (filename, mode);
  if (infile == NULL)
    {
      perror (filename);
      exit (EXIT_FAILURE);
    }

  c = '\n';
  while (!feof (infile))
    {
      char buffer[BUFSIZ];
      char type;

      /* If not at end of line, skip till we get to one.  */
      if (c != '\n' && c != '\r')
	{
	  c = getc (infile);
	  continue;
	}
      /* Skip the line break.  */
      while (c == '\n' || c == '\r')
	c = getc (infile);
      /* Detect a dynamic doc string and save it for the next expression.  */
      if (c == '#')
	{
	  c = getc (infile);
	  if (c == '@')
	    {
	      ptrdiff_t length = 0;
	      ptrdiff_t i;

	      /* Read the length.  */
	      while ((c = getc (infile),
		      c >= '0' && c <= '9'))
		{
		  if (INT_MULTIPLY_WRAPV (length, 10, &length)
		      || INT_ADD_WRAPV (length, c - '0', &length)
		      || SIZE_MAX < length)
		    memory_exhausted ();
		}

	      if (length <= 1)
		fatal ("invalid dynamic doc string length");

	      if (c != ' ')
		fatal ("space not found after dynamic doc string length");

	      /* The next character is a space that is counted in the length
		 but not part of the doc string.
		 We already read it, so just ignore it.  */
	      length--;

	      /* Read in the contents.  */
	      free (saved_string);
	      saved_string = xmalloc (length);
	      for (i = 0; i < length; i++)
		saved_string[i] = getc (infile);
	      /* The last character is a ^_.
		 That is needed in the .elc file
		 but it is redundant in DOC.  So get rid of it here.  */
	      saved_string[length - 1] = 0;
	      /* Skip the line break.  */
	      while (c == '\n' || c == '\r')
		c = getc (infile);
	      /* Skip the following line.  */
	      while (c != '\n' && c != '\r')
		c = getc (infile);
	    }
	  continue;
	}

      if (c != '(')
	continue;

      read_lisp_symbol (infile, buffer);

      if (! strcmp (buffer, "defun")
	  || ! strcmp (buffer, "defmacro")
	  || ! strcmp (buffer, "defsubst"))
	{
	  type = 'F';
	  read_lisp_symbol (infile, buffer);

	  /* Skip the arguments: either "nil" or a list in parens.  */

	  c = getc (infile);
	  if (c == 'n') /* nil */
	    {
	      if ((c = getc (infile)) != 'i'
		  || (c = getc (infile)) != 'l')
		{
		  fprintf (stderr, "## unparsable arglist in %s (%s)\n",
			   buffer, filename);
		  continue;
		}
	    }
	  else if (c != '(')
	    {
	      fprintf (stderr, "## unparsable arglist in %s (%s)\n",
		       buffer, filename);
	      continue;
	    }
	  else
	    while (c != ')')
	      c = getc (infile);
	  skip_white (infile);

	  /* If the next three characters aren't `dquote bslash newline'
	     then we're not reading a docstring.
	   */
	  if ((c = getc (infile)) != '"'
	      || (c = getc (infile)) != '\\'
	      || ((c = getc (infile)) != '\n' && c != '\r'))
	    {
#ifdef DEBUG
	      fprintf (stderr, "## non-docstring in %s (%s)\n",
		       buffer, filename);
#endif
	      continue;
	    }
	}

      /* defcustom can only occur in uncompiled Lisp files.  */
      else if (! strcmp (buffer, "defvar")
	       || ! strcmp (buffer, "defconst")
	       || ! strcmp (buffer, "defcustom"))
	{
	  type = 'V';
	  read_lisp_symbol (infile, buffer);

	  if (saved_string == 0)
	    if (!search_lisp_doc_at_eol (infile))
	      continue;
	}

      else if (! strcmp (buffer, "custom-declare-variable")
	       || ! strcmp (buffer, "defvaralias")
	       )
	{
	  type = 'V';

	  c = getc (infile);
	  if (c == '\'')
	    read_lisp_symbol (infile, buffer);
	  else
	    {
	      if (c != '(')
		{
		  fprintf (stderr,
			   "## unparsable name in custom-declare-variable in %s\n",
			   filename);
		  continue;
		}
	      read_lisp_symbol (infile, buffer);
	      if (strcmp (buffer, "quote"))
		{
		  fprintf (stderr,
			   "## unparsable name in custom-declare-variable in %s\n",
			   filename);
		  continue;
		}
	      read_lisp_symbol (infile, buffer);
	      c = getc (infile);
	      if (c != ')')
		{
		  fprintf (stderr,
			   "## unparsable quoted name in custom-declare-variable in %s\n",
			   filename);
		  continue;
		}
	    }

	  if (saved_string == 0)
	    if (!search_lisp_doc_at_eol (infile))
	      continue;
	}

      else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
	{
	  type = 'F';

	  c = getc (infile);
	  if (c == '\'')
	    read_lisp_symbol (infile, buffer);
	  else
	    {
	      if (c != '(')
		{
		  fprintf (stderr, "## unparsable name in fset in %s\n",
			   filename);
		  continue;
		}
	      read_lisp_symbol (infile, buffer);
	      if (strcmp (buffer, "quote"))
		{
		  fprintf (stderr, "## unparsable name in fset in %s\n",
			   filename);
		  continue;
		}
	      read_lisp_symbol (infile, buffer);
	      c = getc (infile);
	      if (c != ')')
		{
		  fprintf (stderr,
			   "## unparsable quoted name in fset in %s\n",
			   filename);
		  continue;
		}
	    }

	  if (saved_string == 0)
	    if (!search_lisp_doc_at_eol (infile))
	      continue;
	}

      else if (! strcmp (buffer, "autoload"))
	{
	  type = 'F';
	  c = getc (infile);
	  if (c == '\'')
	    read_lisp_symbol (infile, buffer);
	  else
	    {
	      if (c != '(')
		{
		  fprintf (stderr, "## unparsable name in autoload in %s\n",
			   filename);
		  continue;
		}
	      read_lisp_symbol (infile, buffer);
	      if (strcmp (buffer, "quote"))
		{
		  fprintf (stderr, "## unparsable name in autoload in %s\n",
			   filename);
		  continue;
		}
	      read_lisp_symbol (infile, buffer);
	      c = getc (infile);
	      if (c != ')')
		{
		  fprintf (stderr,
			   "## unparsable quoted name in autoload in %s\n",
			   filename);
		  continue;
		}
	    }
	  skip_white (infile);
	  if ((c = getc (infile)) != '\"')
	    {
	      fprintf (stderr, "## autoload of %s unparsable (%s)\n",
		       buffer, filename);
	      continue;
	    }
	  read_c_string_or_comment (infile, 0, false, 0);

	  if (saved_string == 0)
	    if (!search_lisp_doc_at_eol (infile))
	      continue;
	}

#ifdef DEBUG
      else if (! strcmp (buffer, "if")
	       || ! strcmp (buffer, "byte-code"))
	continue;
#endif

      else
	{
#ifdef DEBUG
	  fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
		   buffer, filename);
#endif
	  continue;
	}

      /* At this point, we should either use the previous dynamic doc string in
	 saved_string or gobble a doc string from the input file.
	 In the latter case, the opening quote (and leading backslash-newline)
	 have already been read.  */

      printf ("\037%c%s\n", type, buffer);
      if (saved_string)
	{
	  fputs (saved_string, stdout);
	  /* Don't use one dynamic doc string twice.  */
	  free (saved_string);
	  saved_string = 0;
	}
      else
	read_c_string_or_comment (infile, 1, false, 0);
    }
  free (saved_string);
  if (ferror (infile) || fclose (infile) != 0)
    fatal ("%s: read error", filename);
}