mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
etags: remove some arbitrary limits
etags had undefined behavior if input files, lines, tags, etc., had more than INT_MAX bytes. Clean up the usage of integer types to fix the overflow errors I found. * admin/merge-gnulib (GNULIB_MODULES): Add mempcpy. * lib-src/etags.c: Include inttypes.h, intprops.h. (memcpyz): New function. Use it to simplify several occurrences of memcpy followed by storing a trailing '\0'. (xnew): Use xnmalloc, to catch overflow on integer multiplication. (xrnew): Change last arg to multiplier. The type is not needed. All callers changed. (node, lineno, charno, linecharno, invalidcharno, make_tag): (pfnote, add_node, number_len, C_symtype, lbz, Makefile_targets) (readline): Use intmax_t for line numbers and character positions, instead of int or long. (linebuffer, make_tag, pfnote, total_size_of_entries, put_entry) (in_word_set, C_symtype, token, cstack, pushclass_above): (popclass_above, write_classname, consider_token, C_entries) (Ruby_functions, Makefile_targets, Lua_functions, TeX_commands) (TeX_decode_env, erlang_func, erlang_attribute, erlang_atom) (substitute, regex_tag_multiline, nocase_tail, readline_interval) (readline, savenstr, concat, etags_getcwd, relative_filename) (linebuffer_setlen): Use ptrdiff_t for object sizes, instead of int or long or unsigned or size_t. (write_classname, C_entries): Avoid sprintf, as the result could exceed INT_MAX bytes and then behavior goes haywire. (main): Use int, instead of unsigned, for argv counts. (get_language_from_filename): Use bool for boolean. (Ruby_functions): Prefer strcpy to memcpy when copying "=". (linebuffer_setlen): Use ‘if’ instead of ‘while’. (memory_full, xnmalloc, xnrealloc): New functions. (xmalloc): Use memory_full, and take a ptrdiff_t instead of a size_t. (xrealloc): Remove; no longer needed. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * lib/mempcpy.c, m4/mempcpy.m4: New files, copied from Gnulib.
This commit is contained in:
parent
75b41a38dd
commit
cffa5703b9
6 changed files with 287 additions and 194 deletions
|
|
@ -37,7 +37,7 @@ GNULIB_MODULES='
|
||||||
filemode filevercmp flexmember fpieee fstatat fsusage fsync
|
filemode filevercmp flexmember fpieee fstatat fsusage fsync
|
||||||
getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
|
getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
|
||||||
ieee754-h ignore-value intprops largefile lstat
|
ieee754-h ignore-value intprops largefile lstat
|
||||||
manywarnings memmem-simple memrchr minmax mkostemp mktime nstrftime
|
manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
|
||||||
pathmax pipe2 pselect pthread_sigmask putenv
|
pathmax pipe2 pselect pthread_sigmask putenv
|
||||||
qcopy-acl readlink readlinkat regex
|
qcopy-acl readlink readlinkat regex
|
||||||
sig2str socklen stat-time std-gnu11 stdalign stddef stdio
|
sig2str socklen stat-time std-gnu11 stdalign stddef stdio
|
||||||
|
|
|
||||||
404
lib-src/etags.c
404
lib-src/etags.c
|
|
@ -114,6 +114,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
|
||||||
# define O_CLOEXEC O_NOINHERIT
|
# define O_CLOEXEC O_NOINHERIT
|
||||||
#endif /* WINDOWSNT */
|
#endif /* WINDOWSNT */
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -123,6 +124,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <binary-io.h>
|
#include <binary-io.h>
|
||||||
|
#include <intprops.h>
|
||||||
#include <unlocked-io.h>
|
#include <unlocked-io.h>
|
||||||
#include <c-ctype.h>
|
#include <c-ctype.h>
|
||||||
#include <c-strcase.h>
|
#include <c-strcase.h>
|
||||||
|
|
@ -141,6 +143,14 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
|
||||||
# define CTAGS false
|
# define CTAGS false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Copy to DEST from SRC (containing LEN bytes), and append a NUL byte. */
|
||||||
|
static void
|
||||||
|
memcpyz (void *dest, void const *src, ptrdiff_t len)
|
||||||
|
{
|
||||||
|
char *e = mempcpy (dest, src, len);
|
||||||
|
*e = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
streq (char const *s, char const *t)
|
streq (char const *s, char const *t)
|
||||||
{
|
{
|
||||||
|
|
@ -235,11 +245,11 @@ endtoken (unsigned char c)
|
||||||
/*
|
/*
|
||||||
* xnew, xrnew -- allocate, reallocate storage
|
* xnew, xrnew -- allocate, reallocate storage
|
||||||
*
|
*
|
||||||
* SYNOPSIS: Type *xnew (int n, Type);
|
* SYNOPSIS: Type *xnew (ptrdiff_t n, Type);
|
||||||
* void xrnew (OldPointer, int n, Type);
|
* void xrnew (OldPointer, ptrdiff_t n, int multiplier);
|
||||||
*/
|
*/
|
||||||
#define xnew(n, Type) ((Type *) xmalloc ((n) * sizeof (Type)))
|
#define xnew(n, Type) ((Type *) xnmalloc (n, sizeof (Type)))
|
||||||
#define xrnew(op, n, Type) ((op) = (Type *) xrealloc (op, (n) * sizeof (Type)))
|
#define xrnew(op, n, m) ((op) = xnrealloc (op, n, (m) * sizeof *(op)))
|
||||||
|
|
||||||
typedef void Lang_function (FILE *);
|
typedef void Lang_function (FILE *);
|
||||||
|
|
||||||
|
|
@ -282,8 +292,8 @@ typedef struct node_st
|
||||||
bool valid; /* write this tag on the tag file */
|
bool valid; /* write this tag on the tag file */
|
||||||
bool is_func; /* function tag: use regexp in CTAGS mode */
|
bool is_func; /* function tag: use regexp in CTAGS mode */
|
||||||
bool been_warned; /* warning already given for duplicated tag */
|
bool been_warned; /* warning already given for duplicated tag */
|
||||||
int lno; /* line number tag is on */
|
intmax_t lno; /* line number tag is on */
|
||||||
long cno; /* character number line starts on */
|
intmax_t cno; /* character number line starts on */
|
||||||
} node;
|
} node;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -295,8 +305,8 @@ typedef struct node_st
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
long size;
|
ptrdiff_t size;
|
||||||
int len;
|
ptrdiff_t len;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
} linebuffer;
|
} linebuffer;
|
||||||
|
|
||||||
|
|
@ -365,7 +375,7 @@ static void just_read_file (FILE *);
|
||||||
|
|
||||||
static language *get_language_from_langname (const char *);
|
static language *get_language_from_langname (const char *);
|
||||||
static void readline (linebuffer *, FILE *);
|
static void readline (linebuffer *, FILE *);
|
||||||
static long readline_internal (linebuffer *, FILE *, char const *);
|
static ptrdiff_t readline_internal (linebuffer *, FILE *, char const *);
|
||||||
static bool nocase_tail (const char *);
|
static bool nocase_tail (const char *);
|
||||||
static void get_tag (char *, char **);
|
static void get_tag (char *, char **);
|
||||||
static void get_lispy_tag (char *);
|
static void get_lispy_tag (char *);
|
||||||
|
|
@ -385,7 +395,7 @@ static void process_file (FILE *, char *, language *);
|
||||||
static void find_entries (FILE *);
|
static void find_entries (FILE *);
|
||||||
static void free_tree (node *);
|
static void free_tree (node *);
|
||||||
static void free_fdesc (fdesc *);
|
static void free_fdesc (fdesc *);
|
||||||
static void pfnote (char *, bool, char *, int, int, long);
|
static void pfnote (char *, bool, char *, ptrdiff_t, intmax_t, intmax_t);
|
||||||
static void invalidate_nodes (fdesc *, node **);
|
static void invalidate_nodes (fdesc *, node **);
|
||||||
static void put_entries (node *);
|
static void put_entries (node *);
|
||||||
|
|
||||||
|
|
@ -393,7 +403,7 @@ static char *concat (const char *, const char *, const char *);
|
||||||
static char *skip_spaces (char *);
|
static char *skip_spaces (char *);
|
||||||
static char *skip_non_spaces (char *);
|
static char *skip_non_spaces (char *);
|
||||||
static char *skip_name (char *);
|
static char *skip_name (char *);
|
||||||
static char *savenstr (const char *, int);
|
static char *savenstr (const char *, ptrdiff_t);
|
||||||
static char *savestr (const char *);
|
static char *savestr (const char *);
|
||||||
static char *etags_getcwd (void);
|
static char *etags_getcwd (void);
|
||||||
static char *relative_filename (char *, char *);
|
static char *relative_filename (char *, char *);
|
||||||
|
|
@ -403,9 +413,11 @@ static bool filename_is_absolute (char *f);
|
||||||
static void canonicalize_filename (char *);
|
static void canonicalize_filename (char *);
|
||||||
static char *etags_mktmp (void);
|
static char *etags_mktmp (void);
|
||||||
static void linebuffer_init (linebuffer *);
|
static void linebuffer_init (linebuffer *);
|
||||||
static void linebuffer_setlen (linebuffer *, int);
|
static void linebuffer_setlen (linebuffer *, ptrdiff_t);
|
||||||
static void *xmalloc (size_t);
|
static void *xmalloc (ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1));
|
||||||
static void *xrealloc (void *, size_t);
|
static void *xnmalloc (ptrdiff_t, ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1,2));
|
||||||
|
static void *xnrealloc (void *, ptrdiff_t, ptrdiff_t)
|
||||||
|
ATTRIBUTE_ALLOC_SIZE ((2,3));
|
||||||
|
|
||||||
|
|
||||||
static char searchar = '/'; /* use /.../ searches */
|
static char searchar = '/'; /* use /.../ searches */
|
||||||
|
|
@ -420,12 +432,12 @@ static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */
|
||||||
static fdesc *fdhead; /* head of file description list */
|
static fdesc *fdhead; /* head of file description list */
|
||||||
static fdesc *curfdp; /* current file description */
|
static fdesc *curfdp; /* current file description */
|
||||||
static char *infilename; /* current input file name */
|
static char *infilename; /* current input file name */
|
||||||
static int lineno; /* line number of current line */
|
static intmax_t lineno; /* line number of current line */
|
||||||
static long charno; /* current character number */
|
static intmax_t charno; /* current character number */
|
||||||
static long linecharno; /* charno of start of current line */
|
static intmax_t linecharno; /* charno of start of current line */
|
||||||
static char *dbp; /* pointer to start of current tag */
|
static char *dbp; /* pointer to start of current tag */
|
||||||
|
|
||||||
static const int invalidcharno = -1;
|
static intmax_t const invalidcharno = -1;
|
||||||
|
|
||||||
static node *nodehead; /* the head of the binary tree of tags */
|
static node *nodehead; /* the head of the binary tree of tags */
|
||||||
static node *last_node; /* the last node created */
|
static node *last_node; /* the last node created */
|
||||||
|
|
@ -1070,7 +1082,7 @@ int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned int nincluded_files;
|
int nincluded_files;
|
||||||
char **included_files;
|
char **included_files;
|
||||||
argument *argbuffer;
|
argument *argbuffer;
|
||||||
int current_arg, file_count;
|
int current_arg, file_count;
|
||||||
|
|
@ -1484,7 +1496,7 @@ get_language_from_interpreter (char *interpreter)
|
||||||
* Return a language given the file name.
|
* Return a language given the file name.
|
||||||
*/
|
*/
|
||||||
static language *
|
static language *
|
||||||
get_language_from_filename (char *file, int case_sensitive)
|
get_language_from_filename (char *file, bool case_sensitive)
|
||||||
{
|
{
|
||||||
language *lang;
|
language *lang;
|
||||||
const char **name, **ext, *suffix;
|
const char **name, **ext, *suffix;
|
||||||
|
|
@ -1918,26 +1930,26 @@ find_entries (FILE *inf)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
make_tag (const char *name, /* tag name, or NULL if unnamed */
|
make_tag (const char *name, /* tag name, or NULL if unnamed */
|
||||||
int namelen, /* tag length */
|
ptrdiff_t namelen, /* tag length */
|
||||||
bool is_func, /* tag is a function */
|
bool is_func, /* tag is a function */
|
||||||
char *linestart, /* start of the line where tag is */
|
char *linestart, /* start of the line where tag is */
|
||||||
int linelen, /* length of the line where tag is */
|
ptrdiff_t linelen, /* length of the line where tag is */
|
||||||
int lno, /* line number */
|
intmax_t lno, /* line number */
|
||||||
long int cno) /* character number */
|
intmax_t cno) /* character number */
|
||||||
{
|
{
|
||||||
bool named = (name != NULL && namelen > 0);
|
bool named = (name != NULL && namelen > 0);
|
||||||
char *nname = NULL;
|
char *nname = NULL;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf (stderr, "%s on %s:%d: %s\n",
|
fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n",
|
||||||
named ? name : "(unnamed)", curfdp->taggedfname, lno, linestart);
|
named ? name : "(unnamed)", curfdp->taggedfname, lno, linestart);
|
||||||
|
|
||||||
if (!CTAGS && named) /* maybe set named to false */
|
if (!CTAGS && named) /* maybe set named to false */
|
||||||
/* Let's try to make an implicit tag name, that is, create an unnamed tag
|
/* Let's try to make an implicit tag name, that is, create an unnamed tag
|
||||||
such that etags.el can guess a name from it. */
|
such that etags.el can guess a name from it. */
|
||||||
{
|
{
|
||||||
int i;
|
ptrdiff_t i;
|
||||||
register const char *cp = name;
|
const char *cp = name;
|
||||||
|
|
||||||
for (i = 0; i < namelen; i++)
|
for (i = 0; i < namelen; i++)
|
||||||
if (notinname (*cp++))
|
if (notinname (*cp++))
|
||||||
|
|
@ -1963,8 +1975,8 @@ make_tag (const char *name, /* tag name, or NULL if unnamed */
|
||||||
|
|
||||||
/* Record a tag. */
|
/* Record a tag. */
|
||||||
static void
|
static void
|
||||||
pfnote (char *name, bool is_func, char *linestart, int linelen, int lno,
|
pfnote (char *name, bool is_func, char *linestart, ptrdiff_t linelen,
|
||||||
long int cno)
|
intmax_t lno, intmax_t cno)
|
||||||
/* tag name, or NULL if unnamed */
|
/* tag name, or NULL if unnamed */
|
||||||
/* tag is a function */
|
/* tag is a function */
|
||||||
/* start of the line where tag is */
|
/* start of the line where tag is */
|
||||||
|
|
@ -2197,7 +2209,8 @@ add_node (node *np, node **cur_node_p)
|
||||||
if (!no_warnings)
|
if (!no_warnings)
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Duplicate entry in file %s, line %d: %s\n",
|
("Duplicate entry in file %s, "
|
||||||
|
"line %"PRIdMAX": %s\n"),
|
||||||
np->fdp->infname, lineno, np->name);
|
np->fdp->infname, lineno, np->name);
|
||||||
fprintf (stderr, "Second entry ignored\n");
|
fprintf (stderr, "Second entry ignored\n");
|
||||||
}
|
}
|
||||||
|
|
@ -2293,12 +2306,12 @@ invalidate_nodes (fdesc *badfdp, node **npp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int total_size_of_entries (node *);
|
static ptrdiff_t total_size_of_entries (node *);
|
||||||
static int number_len (long) ATTRIBUTE_CONST;
|
static int number_len (intmax_t) ATTRIBUTE_CONST;
|
||||||
|
|
||||||
/* Length of a non-negative number's decimal representation. */
|
/* Length of a non-negative number's decimal representation. */
|
||||||
static int
|
static int
|
||||||
number_len (long int num)
|
number_len (intmax_t num)
|
||||||
{
|
{
|
||||||
int len = 1;
|
int len = 1;
|
||||||
while ((num /= 10) > 0)
|
while ((num /= 10) > 0)
|
||||||
|
|
@ -2312,10 +2325,10 @@ number_len (long int num)
|
||||||
* This count is irrelevant with etags.el since emacs 19.34 at least,
|
* This count is irrelevant with etags.el since emacs 19.34 at least,
|
||||||
* but is still supplied for backward compatibility.
|
* but is still supplied for backward compatibility.
|
||||||
*/
|
*/
|
||||||
static int
|
static ptrdiff_t
|
||||||
total_size_of_entries (register node *np)
|
total_size_of_entries (node *np)
|
||||||
{
|
{
|
||||||
register int total = 0;
|
ptrdiff_t total = 0;
|
||||||
|
|
||||||
for (; np != NULL; np = np->right)
|
for (; np != NULL; np = np->right)
|
||||||
if (np->valid)
|
if (np->valid)
|
||||||
|
|
@ -2323,7 +2336,7 @@ total_size_of_entries (register node *np)
|
||||||
total += strlen (np->regex) + 1; /* pat\177 */
|
total += strlen (np->regex) + 1; /* pat\177 */
|
||||||
if (np->name != NULL)
|
if (np->name != NULL)
|
||||||
total += strlen (np->name) + 1; /* name\001 */
|
total += strlen (np->name) + 1; /* name\001 */
|
||||||
total += number_len ((long) np->lno) + 1; /* lno, */
|
total += number_len (np->lno) + 1; /* lno, */
|
||||||
if (np->cno != invalidcharno) /* cno */
|
if (np->cno != invalidcharno) /* cno */
|
||||||
total += number_len (np->cno);
|
total += number_len (np->cno);
|
||||||
total += 1; /* newline */
|
total += 1; /* newline */
|
||||||
|
|
@ -2347,7 +2360,7 @@ put_entry (node *np)
|
||||||
if (fdp != np->fdp)
|
if (fdp != np->fdp)
|
||||||
{
|
{
|
||||||
fdp = np->fdp;
|
fdp = np->fdp;
|
||||||
fprintf (tagf, "\f\n%s,%d\n",
|
fprintf (tagf, "\f\n%s,%"PRIdPTR"\n",
|
||||||
fdp->taggedfname, total_size_of_entries (np));
|
fdp->taggedfname, total_size_of_entries (np));
|
||||||
fdp->written = true;
|
fdp->written = true;
|
||||||
}
|
}
|
||||||
|
|
@ -2358,9 +2371,9 @@ put_entry (node *np)
|
||||||
fputs (np->name, tagf);
|
fputs (np->name, tagf);
|
||||||
fputc ('\001', tagf);
|
fputc ('\001', tagf);
|
||||||
}
|
}
|
||||||
fprintf (tagf, "%d,", np->lno);
|
fprintf (tagf, "%"PRIdMAX",", np->lno);
|
||||||
if (np->cno != invalidcharno)
|
if (np->cno != invalidcharno)
|
||||||
fprintf (tagf, "%ld", np->cno);
|
fprintf (tagf, "%"PRIdMAX, np->cno);
|
||||||
fputs ("\n", tagf);
|
fputs ("\n", tagf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2372,10 +2385,10 @@ put_entry (node *np)
|
||||||
if (cxref_style)
|
if (cxref_style)
|
||||||
{
|
{
|
||||||
if (vgrind_style)
|
if (vgrind_style)
|
||||||
fprintf (stdout, "%s %s %d\n",
|
fprintf (stdout, "%s %s %"PRIdMAX"\n",
|
||||||
np->name, np->fdp->taggedfname, (np->lno + 63) / 64);
|
np->name, np->fdp->taggedfname, (np->lno + 63) / 64);
|
||||||
else
|
else
|
||||||
fprintf (stdout, "%-16s %3d %-16s %s\n",
|
fprintf (stdout, "%-16s %3"PRIdMAX" %-16s %s\n",
|
||||||
np->name, np->lno, np->fdp->taggedfname, np->regex);
|
np->name, np->lno, np->fdp->taggedfname, np->regex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2397,7 +2410,7 @@ put_entry (node *np)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* anything else; text pattern inadequate */
|
{ /* anything else; text pattern inadequate */
|
||||||
fprintf (tagf, "%d", np->lno);
|
fprintf (tagf, "%"PRIdMAX, np->lno);
|
||||||
}
|
}
|
||||||
putc ('\n', tagf);
|
putc ('\n', tagf);
|
||||||
}
|
}
|
||||||
|
|
@ -2591,7 +2604,7 @@ hash (const char *str, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct C_stab_entry *
|
static struct C_stab_entry *
|
||||||
in_word_set (register const char *str, register unsigned int len)
|
in_word_set (const char *str, ptrdiff_t len)
|
||||||
{
|
{
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
@ -2658,9 +2671,9 @@ in_word_set (register const char *str, register unsigned int len)
|
||||||
/*%>*/
|
/*%>*/
|
||||||
|
|
||||||
static enum sym_type
|
static enum sym_type
|
||||||
C_symtype (char *str, int len, int c_ext)
|
C_symtype (char *str, ptrdiff_t len, int c_ext)
|
||||||
{
|
{
|
||||||
register struct C_stab_entry *se = in_word_set (str, len);
|
struct C_stab_entry *se = in_word_set (str, len);
|
||||||
|
|
||||||
if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
|
if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
|
||||||
return st_none;
|
return st_none;
|
||||||
|
|
@ -2770,8 +2783,8 @@ static enum
|
||||||
static struct tok
|
static struct tok
|
||||||
{
|
{
|
||||||
char *line; /* string containing the token */
|
char *line; /* string containing the token */
|
||||||
int offset; /* where the token starts in LINE */
|
ptrdiff_t offset; /* where the token starts in LINE */
|
||||||
int length; /* token length */
|
ptrdiff_t length; /* token length */
|
||||||
/*
|
/*
|
||||||
The previous members can be used to pass strings around for generic
|
The previous members can be used to pass strings around for generic
|
||||||
purposes. The following ones specifically refer to creating tags. In this
|
purposes. The following ones specifically refer to creating tags. In this
|
||||||
|
|
@ -2782,23 +2795,23 @@ static struct tok
|
||||||
invalidated whenever a state machine is
|
invalidated whenever a state machine is
|
||||||
reset prematurely */
|
reset prematurely */
|
||||||
bool named; /* create a named tag */
|
bool named; /* create a named tag */
|
||||||
int lineno; /* source line number of tag */
|
intmax_t lineno; /* source line number of tag */
|
||||||
long linepos; /* source char number of tag */
|
intmax_t linepos; /* source char number of tag */
|
||||||
} token; /* latest token read */
|
} token; /* latest token read */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables and functions for dealing with nested structures.
|
* Variables and functions for dealing with nested structures.
|
||||||
* Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
|
* Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
|
||||||
*/
|
*/
|
||||||
static void pushclass_above (int, char *, int);
|
static void pushclass_above (ptrdiff_t, char *, ptrdiff_t);
|
||||||
static void popclass_above (int);
|
static void popclass_above (ptrdiff_t);
|
||||||
static void write_classname (linebuffer *, const char *qualifier);
|
static void write_classname (linebuffer *, const char *qualifier);
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char **cname; /* nested class names */
|
char **cname; /* nested class names */
|
||||||
int *bracelev; /* nested class brace level */
|
ptrdiff_t *bracelev; /* nested class brace level */
|
||||||
int nl; /* class nesting level (elements used) */
|
ptrdiff_t nl; /* class nesting level (elements used) */
|
||||||
int size; /* length of the array */
|
ptrdiff_t size; /* length of the array */
|
||||||
} cstack; /* stack for nested declaration tags */
|
} cstack; /* stack for nested declaration tags */
|
||||||
/* Current struct nesting depth (namespace, class, struct, union, enum). */
|
/* Current struct nesting depth (namespace, class, struct, union, enum). */
|
||||||
#define nestlev (cstack.nl)
|
#define nestlev (cstack.nl)
|
||||||
|
|
@ -2807,17 +2820,17 @@ static struct {
|
||||||
&& bracelev == cstack.bracelev[nestlev-1] + 1)
|
&& bracelev == cstack.bracelev[nestlev-1] + 1)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pushclass_above (int bracelev, char *str, int len)
|
pushclass_above (ptrdiff_t bracelev, char *str, ptrdiff_t len)
|
||||||
{
|
{
|
||||||
int nl;
|
ptrdiff_t nl;
|
||||||
|
|
||||||
popclass_above (bracelev);
|
popclass_above (bracelev);
|
||||||
nl = cstack.nl;
|
nl = cstack.nl;
|
||||||
if (nl >= cstack.size)
|
if (nl >= cstack.size)
|
||||||
{
|
{
|
||||||
int size = cstack.size *= 2;
|
xrnew (cstack.cname, cstack.size, 2);
|
||||||
xrnew (cstack.cname, size, char *);
|
xrnew (cstack.bracelev, cstack.size, 2);
|
||||||
xrnew (cstack.bracelev, size, int);
|
cstack.size *= 2;
|
||||||
}
|
}
|
||||||
assert (nl == 0 || cstack.bracelev[nl-1] < bracelev);
|
assert (nl == 0 || cstack.bracelev[nl-1] < bracelev);
|
||||||
cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
|
cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
|
||||||
|
|
@ -2826,11 +2839,9 @@ pushclass_above (int bracelev, char *str, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
popclass_above (int bracelev)
|
popclass_above (ptrdiff_t bracelev)
|
||||||
{
|
{
|
||||||
int nl;
|
for (ptrdiff_t nl = cstack.nl - 1;
|
||||||
|
|
||||||
for (nl = cstack.nl - 1;
|
|
||||||
nl >= 0 && cstack.bracelev[nl] >= bracelev;
|
nl >= 0 && cstack.bracelev[nl] >= bracelev;
|
||||||
nl--)
|
nl--)
|
||||||
{
|
{
|
||||||
|
|
@ -2842,8 +2853,7 @@ popclass_above (int bracelev)
|
||||||
static void
|
static void
|
||||||
write_classname (linebuffer *cn, const char *qualifier)
|
write_classname (linebuffer *cn, const char *qualifier)
|
||||||
{
|
{
|
||||||
int i, len;
|
ptrdiff_t len;
|
||||||
int qlen = strlen (qualifier);
|
|
||||||
|
|
||||||
if (cstack.nl == 0 || cstack.cname[0] == NULL)
|
if (cstack.nl == 0 || cstack.cname[0] == NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -2857,18 +2867,22 @@ write_classname (linebuffer *cn, const char *qualifier)
|
||||||
linebuffer_setlen (cn, len);
|
linebuffer_setlen (cn, len);
|
||||||
strcpy (cn->buffer, cstack.cname[0]);
|
strcpy (cn->buffer, cstack.cname[0]);
|
||||||
}
|
}
|
||||||
for (i = 1; i < cstack.nl; i++)
|
for (ptrdiff_t i = 1; i < cstack.nl; i++)
|
||||||
{
|
{
|
||||||
char *s = cstack.cname[i];
|
char *s = cstack.cname[i];
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
continue;
|
continue;
|
||||||
linebuffer_setlen (cn, len + qlen + strlen (s));
|
int qlen = strlen (qualifier);
|
||||||
len += sprintf (cn->buffer + len, "%s%s", qualifier, s);
|
ptrdiff_t slen = strlen (s);
|
||||||
|
linebuffer_setlen (cn, len + qlen + slen);
|
||||||
|
memcpyz (stpcpy (cn->buffer + len, qualifier), s, slen);
|
||||||
|
len += qlen + slen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool consider_token (char *, int, int, int *, int, int, bool *);
|
static bool consider_token (char *, ptrdiff_t, int, int *,
|
||||||
|
ptrdiff_t, ptrdiff_t, bool *);
|
||||||
static void make_C_tag (bool);
|
static void make_C_tag (bool);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2889,8 +2903,8 @@ static void make_C_tag (bool);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
consider_token (char *str, int len, int c, int *c_extp,
|
consider_token (char *str, ptrdiff_t len, int c, int *c_extp,
|
||||||
int bracelev, int parlev, bool *is_func_or_var)
|
ptrdiff_t bracelev, ptrdiff_t parlev, bool *is_func_or_var)
|
||||||
/* IN: token pointer */
|
/* IN: token pointer */
|
||||||
/* IN: token length */
|
/* IN: token length */
|
||||||
/* IN: first char after the token */
|
/* IN: first char after the token */
|
||||||
|
|
@ -2903,7 +2917,7 @@ consider_token (char *str, int len, int c, int *c_extp,
|
||||||
structtype is the type of the preceding struct-like keyword, and
|
structtype is the type of the preceding struct-like keyword, and
|
||||||
structbracelev is the brace level where it has been seen. */
|
structbracelev is the brace level where it has been seen. */
|
||||||
static enum sym_type structtype;
|
static enum sym_type structtype;
|
||||||
static int structbracelev;
|
static ptrdiff_t structbracelev;
|
||||||
static enum sym_type toktype;
|
static enum sym_type toktype;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3098,8 +3112,7 @@ consider_token (char *str, int len, int c, int *c_extp,
|
||||||
fvdef = fvnone;
|
fvdef = fvnone;
|
||||||
objdef = omethodtag;
|
objdef = omethodtag;
|
||||||
linebuffer_setlen (&token_name, len);
|
linebuffer_setlen (&token_name, len);
|
||||||
memcpy (token_name.buffer, str, len);
|
memcpyz (token_name.buffer, str, len);
|
||||||
token_name.buffer[len] = '\0';
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -3113,11 +3126,10 @@ consider_token (char *str, int len, int c, int *c_extp,
|
||||||
objdef = omethodtag;
|
objdef = omethodtag;
|
||||||
if (class_qualify)
|
if (class_qualify)
|
||||||
{
|
{
|
||||||
int oldlen = token_name.len;
|
ptrdiff_t oldlen = token_name.len;
|
||||||
fvdef = fvnone;
|
fvdef = fvnone;
|
||||||
linebuffer_setlen (&token_name, oldlen + len);
|
linebuffer_setlen (&token_name, oldlen + len);
|
||||||
memcpy (token_name.buffer + oldlen, str, len);
|
memcpyz (token_name.buffer + oldlen, str, len);
|
||||||
token_name.buffer[oldlen + len] = '\0';
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -3228,7 +3240,7 @@ consider_token (char *str, int len, int c, int *c_extp,
|
||||||
*/
|
*/
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
long linepos;
|
intmax_t linepos;
|
||||||
linebuffer lb;
|
linebuffer lb;
|
||||||
} lbs[2];
|
} lbs[2];
|
||||||
|
|
||||||
|
|
@ -3302,19 +3314,19 @@ C_entries (int c_ext, FILE *inf)
|
||||||
/* extension of C */
|
/* extension of C */
|
||||||
/* input file */
|
/* input file */
|
||||||
{
|
{
|
||||||
register char c; /* latest char read; '\0' for end of line */
|
char c; /* latest char read; '\0' for end of line */
|
||||||
register char *lp; /* pointer one beyond the character `c' */
|
char *lp; /* pointer one beyond the character `c' */
|
||||||
int curndx, newndx; /* indices for current and new lb */
|
bool curndx, newndx; /* indices for current and new lb */
|
||||||
register int tokoff; /* offset in line of start of current token */
|
ptrdiff_t tokoff; /* offset in line of start of current token */
|
||||||
register int toklen; /* length of current token */
|
ptrdiff_t toklen; /* length of current token */
|
||||||
const char *qualifier; /* string used to qualify names */
|
const char *qualifier; /* string used to qualify names */
|
||||||
int qlen; /* length of qualifier */
|
int qlen; /* length of qualifier */
|
||||||
int bracelev; /* current brace level */
|
ptrdiff_t bracelev; /* current brace level */
|
||||||
int bracketlev; /* current bracket level */
|
ptrdiff_t bracketlev; /* current bracket level */
|
||||||
int parlev; /* current parenthesis level */
|
ptrdiff_t parlev; /* current parenthesis level */
|
||||||
int attrparlev; /* __attribute__ parenthesis level */
|
ptrdiff_t attrparlev; /* __attribute__ parenthesis level */
|
||||||
int templatelev; /* current template level */
|
ptrdiff_t templatelev; /* current template level */
|
||||||
int typdefbracelev; /* bracelev where a typedef struct body begun */
|
ptrdiff_t typdefbracelev; /* bracelev where a typedef struct body begun */
|
||||||
bool incomm, inquote, inchar, quotednl, midtoken;
|
bool incomm, inquote, inchar, quotednl, midtoken;
|
||||||
bool yacc_rules; /* in the rules part of a yacc file */
|
bool yacc_rules; /* in the rules part of a yacc file */
|
||||||
struct tok savetoken = {0}; /* token saved during preprocessor handling */
|
struct tok savetoken = {0}; /* token saved during preprocessor handling */
|
||||||
|
|
@ -3327,7 +3339,7 @@ C_entries (int c_ext, FILE *inf)
|
||||||
cstack.size = (DEBUG) ? 1 : 4;
|
cstack.size = (DEBUG) ? 1 : 4;
|
||||||
cstack.nl = 0;
|
cstack.nl = 0;
|
||||||
cstack.cname = xnew (cstack.size, char *);
|
cstack.cname = xnew (cstack.size, char *);
|
||||||
cstack.bracelev = xnew (cstack.size, int);
|
cstack.bracelev = xnew (cstack.size, ptrdiff_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokoff = toklen = typdefbracelev = 0; /* keep compiler quiet */
|
tokoff = toklen = typdefbracelev = 0; /* keep compiler quiet */
|
||||||
|
|
@ -3579,20 +3591,19 @@ C_entries (int c_ext, FILE *inf)
|
||||||
{
|
{
|
||||||
if (class_qualify)
|
if (class_qualify)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
write_classname (&token_name, qualifier);
|
write_classname (&token_name, qualifier);
|
||||||
len = token_name.len;
|
ptrdiff_t len = token_name.len;
|
||||||
linebuffer_setlen (&token_name,
|
linebuffer_setlen (&token_name,
|
||||||
len + qlen + toklen);
|
len + qlen + toklen);
|
||||||
sprintf (token_name.buffer + len, "%s%.*s",
|
memcpyz (stpcpy (token_name.buffer + len,
|
||||||
qualifier, toklen,
|
qualifier),
|
||||||
newlb.buffer + tokoff);
|
newlb.buffer + tokoff, toklen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linebuffer_setlen (&token_name, toklen);
|
linebuffer_setlen (&token_name, toklen);
|
||||||
sprintf (token_name.buffer, "%.*s",
|
memcpyz (token_name.buffer,
|
||||||
toklen, newlb.buffer + tokoff);
|
newlb.buffer + tokoff, toklen);
|
||||||
}
|
}
|
||||||
token.named = true;
|
token.named = true;
|
||||||
}
|
}
|
||||||
|
|
@ -3601,17 +3612,19 @@ C_entries (int c_ext, FILE *inf)
|
||||||
{
|
{
|
||||||
if (class_qualify)
|
if (class_qualify)
|
||||||
{
|
{
|
||||||
int len = strlen (objtag) + 2 + toklen;
|
ptrdiff_t len = strlen (objtag) + 2 + toklen;
|
||||||
linebuffer_setlen (&token_name, len);
|
linebuffer_setlen (&token_name, len);
|
||||||
sprintf (token_name.buffer, "%s(%.*s)",
|
char *p1 = stpcpy (token_name.buffer, objtag);
|
||||||
objtag, toklen,
|
char *p2 = stpcpy (p1, "(");
|
||||||
newlb.buffer + tokoff);
|
char *p3 = mempcpy (p2, newlb.buffer + tokoff,
|
||||||
|
toklen);
|
||||||
|
strcpy (p3, ")");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linebuffer_setlen (&token_name, toklen);
|
linebuffer_setlen (&token_name, toklen);
|
||||||
sprintf (token_name.buffer, "%.*s",
|
memcpyz (token_name.buffer,
|
||||||
toklen, newlb.buffer + tokoff);
|
newlb.buffer + tokoff, toklen);
|
||||||
}
|
}
|
||||||
token.named = true;
|
token.named = true;
|
||||||
}
|
}
|
||||||
|
|
@ -3625,8 +3638,8 @@ C_entries (int c_ext, FILE *inf)
|
||||||
/* GNU DEFUN and similar macros */
|
/* GNU DEFUN and similar macros */
|
||||||
{
|
{
|
||||||
bool defun = (newlb.buffer[tokoff] == 'F');
|
bool defun = (newlb.buffer[tokoff] == 'F');
|
||||||
int off = tokoff;
|
ptrdiff_t off = tokoff;
|
||||||
int len = toklen;
|
ptrdiff_t len = toklen;
|
||||||
|
|
||||||
if (defun)
|
if (defun)
|
||||||
{
|
{
|
||||||
|
|
@ -3635,9 +3648,8 @@ C_entries (int c_ext, FILE *inf)
|
||||||
|
|
||||||
/* First, tag it as its C name */
|
/* First, tag it as its C name */
|
||||||
linebuffer_setlen (&token_name, toklen);
|
linebuffer_setlen (&token_name, toklen);
|
||||||
memcpy (token_name.buffer,
|
memcpyz (token_name.buffer,
|
||||||
newlb.buffer + tokoff, toklen);
|
newlb.buffer + tokoff, toklen);
|
||||||
token_name.buffer[toklen] = '\0';
|
|
||||||
token.named = true;
|
token.named = true;
|
||||||
token.lineno = lineno;
|
token.lineno = lineno;
|
||||||
token.offset = tokoff;
|
token.offset = tokoff;
|
||||||
|
|
@ -3650,9 +3662,8 @@ C_entries (int c_ext, FILE *inf)
|
||||||
/* Rewrite the tag so that emacs lisp DEFUNs
|
/* Rewrite the tag so that emacs lisp DEFUNs
|
||||||
can be found also by their elisp name */
|
can be found also by their elisp name */
|
||||||
linebuffer_setlen (&token_name, len);
|
linebuffer_setlen (&token_name, len);
|
||||||
memcpy (token_name.buffer,
|
memcpyz (token_name.buffer,
|
||||||
newlb.buffer + off, len);
|
newlb.buffer + off, len);
|
||||||
token_name.buffer[len] = '\0';
|
|
||||||
if (defun)
|
if (defun)
|
||||||
while (--len >= 0)
|
while (--len >= 0)
|
||||||
if (token_name.buffer[len] == '_')
|
if (token_name.buffer[len] == '_')
|
||||||
|
|
@ -3662,9 +3673,8 @@ C_entries (int c_ext, FILE *inf)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linebuffer_setlen (&token_name, toklen);
|
linebuffer_setlen (&token_name, toklen);
|
||||||
memcpy (token_name.buffer,
|
memcpyz (token_name.buffer,
|
||||||
newlb.buffer + tokoff, toklen);
|
newlb.buffer + tokoff, toklen);
|
||||||
token_name.buffer[toklen] = '\0';
|
|
||||||
/* Name macros and members. */
|
/* Name macros and members. */
|
||||||
token.named = (structdef == stagseen
|
token.named = (structdef == stagseen
|
||||||
|| typdef == ttypeseen
|
|| typdef == ttypeseen
|
||||||
|
|
@ -3790,7 +3800,7 @@ C_entries (int c_ext, FILE *inf)
|
||||||
objdef = omethodcolon;
|
objdef = omethodcolon;
|
||||||
if (class_qualify)
|
if (class_qualify)
|
||||||
{
|
{
|
||||||
int toklen = token_name.len;
|
ptrdiff_t toklen = token_name.len;
|
||||||
linebuffer_setlen (&token_name, toklen + 1);
|
linebuffer_setlen (&token_name, toklen + 1);
|
||||||
strcpy (token_name.buffer + toklen, ":");
|
strcpy (token_name.buffer + toklen, ":");
|
||||||
}
|
}
|
||||||
|
|
@ -4061,7 +4071,7 @@ C_entries (int c_ext, FILE *inf)
|
||||||
}
|
}
|
||||||
if (uqname > token_name.buffer)
|
if (uqname > token_name.buffer)
|
||||||
{
|
{
|
||||||
int uqlen = strlen (uqname);
|
ptrdiff_t uqlen = strlen (uqname);
|
||||||
linebuffer_setlen (&token_name, uqlen);
|
linebuffer_setlen (&token_name, uqlen);
|
||||||
memmove (token_name.buffer, uqname, uqlen + 1);
|
memmove (token_name.buffer, uqname, uqlen + 1);
|
||||||
}
|
}
|
||||||
|
|
@ -4979,12 +4989,11 @@ Ruby_functions (FILE *inf)
|
||||||
size_t name_len = cp - np + 1;
|
size_t name_len = cp - np + 1;
|
||||||
char *wr_name = xnew (name_len + 1, char);
|
char *wr_name = xnew (name_len + 1, char);
|
||||||
|
|
||||||
memcpy (wr_name, np, name_len - 1);
|
strcpy (mempcpy (wr_name, np, name_len - 1), "=");
|
||||||
memcpy (wr_name + name_len - 1, "=", 2);
|
|
||||||
pfnote (wr_name, true, lb.buffer, cp - lb.buffer + 1,
|
pfnote (wr_name, true, lb.buffer, cp - lb.buffer + 1,
|
||||||
lineno, linecharno);
|
lineno, linecharno);
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf (stderr, "%s on %s:%d: %s\n", wr_name,
|
fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n", wr_name,
|
||||||
curfdp->taggedfname, lineno, lb.buffer);
|
curfdp->taggedfname, lineno, lb.buffer);
|
||||||
continuation = false;
|
continuation = false;
|
||||||
}
|
}
|
||||||
|
|
@ -5178,8 +5187,8 @@ static void
|
||||||
Pascal_functions (FILE *inf)
|
Pascal_functions (FILE *inf)
|
||||||
{
|
{
|
||||||
linebuffer tline; /* mostly copied from C_entries */
|
linebuffer tline; /* mostly copied from C_entries */
|
||||||
long save_lcno;
|
intmax_t save_lcno, save_lineno;
|
||||||
int save_lineno, namelen, taglen;
|
ptrdiff_t namelen, taglen;
|
||||||
char c, *name;
|
char c, *name;
|
||||||
|
|
||||||
bool /* each of these flags is true if: */
|
bool /* each of these flags is true if: */
|
||||||
|
|
@ -5455,7 +5464,7 @@ Lua_functions (FILE *inf)
|
||||||
if (tp_dot || tp_colon)
|
if (tp_dot || tp_colon)
|
||||||
{
|
{
|
||||||
char *p = tp_dot > tp_colon ? tp_dot : tp_colon;
|
char *p = tp_dot > tp_colon ? tp_dot : tp_colon;
|
||||||
int len_add = p - tag_name + 1;
|
ptrdiff_t len_add = p - tag_name + 1;
|
||||||
|
|
||||||
get_tag (bp + len_add, NULL);
|
get_tag (bp + len_add, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -5656,7 +5665,7 @@ TeX_commands (FILE *inf)
|
||||||
if (strneq (cp, key->buffer, key->len))
|
if (strneq (cp, key->buffer, key->len))
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int namelen, linelen;
|
ptrdiff_t namelen, linelen;
|
||||||
bool opgrp = false;
|
bool opgrp = false;
|
||||||
|
|
||||||
cp = skip_spaces (cp + key->len);
|
cp = skip_spaces (cp + key->len);
|
||||||
|
|
@ -5693,8 +5702,8 @@ TeX_commands (FILE *inf)
|
||||||
static void
|
static void
|
||||||
TEX_decode_env (const char *evarname, const char *defenv)
|
TEX_decode_env (const char *evarname, const char *defenv)
|
||||||
{
|
{
|
||||||
register const char *env, *p;
|
const char *env, *p;
|
||||||
int i, len;
|
ptrdiff_t len;
|
||||||
|
|
||||||
/* Append default string to environment. */
|
/* Append default string to environment. */
|
||||||
env = getenv (evarname);
|
env = getenv (evarname);
|
||||||
|
|
@ -5711,7 +5720,7 @@ TEX_decode_env (const char *evarname, const char *defenv)
|
||||||
|
|
||||||
/* Unpack environment string into token table. Be careful about */
|
/* Unpack environment string into token table. Be careful about */
|
||||||
/* zero-length strings (leading ':', "::" and trailing ':') */
|
/* zero-length strings (leading ':', "::" and trailing ':') */
|
||||||
for (i = 0; *env != '\0';)
|
for (ptrdiff_t i = 0; *env != '\0'; )
|
||||||
{
|
{
|
||||||
p = strchr (env, ':');
|
p = strchr (env, ':');
|
||||||
if (!p) /* End of environment string. */
|
if (!p) /* End of environment string. */
|
||||||
|
|
@ -5811,8 +5820,7 @@ HTML_labels (FILE *inf)
|
||||||
for (end = dbp; *end != '\0' && intoken (*end); end++)
|
for (end = dbp; *end != '\0' && intoken (*end); end++)
|
||||||
continue;
|
continue;
|
||||||
linebuffer_setlen (&token_name, end - dbp);
|
linebuffer_setlen (&token_name, end - dbp);
|
||||||
memcpy (token_name.buffer, dbp, end - dbp);
|
memcpyz (token_name.buffer, dbp, end - dbp);
|
||||||
token_name.buffer[end - dbp] = '\0';
|
|
||||||
|
|
||||||
dbp = end;
|
dbp = end;
|
||||||
intag = false; /* we found what we looked for */
|
intag = false; /* we found what we looked for */
|
||||||
|
|
@ -5906,11 +5914,10 @@ Prolog_functions (FILE *inf)
|
||||||
tags later. */
|
tags later. */
|
||||||
if (allocated <= len)
|
if (allocated <= len)
|
||||||
{
|
{
|
||||||
xrnew (last, len + 1, char);
|
xrnew (last, len + 1, 1);
|
||||||
allocated = len + 1;
|
allocated = len + 1;
|
||||||
}
|
}
|
||||||
memcpy (last, cp, len);
|
memcpyz (last, cp, len);
|
||||||
last[len] = '\0';
|
|
||||||
lastlen = len;
|
lastlen = len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6031,9 +6038,9 @@ prolog_atom (char *s, size_t pos)
|
||||||
* Assumes that Erlang functions start at column 0.
|
* Assumes that Erlang functions start at column 0.
|
||||||
* Original code by Anders Lindgren (1996)
|
* Original code by Anders Lindgren (1996)
|
||||||
*/
|
*/
|
||||||
static int erlang_func (char *, char *, ptrdiff_t, ptrdiff_t *);
|
static ptrdiff_t erlang_func (char *, char *, ptrdiff_t, ptrdiff_t *);
|
||||||
static void erlang_attribute (char *);
|
static void erlang_attribute (char *);
|
||||||
static int erlang_atom (char *);
|
static ptrdiff_t erlang_atom (char *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Erlang_functions (FILE *inf)
|
Erlang_functions (FILE *inf)
|
||||||
|
|
@ -6070,11 +6077,10 @@ Erlang_functions (FILE *inf)
|
||||||
tags later. */
|
tags later. */
|
||||||
if (allocated <= len)
|
if (allocated <= len)
|
||||||
{
|
{
|
||||||
xrnew (last, len + 1, char);
|
xrnew (last, len + 1, 1);
|
||||||
allocated = len + 1;
|
allocated = len + 1;
|
||||||
}
|
}
|
||||||
memcpy (last, cp + name_offset, len);
|
memcpyz (last, cp + name_offset, len);
|
||||||
last[len] = '\0';
|
|
||||||
lastlen = len;
|
lastlen = len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6093,7 +6099,7 @@ Erlang_functions (FILE *inf)
|
||||||
* Return the size of the name of the function, or 0 if no function
|
* Return the size of the name of the function, or 0 if no function
|
||||||
* was found.
|
* was found.
|
||||||
*/
|
*/
|
||||||
static int
|
static ptrdiff_t
|
||||||
erlang_func (char *s, char *last, ptrdiff_t lastlen, ptrdiff_t *name_offset)
|
erlang_func (char *s, char *last, ptrdiff_t lastlen, ptrdiff_t *name_offset)
|
||||||
{
|
{
|
||||||
char *name = s;
|
char *name = s;
|
||||||
|
|
@ -6133,15 +6139,13 @@ static void
|
||||||
erlang_attribute (char *s)
|
erlang_attribute (char *s)
|
||||||
{
|
{
|
||||||
char *cp = s;
|
char *cp = s;
|
||||||
int pos;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record"))
|
if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record"))
|
||||||
&& *cp++ == '(')
|
&& *cp++ == '(')
|
||||||
{
|
{
|
||||||
cp = skip_spaces (cp);
|
cp = skip_spaces (cp);
|
||||||
len = erlang_atom (cp);
|
ptrdiff_t len = erlang_atom (cp);
|
||||||
pos = cp + len - s;
|
ptrdiff_t pos = cp + len - s;
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
/* If the name is quoted, the quotes are not part of the name. */
|
/* If the name is quoted, the quotes are not part of the name. */
|
||||||
|
|
@ -6161,10 +6165,10 @@ erlang_attribute (char *s)
|
||||||
* Consume an Erlang atom (or variable).
|
* Consume an Erlang atom (or variable).
|
||||||
* Return the number of bytes consumed, or -1 if there was an error.
|
* Return the number of bytes consumed, or -1 if there was an error.
|
||||||
*/
|
*/
|
||||||
static int
|
static ptrdiff_t
|
||||||
erlang_atom (char *s)
|
erlang_atom (char *s)
|
||||||
{
|
{
|
||||||
int pos = 0;
|
ptrdiff_t pos = 0;
|
||||||
|
|
||||||
if (c_isalpha (s[pos]) || s[pos] == '_')
|
if (c_isalpha (s[pos]) || s[pos] == '_')
|
||||||
{
|
{
|
||||||
|
|
@ -6437,10 +6441,9 @@ static char *
|
||||||
substitute (char *in, char *out, struct re_registers *regs)
|
substitute (char *in, char *out, struct re_registers *regs)
|
||||||
{
|
{
|
||||||
char *result, *t;
|
char *result, *t;
|
||||||
int size, dig, diglen;
|
|
||||||
|
|
||||||
result = NULL;
|
result = NULL;
|
||||||
size = strlen (out);
|
ptrdiff_t size = strlen (out);
|
||||||
|
|
||||||
/* Pass 1: figure out how much to allocate by finding all \N strings. */
|
/* Pass 1: figure out how much to allocate by finding all \N strings. */
|
||||||
if (out[size - 1] == '\\')
|
if (out[size - 1] == '\\')
|
||||||
|
|
@ -6450,8 +6453,8 @@ substitute (char *in, char *out, struct re_registers *regs)
|
||||||
t = strchr (t + 2, '\\'))
|
t = strchr (t + 2, '\\'))
|
||||||
if (c_isdigit (t[1]))
|
if (c_isdigit (t[1]))
|
||||||
{
|
{
|
||||||
dig = t[1] - '0';
|
int dig = t[1] - '0';
|
||||||
diglen = regs->end[dig] - regs->start[dig];
|
ptrdiff_t diglen = regs->end[dig] - regs->start[dig];
|
||||||
size += diglen - 2;
|
size += diglen - 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -6464,8 +6467,8 @@ substitute (char *in, char *out, struct re_registers *regs)
|
||||||
for (t = result; *out != '\0'; out++)
|
for (t = result; *out != '\0'; out++)
|
||||||
if (*out == '\\' && c_isdigit (*++out))
|
if (*out == '\\' && c_isdigit (*++out))
|
||||||
{
|
{
|
||||||
dig = *out - '0';
|
int dig = *out - '0';
|
||||||
diglen = regs->end[dig] - regs->start[dig];
|
ptrdiff_t diglen = regs->end[dig] - regs->start[dig];
|
||||||
memcpy (t, in + regs->start[dig], diglen);
|
memcpy (t, in + regs->start[dig], diglen);
|
||||||
t += diglen;
|
t += diglen;
|
||||||
}
|
}
|
||||||
|
|
@ -6474,7 +6477,7 @@ substitute (char *in, char *out, struct re_registers *regs)
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
|
|
||||||
assert (t <= result + size);
|
assert (t <= result + size);
|
||||||
assert (t - result == (int)strlen (result));
|
assert (t == result + strlen (result));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -6511,7 +6514,7 @@ regex_tag_multiline (void)
|
||||||
|
|
||||||
for (rp = p_head; rp != NULL; rp = rp->p_next)
|
for (rp = p_head; rp != NULL; rp = rp->p_next)
|
||||||
{
|
{
|
||||||
int match = 0;
|
ptrdiff_t match = 0;
|
||||||
|
|
||||||
if (!rp->multi_line)
|
if (!rp->multi_line)
|
||||||
continue; /* skip normal regexps */
|
continue; /* skip normal regexps */
|
||||||
|
|
@ -6572,7 +6575,7 @@ regex_tag_multiline (void)
|
||||||
charno - linecharno + 1, lineno, linecharno);
|
charno - linecharno + 1, lineno, linecharno);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf (stderr, "%s on %s:%d: %s\n",
|
fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n",
|
||||||
name ? name : "(unnamed)", curfdp->taggedfname,
|
name ? name : "(unnamed)", curfdp->taggedfname,
|
||||||
lineno, buffer + linecharno);
|
lineno, buffer + linecharno);
|
||||||
}
|
}
|
||||||
|
|
@ -6589,7 +6592,7 @@ regex_tag_multiline (void)
|
||||||
static bool
|
static bool
|
||||||
nocase_tail (const char *cp)
|
nocase_tail (const char *cp)
|
||||||
{
|
{
|
||||||
int len = 0;
|
ptrdiff_t len = 0;
|
||||||
|
|
||||||
while (*cp != '\0' && c_tolower (*cp) == c_tolower (dbp[len]))
|
while (*cp != '\0' && c_tolower (*cp) == c_tolower (dbp[len]))
|
||||||
cp++, len++;
|
cp++, len++;
|
||||||
|
|
@ -6648,7 +6651,7 @@ get_lispy_tag (register char *bp)
|
||||||
* If multi-line regular expressions are requested, each line read is
|
* If multi-line regular expressions are requested, each line read is
|
||||||
* appended to `filebuf'.
|
* appended to `filebuf'.
|
||||||
*/
|
*/
|
||||||
static long
|
static ptrdiff_t
|
||||||
readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
||||||
{
|
{
|
||||||
char *buffer = lbp->buffer;
|
char *buffer = lbp->buffer;
|
||||||
|
|
@ -6664,8 +6667,8 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
||||||
if (p == pend)
|
if (p == pend)
|
||||||
{
|
{
|
||||||
/* We're at the end of linebuffer: expand it. */
|
/* We're at the end of linebuffer: expand it. */
|
||||||
|
xrnew (buffer, lbp->size, 2);
|
||||||
lbp->size *= 2;
|
lbp->size *= 2;
|
||||||
xrnew (buffer, lbp->size, char);
|
|
||||||
p += buffer - lbp->buffer;
|
p += buffer - lbp->buffer;
|
||||||
pend = buffer + lbp->size;
|
pend = buffer + lbp->size;
|
||||||
lbp->buffer = buffer;
|
lbp->buffer = buffer;
|
||||||
|
|
@ -6702,13 +6705,12 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
||||||
while (filebuf.size <= filebuf.len + lbp->len + 1) /* +1 for \n */
|
while (filebuf.size <= filebuf.len + lbp->len + 1) /* +1 for \n */
|
||||||
{
|
{
|
||||||
/* Expand filebuf. */
|
/* Expand filebuf. */
|
||||||
|
xrnew (filebuf.buffer, filebuf.size, 2);
|
||||||
filebuf.size *= 2;
|
filebuf.size *= 2;
|
||||||
xrnew (filebuf.buffer, filebuf.size, char);
|
|
||||||
}
|
}
|
||||||
memcpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len);
|
strcpy (mempcpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len),
|
||||||
filebuf.len += lbp->len;
|
"\n");
|
||||||
filebuf.buffer[filebuf.len++] = '\n';
|
filebuf.len += lbp->len + 1;
|
||||||
filebuf.buffer[filebuf.len] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lbp->len + chars_deleted;
|
return lbp->len + chars_deleted;
|
||||||
|
|
@ -6722,10 +6724,8 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
||||||
static void
|
static void
|
||||||
readline (linebuffer *lbp, FILE *stream)
|
readline (linebuffer *lbp, FILE *stream)
|
||||||
{
|
{
|
||||||
long result;
|
|
||||||
|
|
||||||
linecharno = charno; /* update global char number of line start */
|
linecharno = charno; /* update global char number of line start */
|
||||||
result = readline_internal (lbp, stream, infilename); /* read line */
|
ptrdiff_t result = readline_internal (lbp, stream, infilename);
|
||||||
lineno += 1; /* increment global line number */
|
lineno += 1; /* increment global line number */
|
||||||
charno += result; /* increment global char number */
|
charno += result; /* increment global char number */
|
||||||
|
|
||||||
|
|
@ -6737,10 +6737,10 @@ readline (linebuffer *lbp, FILE *stream)
|
||||||
/* Check whether this is a #line directive. */
|
/* Check whether this is a #line directive. */
|
||||||
if (result > 12 && strneq (lbp->buffer, "#line ", 6))
|
if (result > 12 && strneq (lbp->buffer, "#line ", 6))
|
||||||
{
|
{
|
||||||
unsigned int lno;
|
intmax_t lno;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
|
||||||
if (sscanf (lbp->buffer, "#line %u \"%n", &lno, &start) >= 1
|
if (sscanf (lbp->buffer, "#line %"SCNdMAX" \"%n", &lno, &start) >= 1
|
||||||
&& start > 0) /* double quote character found */
|
&& start > 0) /* double quote character found */
|
||||||
{
|
{
|
||||||
char *endp = lbp->buffer + start;
|
char *endp = lbp->buffer + start;
|
||||||
|
|
@ -6850,7 +6850,7 @@ readline (linebuffer *lbp, FILE *stream)
|
||||||
} /* if #line directives should be considered */
|
} /* if #line directives should be considered */
|
||||||
|
|
||||||
{
|
{
|
||||||
int match;
|
ptrdiff_t match;
|
||||||
regexp *rp;
|
regexp *rp;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
|
@ -6900,7 +6900,7 @@ readline (linebuffer *lbp, FILE *stream)
|
||||||
/* Force explicit tag name, if a name is there. */
|
/* Force explicit tag name, if a name is there. */
|
||||||
pfnote (name, true, lbp->buffer, match, lineno, linecharno);
|
pfnote (name, true, lbp->buffer, match, lineno, linecharno);
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf (stderr, "%s on %s:%d: %s\n",
|
fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n",
|
||||||
name ? name : "(unnamed)", curfdp->taggedfname,
|
name ? name : "(unnamed)", curfdp->taggedfname,
|
||||||
lineno, lbp->buffer);
|
lineno, lbp->buffer);
|
||||||
}
|
}
|
||||||
|
|
@ -6925,11 +6925,11 @@ savestr (const char *cp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a pointer to a space of size LEN+1 allocated with xnew where
|
* Return a pointer to a space of size LEN+1 allocated with xnew
|
||||||
* the string CP has been copied for at most the first LEN characters.
|
* with a copy of CP (containing LEN bytes) followed by a NUL byte.
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
savenstr (const char *cp, int len)
|
savenstr (const char *cp, ptrdiff_t len)
|
||||||
{
|
{
|
||||||
char *dp = xnew (len + 1, char);
|
char *dp = xnew (len + 1, char);
|
||||||
dp[len] = '\0';
|
dp[len] = '\0';
|
||||||
|
|
@ -7013,13 +7013,9 @@ verror (char const *format, va_list ap)
|
||||||
static char *
|
static char *
|
||||||
concat (const char *s1, const char *s2, const char *s3)
|
concat (const char *s1, const char *s2, const char *s3)
|
||||||
{
|
{
|
||||||
int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
|
ptrdiff_t len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
|
||||||
char *result = xnew (len1 + len2 + len3 + 1, char);
|
char *result = xnew (len1 + len2 + len3 + 1, char);
|
||||||
|
strcpy (stpcpy (stpcpy (result, s1), s2), s3);
|
||||||
strcpy (result, s1);
|
|
||||||
strcpy (result + len1, s2);
|
|
||||||
strcpy (result + len1 + len2, s3);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7029,16 +7025,16 @@ concat (const char *s1, const char *s2, const char *s3)
|
||||||
static char *
|
static char *
|
||||||
etags_getcwd (void)
|
etags_getcwd (void)
|
||||||
{
|
{
|
||||||
int bufsize = 200;
|
ptrdiff_t bufsize = 200;
|
||||||
char *path = xnew (bufsize, char);
|
char *path = xnew (bufsize, char);
|
||||||
|
|
||||||
while (getcwd (path, bufsize) == NULL)
|
while (getcwd (path, bufsize) == NULL)
|
||||||
{
|
{
|
||||||
if (errno != ERANGE)
|
if (errno != ERANGE)
|
||||||
pfatal ("getcwd");
|
pfatal ("getcwd");
|
||||||
bufsize *= 2;
|
|
||||||
free (path);
|
free (path);
|
||||||
path = xnew (bufsize, char);
|
path = xnmalloc (bufsize, 2 * sizeof *path);
|
||||||
|
bufsize *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
canonicalize_filename (path);
|
canonicalize_filename (path);
|
||||||
|
|
@ -7099,7 +7095,7 @@ static char *
|
||||||
relative_filename (char *file, char *dir)
|
relative_filename (char *file, char *dir)
|
||||||
{
|
{
|
||||||
char *fp, *dp, *afn, *res;
|
char *fp, *dp, *afn, *res;
|
||||||
int i;
|
ptrdiff_t i;
|
||||||
|
|
||||||
/* Find the common root of file and dir (with a trailing slash). */
|
/* Find the common root of file and dir (with a trailing slash). */
|
||||||
afn = absolute_filename (file, cwd);
|
afn = absolute_filename (file, cwd);
|
||||||
|
|
@ -7282,32 +7278,54 @@ linebuffer_init (linebuffer *lbp)
|
||||||
|
|
||||||
/* Set the minimum size of a string contained in a linebuffer. */
|
/* Set the minimum size of a string contained in a linebuffer. */
|
||||||
static void
|
static void
|
||||||
linebuffer_setlen (linebuffer *lbp, int toksize)
|
linebuffer_setlen (linebuffer *lbp, ptrdiff_t toksize)
|
||||||
{
|
{
|
||||||
while (lbp->size <= toksize)
|
if (lbp->size <= toksize)
|
||||||
{
|
{
|
||||||
lbp->size *= 2;
|
ptrdiff_t multiplier = toksize / lbp->size + 1;
|
||||||
xrnew (lbp->buffer, lbp->size, char);
|
xrnew (lbp->buffer, lbp->size, multiplier);
|
||||||
|
lbp->size *= multiplier;
|
||||||
}
|
}
|
||||||
lbp->len = toksize;
|
lbp->len = toksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like malloc but get fatal error if memory is exhausted. */
|
/* Memory allocators with a fatal error if memory is exhausted. */
|
||||||
static void * ATTRIBUTE_MALLOC
|
|
||||||
xmalloc (size_t size)
|
static void
|
||||||
|
memory_full (void)
|
||||||
{
|
{
|
||||||
|
fatal ("virtual memory exhausted");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
xmalloc (ptrdiff_t size)
|
||||||
|
{
|
||||||
|
if (SIZE_MAX < size)
|
||||||
|
memory_full ();
|
||||||
void *result = malloc (size);
|
void *result = malloc (size);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
fatal ("virtual memory exhausted");
|
memory_full ();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
xrealloc (void *ptr, size_t size)
|
xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size)
|
||||||
{
|
{
|
||||||
void *result = realloc (ptr, size);
|
ptrdiff_t nbytes;
|
||||||
if (result == NULL)
|
if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes))
|
||||||
fatal ("virtual memory exhausted");
|
memory_full ();
|
||||||
|
return xmalloc (nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
|
||||||
|
{
|
||||||
|
ptrdiff_t nbytes;
|
||||||
|
if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes) || SIZE_MAX < nbytes)
|
||||||
|
memory_full ();
|
||||||
|
void *result = realloc (pa, nbytes);
|
||||||
|
if (!result)
|
||||||
|
memory_full ();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@
|
||||||
# lstat \
|
# lstat \
|
||||||
# manywarnings \
|
# manywarnings \
|
||||||
# memmem-simple \
|
# memmem-simple \
|
||||||
|
# mempcpy \
|
||||||
# memrchr \
|
# memrchr \
|
||||||
# minmax \
|
# minmax \
|
||||||
# mkostemp \
|
# mkostemp \
|
||||||
|
|
@ -2027,6 +2028,17 @@ EXTRA_libgnu_a_SOURCES += memmem.c
|
||||||
endif
|
endif
|
||||||
## end gnulib module memmem-simple
|
## end gnulib module memmem-simple
|
||||||
|
|
||||||
|
## begin gnulib module mempcpy
|
||||||
|
ifeq (,$(OMIT_GNULIB_MODULE_mempcpy))
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_DIST += mempcpy.c
|
||||||
|
|
||||||
|
EXTRA_libgnu_a_SOURCES += mempcpy.c
|
||||||
|
|
||||||
|
endif
|
||||||
|
## end gnulib module mempcpy
|
||||||
|
|
||||||
## begin gnulib module memrchr
|
## begin gnulib module memrchr
|
||||||
ifeq (,$(OMIT_GNULIB_MODULE_memrchr))
|
ifeq (,$(OMIT_GNULIB_MODULE_memrchr))
|
||||||
|
|
||||||
|
|
|
||||||
28
lib/mempcpy.c
Normal file
28
lib/mempcpy.c
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* Copy memory area and return pointer after last written byte.
|
||||||
|
Copyright (C) 2003, 2007, 2009-2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
|
||||||
|
last written byte. */
|
||||||
|
void *
|
||||||
|
mempcpy (void *dest, const void *src, size_t n)
|
||||||
|
{
|
||||||
|
return (char *) memcpy (dest, src, n) + n;
|
||||||
|
}
|
||||||
|
|
@ -118,6 +118,7 @@ AC_DEFUN([gl_EARLY],
|
||||||
# Code from module malloca:
|
# Code from module malloca:
|
||||||
# Code from module manywarnings:
|
# Code from module manywarnings:
|
||||||
# Code from module memmem-simple:
|
# Code from module memmem-simple:
|
||||||
|
# Code from module mempcpy:
|
||||||
# Code from module memrchr:
|
# Code from module memrchr:
|
||||||
# Code from module minmax:
|
# Code from module minmax:
|
||||||
# Code from module mkostemp:
|
# Code from module mkostemp:
|
||||||
|
|
@ -327,6 +328,12 @@ AC_DEFUN([gl_INIT],
|
||||||
AC_LIBOBJ([memmem])
|
AC_LIBOBJ([memmem])
|
||||||
fi
|
fi
|
||||||
gl_STRING_MODULE_INDICATOR([memmem])
|
gl_STRING_MODULE_INDICATOR([memmem])
|
||||||
|
gl_FUNC_MEMPCPY
|
||||||
|
if test $HAVE_MEMPCPY = 0; then
|
||||||
|
AC_LIBOBJ([mempcpy])
|
||||||
|
gl_PREREQ_MEMPCPY
|
||||||
|
fi
|
||||||
|
gl_STRING_MODULE_INDICATOR([mempcpy])
|
||||||
gl_FUNC_MEMRCHR
|
gl_FUNC_MEMRCHR
|
||||||
if test $ac_cv_func_memrchr = no; then
|
if test $ac_cv_func_memrchr = no; then
|
||||||
AC_LIBOBJ([memrchr])
|
AC_LIBOBJ([memrchr])
|
||||||
|
|
@ -954,6 +961,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
lib/md5.c
|
lib/md5.c
|
||||||
lib/md5.h
|
lib/md5.h
|
||||||
lib/memmem.c
|
lib/memmem.c
|
||||||
|
lib/mempcpy.c
|
||||||
lib/memrchr.c
|
lib/memrchr.c
|
||||||
lib/minmax.h
|
lib/minmax.h
|
||||||
lib/mkostemp.c
|
lib/mkostemp.c
|
||||||
|
|
@ -1094,6 +1102,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
m4/mbstate_t.m4
|
m4/mbstate_t.m4
|
||||||
m4/md5.m4
|
m4/md5.m4
|
||||||
m4/memmem.m4
|
m4/memmem.m4
|
||||||
|
m4/mempcpy.m4
|
||||||
m4/memrchr.m4
|
m4/memrchr.m4
|
||||||
m4/minmax.m4
|
m4/minmax.m4
|
||||||
m4/mkostemp.m4
|
m4/mkostemp.m4
|
||||||
|
|
|
||||||
26
m4/mempcpy.m4
Normal file
26
m4/mempcpy.m4
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# mempcpy.m4 serial 11
|
||||||
|
dnl Copyright (C) 2003-2004, 2006-2007, 2009-2019 Free Software Foundation,
|
||||||
|
dnl Inc.
|
||||||
|
dnl This file is free software; the Free Software Foundation
|
||||||
|
dnl gives unlimited permission to copy and/or distribute it,
|
||||||
|
dnl with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
AC_DEFUN([gl_FUNC_MEMPCPY],
|
||||||
|
[
|
||||||
|
dnl Persuade glibc <string.h> to declare mempcpy().
|
||||||
|
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
|
||||||
|
|
||||||
|
dnl The mempcpy() declaration in lib/string.in.h uses 'restrict'.
|
||||||
|
AC_REQUIRE([AC_C_RESTRICT])
|
||||||
|
|
||||||
|
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
|
||||||
|
AC_CHECK_FUNCS([mempcpy])
|
||||||
|
if test $ac_cv_func_mempcpy = no; then
|
||||||
|
HAVE_MEMPCPY=0
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
# Prerequisites of lib/mempcpy.c.
|
||||||
|
AC_DEFUN([gl_PREREQ_MEMPCPY], [
|
||||||
|
:
|
||||||
|
])
|
||||||
Loading…
Add table
Add a link
Reference in a new issue