mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-20 18:17:20 +00: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
@ -37,7 +37,7 @@ GNULIB_MODULES='
|
||||
filemode filevercmp flexmember fpieee fstatat fsusage fsync
|
||||
getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
|
||||
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
|
||||
qcopy-acl readlink readlinkat regex
|
||||
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
|
||||
#endif /* WINDOWSNT */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
@ -123,6 +124,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <binary-io.h>
|
||||
#include <intprops.h>
|
||||
#include <unlocked-io.h>
|
||||
#include <c-ctype.h>
|
||||
#include <c-strcase.h>
|
||||
@ -141,6 +143,14 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
|
||||
# define CTAGS false
|
||||
#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
|
||||
streq (char const *s, char const *t)
|
||||
{
|
||||
@ -235,11 +245,11 @@ endtoken (unsigned char c)
|
||||
/*
|
||||
* xnew, xrnew -- allocate, reallocate storage
|
||||
*
|
||||
* SYNOPSIS: Type *xnew (int n, Type);
|
||||
* void xrnew (OldPointer, int n, Type);
|
||||
* SYNOPSIS: Type *xnew (ptrdiff_t n, Type);
|
||||
* void xrnew (OldPointer, ptrdiff_t n, int multiplier);
|
||||
*/
|
||||
#define xnew(n, Type) ((Type *) xmalloc ((n) * sizeof (Type)))
|
||||
#define xrnew(op, n, Type) ((op) = (Type *) xrealloc (op, (n) * sizeof (Type)))
|
||||
#define xnew(n, Type) ((Type *) xnmalloc (n, sizeof (Type)))
|
||||
#define xrnew(op, n, m) ((op) = xnrealloc (op, n, (m) * sizeof *(op)))
|
||||
|
||||
typedef void Lang_function (FILE *);
|
||||
|
||||
@ -282,8 +292,8 @@ typedef struct node_st
|
||||
bool valid; /* write this tag on the tag file */
|
||||
bool is_func; /* function tag: use regexp in CTAGS mode */
|
||||
bool been_warned; /* warning already given for duplicated tag */
|
||||
int lno; /* line number tag is on */
|
||||
long cno; /* character number line starts on */
|
||||
intmax_t lno; /* line number tag is on */
|
||||
intmax_t cno; /* character number line starts on */
|
||||
} node;
|
||||
|
||||
/*
|
||||
@ -295,8 +305,8 @@ typedef struct node_st
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
long size;
|
||||
int len;
|
||||
ptrdiff_t size;
|
||||
ptrdiff_t len;
|
||||
char *buffer;
|
||||
} linebuffer;
|
||||
|
||||
@ -365,7 +375,7 @@ static void just_read_file (FILE *);
|
||||
|
||||
static language *get_language_from_langname (const char *);
|
||||
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 void get_tag (char *, 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 free_tree (node *);
|
||||
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 put_entries (node *);
|
||||
|
||||
@ -393,7 +403,7 @@ static char *concat (const char *, const char *, const char *);
|
||||
static char *skip_spaces (char *);
|
||||
static char *skip_non_spaces (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 *etags_getcwd (void);
|
||||
static char *relative_filename (char *, char *);
|
||||
@ -403,9 +413,11 @@ static bool filename_is_absolute (char *f);
|
||||
static void canonicalize_filename (char *);
|
||||
static char *etags_mktmp (void);
|
||||
static void linebuffer_init (linebuffer *);
|
||||
static void linebuffer_setlen (linebuffer *, int);
|
||||
static void *xmalloc (size_t);
|
||||
static void *xrealloc (void *, size_t);
|
||||
static void linebuffer_setlen (linebuffer *, ptrdiff_t);
|
||||
static void *xmalloc (ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1));
|
||||
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 */
|
||||
@ -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 *curfdp; /* current file description */
|
||||
static char *infilename; /* current input file name */
|
||||
static int lineno; /* line number of current line */
|
||||
static long charno; /* current character number */
|
||||
static long linecharno; /* charno of start of current line */
|
||||
static intmax_t lineno; /* line number of current line */
|
||||
static intmax_t charno; /* current character number */
|
||||
static intmax_t linecharno; /* charno of start of current line */
|
||||
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 *last_node; /* the last node created */
|
||||
@ -1070,7 +1082,7 @@ int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
unsigned int nincluded_files;
|
||||
int nincluded_files;
|
||||
char **included_files;
|
||||
argument *argbuffer;
|
||||
int current_arg, file_count;
|
||||
@ -1484,7 +1496,7 @@ get_language_from_interpreter (char *interpreter)
|
||||
* Return a language given the file name.
|
||||
*/
|
||||
static language *
|
||||
get_language_from_filename (char *file, int case_sensitive)
|
||||
get_language_from_filename (char *file, bool case_sensitive)
|
||||
{
|
||||
language *lang;
|
||||
const char **name, **ext, *suffix;
|
||||
@ -1918,26 +1930,26 @@ find_entries (FILE *inf)
|
||||
*/
|
||||
static void
|
||||
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 */
|
||||
char *linestart, /* start of the line where tag is */
|
||||
int linelen, /* length of the line where tag is */
|
||||
int lno, /* line number */
|
||||
long int cno) /* character number */
|
||||
ptrdiff_t linelen, /* length of the line where tag is */
|
||||
intmax_t lno, /* line number */
|
||||
intmax_t cno) /* character number */
|
||||
{
|
||||
bool named = (name != NULL && namelen > 0);
|
||||
char *nname = NULL;
|
||||
|
||||
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);
|
||||
|
||||
if (!CTAGS && named) /* maybe set named to false */
|
||||
/* 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. */
|
||||
{
|
||||
int i;
|
||||
register const char *cp = name;
|
||||
ptrdiff_t i;
|
||||
const char *cp = name;
|
||||
|
||||
for (i = 0; i < namelen; i++)
|
||||
if (notinname (*cp++))
|
||||
@ -1963,8 +1975,8 @@ make_tag (const char *name, /* tag name, or NULL if unnamed */
|
||||
|
||||
/* Record a tag. */
|
||||
static void
|
||||
pfnote (char *name, bool is_func, char *linestart, int linelen, int lno,
|
||||
long int cno)
|
||||
pfnote (char *name, bool is_func, char *linestart, ptrdiff_t linelen,
|
||||
intmax_t lno, intmax_t cno)
|
||||
/* tag name, or NULL if unnamed */
|
||||
/* tag is a function */
|
||||
/* start of the line where tag is */
|
||||
@ -2197,7 +2209,8 @@ add_node (node *np, node **cur_node_p)
|
||||
if (!no_warnings)
|
||||
{
|
||||
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);
|
||||
fprintf (stderr, "Second entry ignored\n");
|
||||
}
|
||||
@ -2293,12 +2306,12 @@ invalidate_nodes (fdesc *badfdp, node **npp)
|
||||
}
|
||||
|
||||
|
||||
static int total_size_of_entries (node *);
|
||||
static int number_len (long) ATTRIBUTE_CONST;
|
||||
static ptrdiff_t total_size_of_entries (node *);
|
||||
static int number_len (intmax_t) ATTRIBUTE_CONST;
|
||||
|
||||
/* Length of a non-negative number's decimal representation. */
|
||||
static int
|
||||
number_len (long int num)
|
||||
number_len (intmax_t num)
|
||||
{
|
||||
int len = 1;
|
||||
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,
|
||||
* but is still supplied for backward compatibility.
|
||||
*/
|
||||
static int
|
||||
total_size_of_entries (register node *np)
|
||||
static ptrdiff_t
|
||||
total_size_of_entries (node *np)
|
||||
{
|
||||
register int total = 0;
|
||||
ptrdiff_t total = 0;
|
||||
|
||||
for (; np != NULL; np = np->right)
|
||||
if (np->valid)
|
||||
@ -2323,7 +2336,7 @@ total_size_of_entries (register node *np)
|
||||
total += strlen (np->regex) + 1; /* pat\177 */
|
||||
if (np->name != NULL)
|
||||
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 */
|
||||
total += number_len (np->cno);
|
||||
total += 1; /* newline */
|
||||
@ -2347,7 +2360,7 @@ put_entry (node *np)
|
||||
if (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->written = true;
|
||||
}
|
||||
@ -2358,9 +2371,9 @@ put_entry (node *np)
|
||||
fputs (np->name, tagf);
|
||||
fputc ('\001', tagf);
|
||||
}
|
||||
fprintf (tagf, "%d,", np->lno);
|
||||
fprintf (tagf, "%"PRIdMAX",", np->lno);
|
||||
if (np->cno != invalidcharno)
|
||||
fprintf (tagf, "%ld", np->cno);
|
||||
fprintf (tagf, "%"PRIdMAX, np->cno);
|
||||
fputs ("\n", tagf);
|
||||
}
|
||||
else
|
||||
@ -2372,10 +2385,10 @@ put_entry (node *np)
|
||||
if (cxref_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);
|
||||
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);
|
||||
}
|
||||
else
|
||||
@ -2397,7 +2410,7 @@ put_entry (node *np)
|
||||
}
|
||||
else
|
||||
{ /* anything else; text pattern inadequate */
|
||||
fprintf (tagf, "%d", np->lno);
|
||||
fprintf (tagf, "%"PRIdMAX, np->lno);
|
||||
}
|
||||
putc ('\n', tagf);
|
||||
}
|
||||
@ -2591,7 +2604,7 @@ hash (const char *str, int len)
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
@ -2658,9 +2671,9 @@ in_word_set (register const char *str, register unsigned int len)
|
||||
/*%>*/
|
||||
|
||||
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)))
|
||||
return st_none;
|
||||
@ -2770,8 +2783,8 @@ static enum
|
||||
static struct tok
|
||||
{
|
||||
char *line; /* string containing the token */
|
||||
int offset; /* where the token starts in LINE */
|
||||
int length; /* token length */
|
||||
ptrdiff_t offset; /* where the token starts in LINE */
|
||||
ptrdiff_t length; /* token length */
|
||||
/*
|
||||
The previous members can be used to pass strings around for generic
|
||||
purposes. The following ones specifically refer to creating tags. In this
|
||||
@ -2782,23 +2795,23 @@ static struct tok
|
||||
invalidated whenever a state machine is
|
||||
reset prematurely */
|
||||
bool named; /* create a named tag */
|
||||
int lineno; /* source line number of tag */
|
||||
long linepos; /* source char number of tag */
|
||||
intmax_t lineno; /* source line number of tag */
|
||||
intmax_t linepos; /* source char number of tag */
|
||||
} token; /* latest token read */
|
||||
|
||||
/*
|
||||
* Variables and functions for dealing with nested structures.
|
||||
* Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
|
||||
*/
|
||||
static void pushclass_above (int, char *, int);
|
||||
static void popclass_above (int);
|
||||
static void pushclass_above (ptrdiff_t, char *, ptrdiff_t);
|
||||
static void popclass_above (ptrdiff_t);
|
||||
static void write_classname (linebuffer *, const char *qualifier);
|
||||
|
||||
static struct {
|
||||
char **cname; /* nested class names */
|
||||
int *bracelev; /* nested class brace level */
|
||||
int nl; /* class nesting level (elements used) */
|
||||
int size; /* length of the array */
|
||||
ptrdiff_t *bracelev; /* nested class brace level */
|
||||
ptrdiff_t nl; /* class nesting level (elements used) */
|
||||
ptrdiff_t size; /* length of the array */
|
||||
} cstack; /* stack for nested declaration tags */
|
||||
/* Current struct nesting depth (namespace, class, struct, union, enum). */
|
||||
#define nestlev (cstack.nl)
|
||||
@ -2807,17 +2820,17 @@ static struct {
|
||||
&& bracelev == cstack.bracelev[nestlev-1] + 1)
|
||||
|
||||
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);
|
||||
nl = cstack.nl;
|
||||
if (nl >= cstack.size)
|
||||
{
|
||||
int size = cstack.size *= 2;
|
||||
xrnew (cstack.cname, size, char *);
|
||||
xrnew (cstack.bracelev, size, int);
|
||||
xrnew (cstack.cname, cstack.size, 2);
|
||||
xrnew (cstack.bracelev, cstack.size, 2);
|
||||
cstack.size *= 2;
|
||||
}
|
||||
assert (nl == 0 || cstack.bracelev[nl-1] < bracelev);
|
||||
cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
|
||||
@ -2826,11 +2839,9 @@ pushclass_above (int bracelev, char *str, int len)
|
||||
}
|
||||
|
||||
static void
|
||||
popclass_above (int bracelev)
|
||||
popclass_above (ptrdiff_t bracelev)
|
||||
{
|
||||
int nl;
|
||||
|
||||
for (nl = cstack.nl - 1;
|
||||
for (ptrdiff_t nl = cstack.nl - 1;
|
||||
nl >= 0 && cstack.bracelev[nl] >= bracelev;
|
||||
nl--)
|
||||
{
|
||||
@ -2842,8 +2853,7 @@ popclass_above (int bracelev)
|
||||
static void
|
||||
write_classname (linebuffer *cn, const char *qualifier)
|
||||
{
|
||||
int i, len;
|
||||
int qlen = strlen (qualifier);
|
||||
ptrdiff_t len;
|
||||
|
||||
if (cstack.nl == 0 || cstack.cname[0] == NULL)
|
||||
{
|
||||
@ -2857,18 +2867,22 @@ write_classname (linebuffer *cn, const char *qualifier)
|
||||
linebuffer_setlen (cn, len);
|
||||
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];
|
||||
if (s == NULL)
|
||||
continue;
|
||||
linebuffer_setlen (cn, len + qlen + strlen (s));
|
||||
len += sprintf (cn->buffer + len, "%s%s", qualifier, s);
|
||||
int qlen = strlen (qualifier);
|
||||
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);
|
||||
|
||||
/*
|
||||
@ -2889,8 +2903,8 @@ static void make_C_tag (bool);
|
||||
*/
|
||||
|
||||
static bool
|
||||
consider_token (char *str, int len, int c, int *c_extp,
|
||||
int bracelev, int parlev, bool *is_func_or_var)
|
||||
consider_token (char *str, ptrdiff_t len, int c, int *c_extp,
|
||||
ptrdiff_t bracelev, ptrdiff_t parlev, bool *is_func_or_var)
|
||||
/* IN: token pointer */
|
||||
/* IN: token length */
|
||||
/* 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
|
||||
structbracelev is the brace level where it has been seen. */
|
||||
static enum sym_type structtype;
|
||||
static int structbracelev;
|
||||
static ptrdiff_t structbracelev;
|
||||
static enum sym_type toktype;
|
||||
|
||||
|
||||
@ -3098,8 +3112,7 @@ consider_token (char *str, int len, int c, int *c_extp,
|
||||
fvdef = fvnone;
|
||||
objdef = omethodtag;
|
||||
linebuffer_setlen (&token_name, len);
|
||||
memcpy (token_name.buffer, str, len);
|
||||
token_name.buffer[len] = '\0';
|
||||
memcpyz (token_name.buffer, str, len);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -3113,11 +3126,10 @@ consider_token (char *str, int len, int c, int *c_extp,
|
||||
objdef = omethodtag;
|
||||
if (class_qualify)
|
||||
{
|
||||
int oldlen = token_name.len;
|
||||
ptrdiff_t oldlen = token_name.len;
|
||||
fvdef = fvnone;
|
||||
linebuffer_setlen (&token_name, oldlen + len);
|
||||
memcpy (token_name.buffer + oldlen, str, len);
|
||||
token_name.buffer[oldlen + len] = '\0';
|
||||
memcpyz (token_name.buffer + oldlen, str, len);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -3228,7 +3240,7 @@ consider_token (char *str, int len, int c, int *c_extp,
|
||||
*/
|
||||
static struct
|
||||
{
|
||||
long linepos;
|
||||
intmax_t linepos;
|
||||
linebuffer lb;
|
||||
} lbs[2];
|
||||
|
||||
@ -3302,19 +3314,19 @@ C_entries (int c_ext, FILE *inf)
|
||||
/* extension of C */
|
||||
/* input file */
|
||||
{
|
||||
register char c; /* latest char read; '\0' for end of line */
|
||||
register char *lp; /* pointer one beyond the character `c' */
|
||||
int curndx, newndx; /* indices for current and new lb */
|
||||
register int tokoff; /* offset in line of start of current token */
|
||||
register int toklen; /* length of current token */
|
||||
char c; /* latest char read; '\0' for end of line */
|
||||
char *lp; /* pointer one beyond the character `c' */
|
||||
bool curndx, newndx; /* indices for current and new lb */
|
||||
ptrdiff_t tokoff; /* offset in line of start of current token */
|
||||
ptrdiff_t toklen; /* length of current token */
|
||||
const char *qualifier; /* string used to qualify names */
|
||||
int qlen; /* length of qualifier */
|
||||
int bracelev; /* current brace level */
|
||||
int bracketlev; /* current bracket level */
|
||||
int parlev; /* current parenthesis level */
|
||||
int attrparlev; /* __attribute__ parenthesis level */
|
||||
int templatelev; /* current template level */
|
||||
int typdefbracelev; /* bracelev where a typedef struct body begun */
|
||||
ptrdiff_t bracelev; /* current brace level */
|
||||
ptrdiff_t bracketlev; /* current bracket level */
|
||||
ptrdiff_t parlev; /* current parenthesis level */
|
||||
ptrdiff_t attrparlev; /* __attribute__ parenthesis level */
|
||||
ptrdiff_t templatelev; /* current template level */
|
||||
ptrdiff_t typdefbracelev; /* bracelev where a typedef struct body begun */
|
||||
bool incomm, inquote, inchar, quotednl, midtoken;
|
||||
bool yacc_rules; /* in the rules part of a yacc file */
|
||||
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.nl = 0;
|
||||
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 */
|
||||
@ -3579,20 +3591,19 @@ C_entries (int c_ext, FILE *inf)
|
||||
{
|
||||
if (class_qualify)
|
||||
{
|
||||
int len;
|
||||
write_classname (&token_name, qualifier);
|
||||
len = token_name.len;
|
||||
ptrdiff_t len = token_name.len;
|
||||
linebuffer_setlen (&token_name,
|
||||
len + qlen + toklen);
|
||||
sprintf (token_name.buffer + len, "%s%.*s",
|
||||
qualifier, toklen,
|
||||
newlb.buffer + tokoff);
|
||||
memcpyz (stpcpy (token_name.buffer + len,
|
||||
qualifier),
|
||||
newlb.buffer + tokoff, toklen);
|
||||
}
|
||||
else
|
||||
{
|
||||
linebuffer_setlen (&token_name, toklen);
|
||||
sprintf (token_name.buffer, "%.*s",
|
||||
toklen, newlb.buffer + tokoff);
|
||||
memcpyz (token_name.buffer,
|
||||
newlb.buffer + tokoff, toklen);
|
||||
}
|
||||
token.named = true;
|
||||
}
|
||||
@ -3601,17 +3612,19 @@ C_entries (int c_ext, FILE *inf)
|
||||
{
|
||||
if (class_qualify)
|
||||
{
|
||||
int len = strlen (objtag) + 2 + toklen;
|
||||
ptrdiff_t len = strlen (objtag) + 2 + toklen;
|
||||
linebuffer_setlen (&token_name, len);
|
||||
sprintf (token_name.buffer, "%s(%.*s)",
|
||||
objtag, toklen,
|
||||
newlb.buffer + tokoff);
|
||||
char *p1 = stpcpy (token_name.buffer, objtag);
|
||||
char *p2 = stpcpy (p1, "(");
|
||||
char *p3 = mempcpy (p2, newlb.buffer + tokoff,
|
||||
toklen);
|
||||
strcpy (p3, ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
linebuffer_setlen (&token_name, toklen);
|
||||
sprintf (token_name.buffer, "%.*s",
|
||||
toklen, newlb.buffer + tokoff);
|
||||
memcpyz (token_name.buffer,
|
||||
newlb.buffer + tokoff, toklen);
|
||||
}
|
||||
token.named = true;
|
||||
}
|
||||
@ -3625,8 +3638,8 @@ C_entries (int c_ext, FILE *inf)
|
||||
/* GNU DEFUN and similar macros */
|
||||
{
|
||||
bool defun = (newlb.buffer[tokoff] == 'F');
|
||||
int off = tokoff;
|
||||
int len = toklen;
|
||||
ptrdiff_t off = tokoff;
|
||||
ptrdiff_t len = toklen;
|
||||
|
||||
if (defun)
|
||||
{
|
||||
@ -3635,9 +3648,8 @@ C_entries (int c_ext, FILE *inf)
|
||||
|
||||
/* First, tag it as its C name */
|
||||
linebuffer_setlen (&token_name, toklen);
|
||||
memcpy (token_name.buffer,
|
||||
newlb.buffer + tokoff, toklen);
|
||||
token_name.buffer[toklen] = '\0';
|
||||
memcpyz (token_name.buffer,
|
||||
newlb.buffer + tokoff, toklen);
|
||||
token.named = true;
|
||||
token.lineno = lineno;
|
||||
token.offset = tokoff;
|
||||
@ -3650,9 +3662,8 @@ C_entries (int c_ext, FILE *inf)
|
||||
/* Rewrite the tag so that emacs lisp DEFUNs
|
||||
can be found also by their elisp name */
|
||||
linebuffer_setlen (&token_name, len);
|
||||
memcpy (token_name.buffer,
|
||||
newlb.buffer + off, len);
|
||||
token_name.buffer[len] = '\0';
|
||||
memcpyz (token_name.buffer,
|
||||
newlb.buffer + off, len);
|
||||
if (defun)
|
||||
while (--len >= 0)
|
||||
if (token_name.buffer[len] == '_')
|
||||
@ -3662,9 +3673,8 @@ C_entries (int c_ext, FILE *inf)
|
||||
else
|
||||
{
|
||||
linebuffer_setlen (&token_name, toklen);
|
||||
memcpy (token_name.buffer,
|
||||
newlb.buffer + tokoff, toklen);
|
||||
token_name.buffer[toklen] = '\0';
|
||||
memcpyz (token_name.buffer,
|
||||
newlb.buffer + tokoff, toklen);
|
||||
/* Name macros and members. */
|
||||
token.named = (structdef == stagseen
|
||||
|| typdef == ttypeseen
|
||||
@ -3790,7 +3800,7 @@ C_entries (int c_ext, FILE *inf)
|
||||
objdef = omethodcolon;
|
||||
if (class_qualify)
|
||||
{
|
||||
int toklen = token_name.len;
|
||||
ptrdiff_t toklen = token_name.len;
|
||||
linebuffer_setlen (&token_name, toklen + 1);
|
||||
strcpy (token_name.buffer + toklen, ":");
|
||||
}
|
||||
@ -4061,7 +4071,7 @@ C_entries (int c_ext, FILE *inf)
|
||||
}
|
||||
if (uqname > token_name.buffer)
|
||||
{
|
||||
int uqlen = strlen (uqname);
|
||||
ptrdiff_t uqlen = strlen (uqname);
|
||||
linebuffer_setlen (&token_name, uqlen);
|
||||
memmove (token_name.buffer, uqname, uqlen + 1);
|
||||
}
|
||||
@ -4979,12 +4989,11 @@ Ruby_functions (FILE *inf)
|
||||
size_t name_len = cp - np + 1;
|
||||
char *wr_name = xnew (name_len + 1, char);
|
||||
|
||||
memcpy (wr_name, np, name_len - 1);
|
||||
memcpy (wr_name + name_len - 1, "=", 2);
|
||||
strcpy (mempcpy (wr_name, np, name_len - 1), "=");
|
||||
pfnote (wr_name, true, lb.buffer, cp - lb.buffer + 1,
|
||||
lineno, linecharno);
|
||||
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);
|
||||
continuation = false;
|
||||
}
|
||||
@ -5178,8 +5187,8 @@ static void
|
||||
Pascal_functions (FILE *inf)
|
||||
{
|
||||
linebuffer tline; /* mostly copied from C_entries */
|
||||
long save_lcno;
|
||||
int save_lineno, namelen, taglen;
|
||||
intmax_t save_lcno, save_lineno;
|
||||
ptrdiff_t namelen, taglen;
|
||||
char c, *name;
|
||||
|
||||
bool /* each of these flags is true if: */
|
||||
@ -5455,7 +5464,7 @@ Lua_functions (FILE *inf)
|
||||
if (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);
|
||||
}
|
||||
@ -5656,7 +5665,7 @@ TeX_commands (FILE *inf)
|
||||
if (strneq (cp, key->buffer, key->len))
|
||||
{
|
||||
char *p;
|
||||
int namelen, linelen;
|
||||
ptrdiff_t namelen, linelen;
|
||||
bool opgrp = false;
|
||||
|
||||
cp = skip_spaces (cp + key->len);
|
||||
@ -5693,8 +5702,8 @@ TeX_commands (FILE *inf)
|
||||
static void
|
||||
TEX_decode_env (const char *evarname, const char *defenv)
|
||||
{
|
||||
register const char *env, *p;
|
||||
int i, len;
|
||||
const char *env, *p;
|
||||
ptrdiff_t len;
|
||||
|
||||
/* Append default string to environment. */
|
||||
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 */
|
||||
/* zero-length strings (leading ':', "::" and trailing ':') */
|
||||
for (i = 0; *env != '\0';)
|
||||
for (ptrdiff_t i = 0; *env != '\0'; )
|
||||
{
|
||||
p = strchr (env, ':');
|
||||
if (!p) /* End of environment string. */
|
||||
@ -5811,8 +5820,7 @@ HTML_labels (FILE *inf)
|
||||
for (end = dbp; *end != '\0' && intoken (*end); end++)
|
||||
continue;
|
||||
linebuffer_setlen (&token_name, end - dbp);
|
||||
memcpy (token_name.buffer, dbp, end - dbp);
|
||||
token_name.buffer[end - dbp] = '\0';
|
||||
memcpyz (token_name.buffer, dbp, end - dbp);
|
||||
|
||||
dbp = end;
|
||||
intag = false; /* we found what we looked for */
|
||||
@ -5906,11 +5914,10 @@ Prolog_functions (FILE *inf)
|
||||
tags later. */
|
||||
if (allocated <= len)
|
||||
{
|
||||
xrnew (last, len + 1, char);
|
||||
xrnew (last, len + 1, 1);
|
||||
allocated = len + 1;
|
||||
}
|
||||
memcpy (last, cp, len);
|
||||
last[len] = '\0';
|
||||
memcpyz (last, cp, len);
|
||||
lastlen = len;
|
||||
}
|
||||
}
|
||||
@ -6031,9 +6038,9 @@ prolog_atom (char *s, size_t pos)
|
||||
* Assumes that Erlang functions start at column 0.
|
||||
* 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 int erlang_atom (char *);
|
||||
static ptrdiff_t erlang_atom (char *);
|
||||
|
||||
static void
|
||||
Erlang_functions (FILE *inf)
|
||||
@ -6070,11 +6077,10 @@ Erlang_functions (FILE *inf)
|
||||
tags later. */
|
||||
if (allocated <= len)
|
||||
{
|
||||
xrnew (last, len + 1, char);
|
||||
xrnew (last, len + 1, 1);
|
||||
allocated = len + 1;
|
||||
}
|
||||
memcpy (last, cp + name_offset, len);
|
||||
last[len] = '\0';
|
||||
memcpyz (last, cp + name_offset, 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
|
||||
* was found.
|
||||
*/
|
||||
static int
|
||||
static ptrdiff_t
|
||||
erlang_func (char *s, char *last, ptrdiff_t lastlen, ptrdiff_t *name_offset)
|
||||
{
|
||||
char *name = s;
|
||||
@ -6133,15 +6139,13 @@ static void
|
||||
erlang_attribute (char *s)
|
||||
{
|
||||
char *cp = s;
|
||||
int pos;
|
||||
int len;
|
||||
|
||||
if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record"))
|
||||
&& *cp++ == '(')
|
||||
{
|
||||
cp = skip_spaces (cp);
|
||||
len = erlang_atom (cp);
|
||||
pos = cp + len - s;
|
||||
ptrdiff_t len = erlang_atom (cp);
|
||||
ptrdiff_t pos = cp + len - s;
|
||||
if (len > 0)
|
||||
{
|
||||
/* 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).
|
||||
* Return the number of bytes consumed, or -1 if there was an error.
|
||||
*/
|
||||
static int
|
||||
static ptrdiff_t
|
||||
erlang_atom (char *s)
|
||||
{
|
||||
int pos = 0;
|
||||
ptrdiff_t pos = 0;
|
||||
|
||||
if (c_isalpha (s[pos]) || s[pos] == '_')
|
||||
{
|
||||
@ -6437,10 +6441,9 @@ static char *
|
||||
substitute (char *in, char *out, struct re_registers *regs)
|
||||
{
|
||||
char *result, *t;
|
||||
int size, dig, diglen;
|
||||
|
||||
result = NULL;
|
||||
size = strlen (out);
|
||||
ptrdiff_t size = strlen (out);
|
||||
|
||||
/* Pass 1: figure out how much to allocate by finding all \N strings. */
|
||||
if (out[size - 1] == '\\')
|
||||
@ -6450,8 +6453,8 @@ substitute (char *in, char *out, struct re_registers *regs)
|
||||
t = strchr (t + 2, '\\'))
|
||||
if (c_isdigit (t[1]))
|
||||
{
|
||||
dig = t[1] - '0';
|
||||
diglen = regs->end[dig] - regs->start[dig];
|
||||
int dig = t[1] - '0';
|
||||
ptrdiff_t diglen = regs->end[dig] - regs->start[dig];
|
||||
size += diglen - 2;
|
||||
}
|
||||
else
|
||||
@ -6464,8 +6467,8 @@ substitute (char *in, char *out, struct re_registers *regs)
|
||||
for (t = result; *out != '\0'; out++)
|
||||
if (*out == '\\' && c_isdigit (*++out))
|
||||
{
|
||||
dig = *out - '0';
|
||||
diglen = regs->end[dig] - regs->start[dig];
|
||||
int dig = *out - '0';
|
||||
ptrdiff_t diglen = regs->end[dig] - regs->start[dig];
|
||||
memcpy (t, in + regs->start[dig], diglen);
|
||||
t += diglen;
|
||||
}
|
||||
@ -6474,7 +6477,7 @@ substitute (char *in, char *out, struct re_registers *regs)
|
||||
*t = '\0';
|
||||
|
||||
assert (t <= result + size);
|
||||
assert (t - result == (int)strlen (result));
|
||||
assert (t == result + strlen (result));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -6511,7 +6514,7 @@ regex_tag_multiline (void)
|
||||
|
||||
for (rp = p_head; rp != NULL; rp = rp->p_next)
|
||||
{
|
||||
int match = 0;
|
||||
ptrdiff_t match = 0;
|
||||
|
||||
if (!rp->multi_line)
|
||||
continue; /* skip normal regexps */
|
||||
@ -6572,7 +6575,7 @@ regex_tag_multiline (void)
|
||||
charno - linecharno + 1, lineno, linecharno);
|
||||
|
||||
if (debug)
|
||||
fprintf (stderr, "%s on %s:%d: %s\n",
|
||||
fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n",
|
||||
name ? name : "(unnamed)", curfdp->taggedfname,
|
||||
lineno, buffer + linecharno);
|
||||
}
|
||||
@ -6589,7 +6592,7 @@ regex_tag_multiline (void)
|
||||
static bool
|
||||
nocase_tail (const char *cp)
|
||||
{
|
||||
int len = 0;
|
||||
ptrdiff_t len = 0;
|
||||
|
||||
while (*cp != '\0' && c_tolower (*cp) == c_tolower (dbp[len]))
|
||||
cp++, len++;
|
||||
@ -6648,7 +6651,7 @@ get_lispy_tag (register char *bp)
|
||||
* If multi-line regular expressions are requested, each line read is
|
||||
* appended to `filebuf'.
|
||||
*/
|
||||
static long
|
||||
static ptrdiff_t
|
||||
readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
||||
{
|
||||
char *buffer = lbp->buffer;
|
||||
@ -6664,8 +6667,8 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
||||
if (p == pend)
|
||||
{
|
||||
/* We're at the end of linebuffer: expand it. */
|
||||
xrnew (buffer, lbp->size, 2);
|
||||
lbp->size *= 2;
|
||||
xrnew (buffer, lbp->size, char);
|
||||
p += buffer - lbp->buffer;
|
||||
pend = buffer + lbp->size;
|
||||
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 */
|
||||
{
|
||||
/* Expand filebuf. */
|
||||
xrnew (filebuf.buffer, filebuf.size, 2);
|
||||
filebuf.size *= 2;
|
||||
xrnew (filebuf.buffer, filebuf.size, char);
|
||||
}
|
||||
memcpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len);
|
||||
filebuf.len += lbp->len;
|
||||
filebuf.buffer[filebuf.len++] = '\n';
|
||||
filebuf.buffer[filebuf.len] = '\0';
|
||||
strcpy (mempcpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len),
|
||||
"\n");
|
||||
filebuf.len += lbp->len + 1;
|
||||
}
|
||||
|
||||
return lbp->len + chars_deleted;
|
||||
@ -6722,10 +6724,8 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
|
||||
static void
|
||||
readline (linebuffer *lbp, FILE *stream)
|
||||
{
|
||||
long result;
|
||||
|
||||
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 */
|
||||
charno += result; /* increment global char number */
|
||||
|
||||
@ -6737,10 +6737,10 @@ readline (linebuffer *lbp, FILE *stream)
|
||||
/* Check whether this is a #line directive. */
|
||||
if (result > 12 && strneq (lbp->buffer, "#line ", 6))
|
||||
{
|
||||
unsigned int lno;
|
||||
intmax_t lno;
|
||||
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 */
|
||||
{
|
||||
char *endp = lbp->buffer + start;
|
||||
@ -6850,7 +6850,7 @@ readline (linebuffer *lbp, FILE *stream)
|
||||
} /* if #line directives should be considered */
|
||||
|
||||
{
|
||||
int match;
|
||||
ptrdiff_t match;
|
||||
regexp *rp;
|
||||
char *name;
|
||||
|
||||
@ -6900,7 +6900,7 @@ readline (linebuffer *lbp, FILE *stream)
|
||||
/* Force explicit tag name, if a name is there. */
|
||||
pfnote (name, true, lbp->buffer, match, lineno, linecharno);
|
||||
if (debug)
|
||||
fprintf (stderr, "%s on %s:%d: %s\n",
|
||||
fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n",
|
||||
name ? name : "(unnamed)", curfdp->taggedfname,
|
||||
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
|
||||
* the string CP has been copied for at most the first LEN characters.
|
||||
* Return a pointer to a space of size LEN+1 allocated with xnew
|
||||
* with a copy of CP (containing LEN bytes) followed by a NUL byte.
|
||||
*/
|
||||
static char *
|
||||
savenstr (const char *cp, int len)
|
||||
savenstr (const char *cp, ptrdiff_t len)
|
||||
{
|
||||
char *dp = xnew (len + 1, char);
|
||||
dp[len] = '\0';
|
||||
@ -7013,13 +7013,9 @@ verror (char const *format, va_list ap)
|
||||
static char *
|
||||
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);
|
||||
|
||||
strcpy (result, s1);
|
||||
strcpy (result + len1, s2);
|
||||
strcpy (result + len1 + len2, s3);
|
||||
|
||||
strcpy (stpcpy (stpcpy (result, s1), s2), s3);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -7029,16 +7025,16 @@ concat (const char *s1, const char *s2, const char *s3)
|
||||
static char *
|
||||
etags_getcwd (void)
|
||||
{
|
||||
int bufsize = 200;
|
||||
ptrdiff_t bufsize = 200;
|
||||
char *path = xnew (bufsize, char);
|
||||
|
||||
while (getcwd (path, bufsize) == NULL)
|
||||
{
|
||||
if (errno != ERANGE)
|
||||
pfatal ("getcwd");
|
||||
bufsize *= 2;
|
||||
free (path);
|
||||
path = xnew (bufsize, char);
|
||||
path = xnmalloc (bufsize, 2 * sizeof *path);
|
||||
bufsize *= 2;
|
||||
}
|
||||
|
||||
canonicalize_filename (path);
|
||||
@ -7099,7 +7095,7 @@ static char *
|
||||
relative_filename (char *file, char *dir)
|
||||
{
|
||||
char *fp, *dp, *afn, *res;
|
||||
int i;
|
||||
ptrdiff_t i;
|
||||
|
||||
/* Find the common root of file and dir (with a trailing slash). */
|
||||
afn = absolute_filename (file, cwd);
|
||||
@ -7282,32 +7278,54 @@ linebuffer_init (linebuffer *lbp)
|
||||
|
||||
/* Set the minimum size of a string contained in a linebuffer. */
|
||||
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;
|
||||
xrnew (lbp->buffer, lbp->size, char);
|
||||
ptrdiff_t multiplier = toksize / lbp->size + 1;
|
||||
xrnew (lbp->buffer, lbp->size, multiplier);
|
||||
lbp->size *= multiplier;
|
||||
}
|
||||
lbp->len = toksize;
|
||||
}
|
||||
|
||||
/* Like malloc but get fatal error if memory is exhausted. */
|
||||
static void * ATTRIBUTE_MALLOC
|
||||
xmalloc (size_t size)
|
||||
/* Memory allocators with a fatal error if memory is exhausted. */
|
||||
|
||||
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);
|
||||
if (result == NULL)
|
||||
fatal ("virtual memory exhausted");
|
||||
memory_full ();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void *
|
||||
xrealloc (void *ptr, size_t size)
|
||||
xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size)
|
||||
{
|
||||
void *result = realloc (ptr, size);
|
||||
if (result == NULL)
|
||||
fatal ("virtual memory exhausted");
|
||||
ptrdiff_t nbytes;
|
||||
if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes))
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,7 @@
|
||||
# lstat \
|
||||
# manywarnings \
|
||||
# memmem-simple \
|
||||
# mempcpy \
|
||||
# memrchr \
|
||||
# minmax \
|
||||
# mkostemp \
|
||||
@ -2027,6 +2028,17 @@ EXTRA_libgnu_a_SOURCES += memmem.c
|
||||
endif
|
||||
## 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
|
||||
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 manywarnings:
|
||||
# Code from module memmem-simple:
|
||||
# Code from module mempcpy:
|
||||
# Code from module memrchr:
|
||||
# Code from module minmax:
|
||||
# Code from module mkostemp:
|
||||
@ -327,6 +328,12 @@ AC_DEFUN([gl_INIT],
|
||||
AC_LIBOBJ([memmem])
|
||||
fi
|
||||
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
|
||||
if test $ac_cv_func_memrchr = no; then
|
||||
AC_LIBOBJ([memrchr])
|
||||
@ -954,6 +961,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||
lib/md5.c
|
||||
lib/md5.h
|
||||
lib/memmem.c
|
||||
lib/mempcpy.c
|
||||
lib/memrchr.c
|
||||
lib/minmax.h
|
||||
lib/mkostemp.c
|
||||
@ -1094,6 +1102,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||
m4/mbstate_t.m4
|
||||
m4/md5.m4
|
||||
m4/memmem.m4
|
||||
m4/mempcpy.m4
|
||||
m4/memrchr.m4
|
||||
m4/minmax.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…
Reference in New Issue
Block a user