diff options
| author | Paul Eggert | 2019-11-26 13:53:41 -0800 |
|---|---|---|
| committer | Paul Eggert | 2019-11-26 13:57:00 -0800 |
| commit | cffa5703b95fba3624dc54db5e693bae559eac5f (patch) | |
| tree | 7ac0719a3db6a29399ed4389ff27f1d0aeb211e5 /lib-src | |
| parent | 75b41a38dd0735fe63457e12741656c63972d3ce (diff) | |
| download | emacs-cffa5703b95fba3624dc54db5e693bae559eac5f.tar.gz emacs-cffa5703b95fba3624dc54db5e693bae559eac5f.zip | |
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.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/etags.c | 404 |
1 files changed, 211 insertions, 193 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index 6409407e466..0665cb00b9b 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -114,6 +114,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; | |||
| 114 | # define O_CLOEXEC O_NOINHERIT | 114 | # define O_CLOEXEC O_NOINHERIT |
| 115 | #endif /* WINDOWSNT */ | 115 | #endif /* WINDOWSNT */ |
| 116 | 116 | ||
| 117 | #include <inttypes.h> | ||
| 117 | #include <limits.h> | 118 | #include <limits.h> |
| 118 | #include <unistd.h> | 119 | #include <unistd.h> |
| 119 | #include <stdarg.h> | 120 | #include <stdarg.h> |
| @@ -123,6 +124,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; | |||
| 123 | #include <errno.h> | 124 | #include <errno.h> |
| 124 | #include <fcntl.h> | 125 | #include <fcntl.h> |
| 125 | #include <binary-io.h> | 126 | #include <binary-io.h> |
| 127 | #include <intprops.h> | ||
| 126 | #include <unlocked-io.h> | 128 | #include <unlocked-io.h> |
| 127 | #include <c-ctype.h> | 129 | #include <c-ctype.h> |
| 128 | #include <c-strcase.h> | 130 | #include <c-strcase.h> |
| @@ -141,6 +143,14 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; | |||
| 141 | # define CTAGS false | 143 | # define CTAGS false |
| 142 | #endif | 144 | #endif |
| 143 | 145 | ||
| 146 | /* Copy to DEST from SRC (containing LEN bytes), and append a NUL byte. */ | ||
| 147 | static void | ||
| 148 | memcpyz (void *dest, void const *src, ptrdiff_t len) | ||
| 149 | { | ||
| 150 | char *e = mempcpy (dest, src, len); | ||
| 151 | *e = '\0'; | ||
| 152 | } | ||
| 153 | |||
| 144 | static bool | 154 | static bool |
| 145 | streq (char const *s, char const *t) | 155 | streq (char const *s, char const *t) |
| 146 | { | 156 | { |
| @@ -235,11 +245,11 @@ endtoken (unsigned char c) | |||
| 235 | /* | 245 | /* |
| 236 | * xnew, xrnew -- allocate, reallocate storage | 246 | * xnew, xrnew -- allocate, reallocate storage |
| 237 | * | 247 | * |
| 238 | * SYNOPSIS: Type *xnew (int n, Type); | 248 | * SYNOPSIS: Type *xnew (ptrdiff_t n, Type); |
| 239 | * void xrnew (OldPointer, int n, Type); | 249 | * void xrnew (OldPointer, ptrdiff_t n, int multiplier); |
| 240 | */ | 250 | */ |
| 241 | #define xnew(n, Type) ((Type *) xmalloc ((n) * sizeof (Type))) | 251 | #define xnew(n, Type) ((Type *) xnmalloc (n, sizeof (Type))) |
| 242 | #define xrnew(op, n, Type) ((op) = (Type *) xrealloc (op, (n) * sizeof (Type))) | 252 | #define xrnew(op, n, m) ((op) = xnrealloc (op, n, (m) * sizeof *(op))) |
| 243 | 253 | ||
| 244 | typedef void Lang_function (FILE *); | 254 | typedef void Lang_function (FILE *); |
| 245 | 255 | ||
| @@ -282,8 +292,8 @@ typedef struct node_st | |||
| 282 | bool valid; /* write this tag on the tag file */ | 292 | bool valid; /* write this tag on the tag file */ |
| 283 | bool is_func; /* function tag: use regexp in CTAGS mode */ | 293 | bool is_func; /* function tag: use regexp in CTAGS mode */ |
| 284 | bool been_warned; /* warning already given for duplicated tag */ | 294 | bool been_warned; /* warning already given for duplicated tag */ |
| 285 | int lno; /* line number tag is on */ | 295 | intmax_t lno; /* line number tag is on */ |
| 286 | long cno; /* character number line starts on */ | 296 | intmax_t cno; /* character number line starts on */ |
| 287 | } node; | 297 | } node; |
| 288 | 298 | ||
| 289 | /* | 299 | /* |
| @@ -295,8 +305,8 @@ typedef struct node_st | |||
| 295 | */ | 305 | */ |
| 296 | typedef struct | 306 | typedef struct |
| 297 | { | 307 | { |
| 298 | long size; | 308 | ptrdiff_t size; |
| 299 | int len; | 309 | ptrdiff_t len; |
| 300 | char *buffer; | 310 | char *buffer; |
| 301 | } linebuffer; | 311 | } linebuffer; |
| 302 | 312 | ||
| @@ -365,7 +375,7 @@ static void just_read_file (FILE *); | |||
| 365 | 375 | ||
| 366 | static language *get_language_from_langname (const char *); | 376 | static language *get_language_from_langname (const char *); |
| 367 | static void readline (linebuffer *, FILE *); | 377 | static void readline (linebuffer *, FILE *); |
| 368 | static long readline_internal (linebuffer *, FILE *, char const *); | 378 | static ptrdiff_t readline_internal (linebuffer *, FILE *, char const *); |
| 369 | static bool nocase_tail (const char *); | 379 | static bool nocase_tail (const char *); |
| 370 | static void get_tag (char *, char **); | 380 | static void get_tag (char *, char **); |
| 371 | static void get_lispy_tag (char *); | 381 | static void get_lispy_tag (char *); |
| @@ -385,7 +395,7 @@ static void process_file (FILE *, char *, language *); | |||
| 385 | static void find_entries (FILE *); | 395 | static void find_entries (FILE *); |
| 386 | static void free_tree (node *); | 396 | static void free_tree (node *); |
| 387 | static void free_fdesc (fdesc *); | 397 | static void free_fdesc (fdesc *); |
| 388 | static void pfnote (char *, bool, char *, int, int, long); | 398 | static void pfnote (char *, bool, char *, ptrdiff_t, intmax_t, intmax_t); |
| 389 | static void invalidate_nodes (fdesc *, node **); | 399 | static void invalidate_nodes (fdesc *, node **); |
| 390 | static void put_entries (node *); | 400 | static void put_entries (node *); |
| 391 | 401 | ||
| @@ -393,7 +403,7 @@ static char *concat (const char *, const char *, const char *); | |||
| 393 | static char *skip_spaces (char *); | 403 | static char *skip_spaces (char *); |
| 394 | static char *skip_non_spaces (char *); | 404 | static char *skip_non_spaces (char *); |
| 395 | static char *skip_name (char *); | 405 | static char *skip_name (char *); |
| 396 | static char *savenstr (const char *, int); | 406 | static char *savenstr (const char *, ptrdiff_t); |
| 397 | static char *savestr (const char *); | 407 | static char *savestr (const char *); |
| 398 | static char *etags_getcwd (void); | 408 | static char *etags_getcwd (void); |
| 399 | static char *relative_filename (char *, char *); | 409 | static char *relative_filename (char *, char *); |
| @@ -403,9 +413,11 @@ static bool filename_is_absolute (char *f); | |||
| 403 | static void canonicalize_filename (char *); | 413 | static void canonicalize_filename (char *); |
| 404 | static char *etags_mktmp (void); | 414 | static char *etags_mktmp (void); |
| 405 | static void linebuffer_init (linebuffer *); | 415 | static void linebuffer_init (linebuffer *); |
| 406 | static void linebuffer_setlen (linebuffer *, int); | 416 | static void linebuffer_setlen (linebuffer *, ptrdiff_t); |
| 407 | static void *xmalloc (size_t); | 417 | static void *xmalloc (ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1)); |
| 408 | static void *xrealloc (void *, size_t); | 418 | static void *xnmalloc (ptrdiff_t, ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1,2)); |
| 419 | static void *xnrealloc (void *, ptrdiff_t, ptrdiff_t) | ||
| 420 | ATTRIBUTE_ALLOC_SIZE ((2,3)); | ||
| 409 | 421 | ||
| 410 | 422 | ||
| 411 | static char searchar = '/'; /* use /.../ searches */ | 423 | static char searchar = '/'; /* use /.../ searches */ |
| @@ -420,12 +432,12 @@ static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */ | |||
| 420 | static fdesc *fdhead; /* head of file description list */ | 432 | static fdesc *fdhead; /* head of file description list */ |
| 421 | static fdesc *curfdp; /* current file description */ | 433 | static fdesc *curfdp; /* current file description */ |
| 422 | static char *infilename; /* current input file name */ | 434 | static char *infilename; /* current input file name */ |
| 423 | static int lineno; /* line number of current line */ | 435 | static intmax_t lineno; /* line number of current line */ |
| 424 | static long charno; /* current character number */ | 436 | static intmax_t charno; /* current character number */ |
| 425 | static long linecharno; /* charno of start of current line */ | 437 | static intmax_t linecharno; /* charno of start of current line */ |
| 426 | static char *dbp; /* pointer to start of current tag */ | 438 | static char *dbp; /* pointer to start of current tag */ |
| 427 | 439 | ||
| 428 | static const int invalidcharno = -1; | 440 | static intmax_t const invalidcharno = -1; |
| 429 | 441 | ||
| 430 | static node *nodehead; /* the head of the binary tree of tags */ | 442 | static node *nodehead; /* the head of the binary tree of tags */ |
| 431 | static node *last_node; /* the last node created */ | 443 | static node *last_node; /* the last node created */ |
| @@ -1070,7 +1082,7 @@ int | |||
| 1070 | main (int argc, char **argv) | 1082 | main (int argc, char **argv) |
| 1071 | { | 1083 | { |
| 1072 | int i; | 1084 | int i; |
| 1073 | unsigned int nincluded_files; | 1085 | int nincluded_files; |
| 1074 | char **included_files; | 1086 | char **included_files; |
| 1075 | argument *argbuffer; | 1087 | argument *argbuffer; |
| 1076 | int current_arg, file_count; | 1088 | int current_arg, file_count; |
| @@ -1484,7 +1496,7 @@ get_language_from_interpreter (char *interpreter) | |||
| 1484 | * Return a language given the file name. | 1496 | * Return a language given the file name. |
| 1485 | */ | 1497 | */ |
| 1486 | static language * | 1498 | static language * |
| 1487 | get_language_from_filename (char *file, int case_sensitive) | 1499 | get_language_from_filename (char *file, bool case_sensitive) |
| 1488 | { | 1500 | { |
| 1489 | language *lang; | 1501 | language *lang; |
| 1490 | const char **name, **ext, *suffix; | 1502 | const char **name, **ext, *suffix; |
| @@ -1918,26 +1930,26 @@ find_entries (FILE *inf) | |||
| 1918 | */ | 1930 | */ |
| 1919 | static void | 1931 | static void |
| 1920 | make_tag (const char *name, /* tag name, or NULL if unnamed */ | 1932 | make_tag (const char *name, /* tag name, or NULL if unnamed */ |
| 1921 | int namelen, /* tag length */ | 1933 | ptrdiff_t namelen, /* tag length */ |
| 1922 | bool is_func, /* tag is a function */ | 1934 | bool is_func, /* tag is a function */ |
| 1923 | char *linestart, /* start of the line where tag is */ | 1935 | char *linestart, /* start of the line where tag is */ |
| 1924 | int linelen, /* length of the line where tag is */ | 1936 | ptrdiff_t linelen, /* length of the line where tag is */ |
| 1925 | int lno, /* line number */ | 1937 | intmax_t lno, /* line number */ |
| 1926 | long int cno) /* character number */ | 1938 | intmax_t cno) /* character number */ |
| 1927 | { | 1939 | { |
| 1928 | bool named = (name != NULL && namelen > 0); | 1940 | bool named = (name != NULL && namelen > 0); |
| 1929 | char *nname = NULL; | 1941 | char *nname = NULL; |
| 1930 | 1942 | ||
| 1931 | if (debug) | 1943 | if (debug) |
| 1932 | fprintf (stderr, "%s on %s:%d: %s\n", | 1944 | fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n", |
| 1933 | named ? name : "(unnamed)", curfdp->taggedfname, lno, linestart); | 1945 | named ? name : "(unnamed)", curfdp->taggedfname, lno, linestart); |
| 1934 | 1946 | ||
| 1935 | if (!CTAGS && named) /* maybe set named to false */ | 1947 | if (!CTAGS && named) /* maybe set named to false */ |
| 1936 | /* Let's try to make an implicit tag name, that is, create an unnamed tag | 1948 | /* Let's try to make an implicit tag name, that is, create an unnamed tag |
| 1937 | such that etags.el can guess a name from it. */ | 1949 | such that etags.el can guess a name from it. */ |
| 1938 | { | 1950 | { |
| 1939 | int i; | 1951 | ptrdiff_t i; |
| 1940 | register const char *cp = name; | 1952 | const char *cp = name; |
| 1941 | 1953 | ||
| 1942 | for (i = 0; i < namelen; i++) | 1954 | for (i = 0; i < namelen; i++) |
| 1943 | if (notinname (*cp++)) | 1955 | if (notinname (*cp++)) |
| @@ -1963,8 +1975,8 @@ make_tag (const char *name, /* tag name, or NULL if unnamed */ | |||
| 1963 | 1975 | ||
| 1964 | /* Record a tag. */ | 1976 | /* Record a tag. */ |
| 1965 | static void | 1977 | static void |
| 1966 | pfnote (char *name, bool is_func, char *linestart, int linelen, int lno, | 1978 | pfnote (char *name, bool is_func, char *linestart, ptrdiff_t linelen, |
| 1967 | long int cno) | 1979 | intmax_t lno, intmax_t cno) |
| 1968 | /* tag name, or NULL if unnamed */ | 1980 | /* tag name, or NULL if unnamed */ |
| 1969 | /* tag is a function */ | 1981 | /* tag is a function */ |
| 1970 | /* start of the line where tag is */ | 1982 | /* start of the line where tag is */ |
| @@ -2197,7 +2209,8 @@ add_node (node *np, node **cur_node_p) | |||
| 2197 | if (!no_warnings) | 2209 | if (!no_warnings) |
| 2198 | { | 2210 | { |
| 2199 | fprintf (stderr, | 2211 | fprintf (stderr, |
| 2200 | "Duplicate entry in file %s, line %d: %s\n", | 2212 | ("Duplicate entry in file %s, " |
| 2213 | "line %"PRIdMAX": %s\n"), | ||
| 2201 | np->fdp->infname, lineno, np->name); | 2214 | np->fdp->infname, lineno, np->name); |
| 2202 | fprintf (stderr, "Second entry ignored\n"); | 2215 | fprintf (stderr, "Second entry ignored\n"); |
| 2203 | } | 2216 | } |
| @@ -2293,12 +2306,12 @@ invalidate_nodes (fdesc *badfdp, node **npp) | |||
| 2293 | } | 2306 | } |
| 2294 | 2307 | ||
| 2295 | 2308 | ||
| 2296 | static int total_size_of_entries (node *); | 2309 | static ptrdiff_t total_size_of_entries (node *); |
| 2297 | static int number_len (long) ATTRIBUTE_CONST; | 2310 | static int number_len (intmax_t) ATTRIBUTE_CONST; |
| 2298 | 2311 | ||
| 2299 | /* Length of a non-negative number's decimal representation. */ | 2312 | /* Length of a non-negative number's decimal representation. */ |
| 2300 | static int | 2313 | static int |
| 2301 | number_len (long int num) | 2314 | number_len (intmax_t num) |
| 2302 | { | 2315 | { |
| 2303 | int len = 1; | 2316 | int len = 1; |
| 2304 | while ((num /= 10) > 0) | 2317 | while ((num /= 10) > 0) |
| @@ -2312,10 +2325,10 @@ number_len (long int num) | |||
| 2312 | * This count is irrelevant with etags.el since emacs 19.34 at least, | 2325 | * This count is irrelevant with etags.el since emacs 19.34 at least, |
| 2313 | * but is still supplied for backward compatibility. | 2326 | * but is still supplied for backward compatibility. |
| 2314 | */ | 2327 | */ |
| 2315 | static int | 2328 | static ptrdiff_t |
| 2316 | total_size_of_entries (register node *np) | 2329 | total_size_of_entries (node *np) |
| 2317 | { | 2330 | { |
| 2318 | register int total = 0; | 2331 | ptrdiff_t total = 0; |
| 2319 | 2332 | ||
| 2320 | for (; np != NULL; np = np->right) | 2333 | for (; np != NULL; np = np->right) |
| 2321 | if (np->valid) | 2334 | if (np->valid) |
| @@ -2323,7 +2336,7 @@ total_size_of_entries (register node *np) | |||
| 2323 | total += strlen (np->regex) + 1; /* pat\177 */ | 2336 | total += strlen (np->regex) + 1; /* pat\177 */ |
| 2324 | if (np->name != NULL) | 2337 | if (np->name != NULL) |
| 2325 | total += strlen (np->name) + 1; /* name\001 */ | 2338 | total += strlen (np->name) + 1; /* name\001 */ |
| 2326 | total += number_len ((long) np->lno) + 1; /* lno, */ | 2339 | total += number_len (np->lno) + 1; /* lno, */ |
| 2327 | if (np->cno != invalidcharno) /* cno */ | 2340 | if (np->cno != invalidcharno) /* cno */ |
| 2328 | total += number_len (np->cno); | 2341 | total += number_len (np->cno); |
| 2329 | total += 1; /* newline */ | 2342 | total += 1; /* newline */ |
| @@ -2347,7 +2360,7 @@ put_entry (node *np) | |||
| 2347 | if (fdp != np->fdp) | 2360 | if (fdp != np->fdp) |
| 2348 | { | 2361 | { |
| 2349 | fdp = np->fdp; | 2362 | fdp = np->fdp; |
| 2350 | fprintf (tagf, "\f\n%s,%d\n", | 2363 | fprintf (tagf, "\f\n%s,%"PRIdPTR"\n", |
| 2351 | fdp->taggedfname, total_size_of_entries (np)); | 2364 | fdp->taggedfname, total_size_of_entries (np)); |
| 2352 | fdp->written = true; | 2365 | fdp->written = true; |
| 2353 | } | 2366 | } |
| @@ -2358,9 +2371,9 @@ put_entry (node *np) | |||
| 2358 | fputs (np->name, tagf); | 2371 | fputs (np->name, tagf); |
| 2359 | fputc ('\001', tagf); | 2372 | fputc ('\001', tagf); |
| 2360 | } | 2373 | } |
| 2361 | fprintf (tagf, "%d,", np->lno); | 2374 | fprintf (tagf, "%"PRIdMAX",", np->lno); |
| 2362 | if (np->cno != invalidcharno) | 2375 | if (np->cno != invalidcharno) |
| 2363 | fprintf (tagf, "%ld", np->cno); | 2376 | fprintf (tagf, "%"PRIdMAX, np->cno); |
| 2364 | fputs ("\n", tagf); | 2377 | fputs ("\n", tagf); |
| 2365 | } | 2378 | } |
| 2366 | else | 2379 | else |
| @@ -2372,10 +2385,10 @@ put_entry (node *np) | |||
| 2372 | if (cxref_style) | 2385 | if (cxref_style) |
| 2373 | { | 2386 | { |
| 2374 | if (vgrind_style) | 2387 | if (vgrind_style) |
| 2375 | fprintf (stdout, "%s %s %d\n", | 2388 | fprintf (stdout, "%s %s %"PRIdMAX"\n", |
| 2376 | np->name, np->fdp->taggedfname, (np->lno + 63) / 64); | 2389 | np->name, np->fdp->taggedfname, (np->lno + 63) / 64); |
| 2377 | else | 2390 | else |
| 2378 | fprintf (stdout, "%-16s %3d %-16s %s\n", | 2391 | fprintf (stdout, "%-16s %3"PRIdMAX" %-16s %s\n", |
| 2379 | np->name, np->lno, np->fdp->taggedfname, np->regex); | 2392 | np->name, np->lno, np->fdp->taggedfname, np->regex); |
| 2380 | } | 2393 | } |
| 2381 | else | 2394 | else |
| @@ -2397,7 +2410,7 @@ put_entry (node *np) | |||
| 2397 | } | 2410 | } |
| 2398 | else | 2411 | else |
| 2399 | { /* anything else; text pattern inadequate */ | 2412 | { /* anything else; text pattern inadequate */ |
| 2400 | fprintf (tagf, "%d", np->lno); | 2413 | fprintf (tagf, "%"PRIdMAX, np->lno); |
| 2401 | } | 2414 | } |
| 2402 | putc ('\n', tagf); | 2415 | putc ('\n', tagf); |
| 2403 | } | 2416 | } |
| @@ -2591,7 +2604,7 @@ hash (const char *str, int len) | |||
| 2591 | } | 2604 | } |
| 2592 | 2605 | ||
| 2593 | static struct C_stab_entry * | 2606 | static struct C_stab_entry * |
| 2594 | in_word_set (register const char *str, register unsigned int len) | 2607 | in_word_set (const char *str, ptrdiff_t len) |
| 2595 | { | 2608 | { |
| 2596 | enum | 2609 | enum |
| 2597 | { | 2610 | { |
| @@ -2658,9 +2671,9 @@ in_word_set (register const char *str, register unsigned int len) | |||
| 2658 | /*%>*/ | 2671 | /*%>*/ |
| 2659 | 2672 | ||
| 2660 | static enum sym_type | 2673 | static enum sym_type |
| 2661 | C_symtype (char *str, int len, int c_ext) | 2674 | C_symtype (char *str, ptrdiff_t len, int c_ext) |
| 2662 | { | 2675 | { |
| 2663 | register struct C_stab_entry *se = in_word_set (str, len); | 2676 | struct C_stab_entry *se = in_word_set (str, len); |
| 2664 | 2677 | ||
| 2665 | if (se == NULL || (se->c_ext && !(c_ext & se->c_ext))) | 2678 | if (se == NULL || (se->c_ext && !(c_ext & se->c_ext))) |
| 2666 | return st_none; | 2679 | return st_none; |
| @@ -2770,8 +2783,8 @@ static enum | |||
| 2770 | static struct tok | 2783 | static struct tok |
| 2771 | { | 2784 | { |
| 2772 | char *line; /* string containing the token */ | 2785 | char *line; /* string containing the token */ |
| 2773 | int offset; /* where the token starts in LINE */ | 2786 | ptrdiff_t offset; /* where the token starts in LINE */ |
| 2774 | int length; /* token length */ | 2787 | ptrdiff_t length; /* token length */ |
| 2775 | /* | 2788 | /* |
| 2776 | The previous members can be used to pass strings around for generic | 2789 | The previous members can be used to pass strings around for generic |
| 2777 | purposes. The following ones specifically refer to creating tags. In this | 2790 | purposes. The following ones specifically refer to creating tags. In this |
| @@ -2782,23 +2795,23 @@ static struct tok | |||
| 2782 | invalidated whenever a state machine is | 2795 | invalidated whenever a state machine is |
| 2783 | reset prematurely */ | 2796 | reset prematurely */ |
| 2784 | bool named; /* create a named tag */ | 2797 | bool named; /* create a named tag */ |
| 2785 | int lineno; /* source line number of tag */ | 2798 | intmax_t lineno; /* source line number of tag */ |
| 2786 | long linepos; /* source char number of tag */ | 2799 | intmax_t linepos; /* source char number of tag */ |
| 2787 | } token; /* latest token read */ | 2800 | } token; /* latest token read */ |
| 2788 | 2801 | ||
| 2789 | /* | 2802 | /* |
| 2790 | * Variables and functions for dealing with nested structures. | 2803 | * Variables and functions for dealing with nested structures. |
| 2791 | * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001) | 2804 | * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001) |
| 2792 | */ | 2805 | */ |
| 2793 | static void pushclass_above (int, char *, int); | 2806 | static void pushclass_above (ptrdiff_t, char *, ptrdiff_t); |
| 2794 | static void popclass_above (int); | 2807 | static void popclass_above (ptrdiff_t); |
| 2795 | static void write_classname (linebuffer *, const char *qualifier); | 2808 | static void write_classname (linebuffer *, const char *qualifier); |
| 2796 | 2809 | ||
| 2797 | static struct { | 2810 | static struct { |
| 2798 | char **cname; /* nested class names */ | 2811 | char **cname; /* nested class names */ |
| 2799 | int *bracelev; /* nested class brace level */ | 2812 | ptrdiff_t *bracelev; /* nested class brace level */ |
| 2800 | int nl; /* class nesting level (elements used) */ | 2813 | ptrdiff_t nl; /* class nesting level (elements used) */ |
| 2801 | int size; /* length of the array */ | 2814 | ptrdiff_t size; /* length of the array */ |
| 2802 | } cstack; /* stack for nested declaration tags */ | 2815 | } cstack; /* stack for nested declaration tags */ |
| 2803 | /* Current struct nesting depth (namespace, class, struct, union, enum). */ | 2816 | /* Current struct nesting depth (namespace, class, struct, union, enum). */ |
| 2804 | #define nestlev (cstack.nl) | 2817 | #define nestlev (cstack.nl) |
| @@ -2807,17 +2820,17 @@ static struct { | |||
| 2807 | && bracelev == cstack.bracelev[nestlev-1] + 1) | 2820 | && bracelev == cstack.bracelev[nestlev-1] + 1) |
| 2808 | 2821 | ||
| 2809 | static void | 2822 | static void |
| 2810 | pushclass_above (int bracelev, char *str, int len) | 2823 | pushclass_above (ptrdiff_t bracelev, char *str, ptrdiff_t len) |
| 2811 | { | 2824 | { |
| 2812 | int nl; | 2825 | ptrdiff_t nl; |
| 2813 | 2826 | ||
| 2814 | popclass_above (bracelev); | 2827 | popclass_above (bracelev); |
| 2815 | nl = cstack.nl; | 2828 | nl = cstack.nl; |
| 2816 | if (nl >= cstack.size) | 2829 | if (nl >= cstack.size) |
| 2817 | { | 2830 | { |
| 2818 | int size = cstack.size *= 2; | 2831 | xrnew (cstack.cname, cstack.size, 2); |
| 2819 | xrnew (cstack.cname, size, char *); | 2832 | xrnew (cstack.bracelev, cstack.size, 2); |
| 2820 | xrnew (cstack.bracelev, size, int); | 2833 | cstack.size *= 2; |
| 2821 | } | 2834 | } |
| 2822 | assert (nl == 0 || cstack.bracelev[nl-1] < bracelev); | 2835 | assert (nl == 0 || cstack.bracelev[nl-1] < bracelev); |
| 2823 | cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len); | 2836 | cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len); |
| @@ -2826,11 +2839,9 @@ pushclass_above (int bracelev, char *str, int len) | |||
| 2826 | } | 2839 | } |
| 2827 | 2840 | ||
| 2828 | static void | 2841 | static void |
| 2829 | popclass_above (int bracelev) | 2842 | popclass_above (ptrdiff_t bracelev) |
| 2830 | { | 2843 | { |
| 2831 | int nl; | 2844 | for (ptrdiff_t nl = cstack.nl - 1; |
| 2832 | |||
| 2833 | for (nl = cstack.nl - 1; | ||
| 2834 | nl >= 0 && cstack.bracelev[nl] >= bracelev; | 2845 | nl >= 0 && cstack.bracelev[nl] >= bracelev; |
| 2835 | nl--) | 2846 | nl--) |
| 2836 | { | 2847 | { |
| @@ -2842,8 +2853,7 @@ popclass_above (int bracelev) | |||
| 2842 | static void | 2853 | static void |
| 2843 | write_classname (linebuffer *cn, const char *qualifier) | 2854 | write_classname (linebuffer *cn, const char *qualifier) |
| 2844 | { | 2855 | { |
| 2845 | int i, len; | 2856 | ptrdiff_t len; |
| 2846 | int qlen = strlen (qualifier); | ||
| 2847 | 2857 | ||
| 2848 | if (cstack.nl == 0 || cstack.cname[0] == NULL) | 2858 | if (cstack.nl == 0 || cstack.cname[0] == NULL) |
| 2849 | { | 2859 | { |
| @@ -2857,18 +2867,22 @@ write_classname (linebuffer *cn, const char *qualifier) | |||
| 2857 | linebuffer_setlen (cn, len); | 2867 | linebuffer_setlen (cn, len); |
| 2858 | strcpy (cn->buffer, cstack.cname[0]); | 2868 | strcpy (cn->buffer, cstack.cname[0]); |
| 2859 | } | 2869 | } |
| 2860 | for (i = 1; i < cstack.nl; i++) | 2870 | for (ptrdiff_t i = 1; i < cstack.nl; i++) |
| 2861 | { | 2871 | { |
| 2862 | char *s = cstack.cname[i]; | 2872 | char *s = cstack.cname[i]; |
| 2863 | if (s == NULL) | 2873 | if (s == NULL) |
| 2864 | continue; | 2874 | continue; |
| 2865 | linebuffer_setlen (cn, len + qlen + strlen (s)); | 2875 | int qlen = strlen (qualifier); |
| 2866 | len += sprintf (cn->buffer + len, "%s%s", qualifier, s); | 2876 | ptrdiff_t slen = strlen (s); |
| 2877 | linebuffer_setlen (cn, len + qlen + slen); | ||
| 2878 | memcpyz (stpcpy (cn->buffer + len, qualifier), s, slen); | ||
| 2879 | len += qlen + slen; | ||
| 2867 | } | 2880 | } |
| 2868 | } | 2881 | } |
| 2869 | 2882 | ||
| 2870 | 2883 | ||
| 2871 | static bool consider_token (char *, int, int, int *, int, int, bool *); | 2884 | static bool consider_token (char *, ptrdiff_t, int, int *, |
| 2885 | ptrdiff_t, ptrdiff_t, bool *); | ||
| 2872 | static void make_C_tag (bool); | 2886 | static void make_C_tag (bool); |
| 2873 | 2887 | ||
| 2874 | /* | 2888 | /* |
| @@ -2889,8 +2903,8 @@ static void make_C_tag (bool); | |||
| 2889 | */ | 2903 | */ |
| 2890 | 2904 | ||
| 2891 | static bool | 2905 | static bool |
| 2892 | consider_token (char *str, int len, int c, int *c_extp, | 2906 | consider_token (char *str, ptrdiff_t len, int c, int *c_extp, |
| 2893 | int bracelev, int parlev, bool *is_func_or_var) | 2907 | ptrdiff_t bracelev, ptrdiff_t parlev, bool *is_func_or_var) |
| 2894 | /* IN: token pointer */ | 2908 | /* IN: token pointer */ |
| 2895 | /* IN: token length */ | 2909 | /* IN: token length */ |
| 2896 | /* IN: first char after the token */ | 2910 | /* IN: first char after the token */ |
| @@ -2903,7 +2917,7 @@ consider_token (char *str, int len, int c, int *c_extp, | |||
| 2903 | structtype is the type of the preceding struct-like keyword, and | 2917 | structtype is the type of the preceding struct-like keyword, and |
| 2904 | structbracelev is the brace level where it has been seen. */ | 2918 | structbracelev is the brace level where it has been seen. */ |
| 2905 | static enum sym_type structtype; | 2919 | static enum sym_type structtype; |
| 2906 | static int structbracelev; | 2920 | static ptrdiff_t structbracelev; |
| 2907 | static enum sym_type toktype; | 2921 | static enum sym_type toktype; |
| 2908 | 2922 | ||
| 2909 | 2923 | ||
| @@ -3098,8 +3112,7 @@ consider_token (char *str, int len, int c, int *c_extp, | |||
| 3098 | fvdef = fvnone; | 3112 | fvdef = fvnone; |
| 3099 | objdef = omethodtag; | 3113 | objdef = omethodtag; |
| 3100 | linebuffer_setlen (&token_name, len); | 3114 | linebuffer_setlen (&token_name, len); |
| 3101 | memcpy (token_name.buffer, str, len); | 3115 | memcpyz (token_name.buffer, str, len); |
| 3102 | token_name.buffer[len] = '\0'; | ||
| 3103 | return true; | 3116 | return true; |
| 3104 | } | 3117 | } |
| 3105 | return false; | 3118 | return false; |
| @@ -3113,11 +3126,10 @@ consider_token (char *str, int len, int c, int *c_extp, | |||
| 3113 | objdef = omethodtag; | 3126 | objdef = omethodtag; |
| 3114 | if (class_qualify) | 3127 | if (class_qualify) |
| 3115 | { | 3128 | { |
| 3116 | int oldlen = token_name.len; | 3129 | ptrdiff_t oldlen = token_name.len; |
| 3117 | fvdef = fvnone; | 3130 | fvdef = fvnone; |
| 3118 | linebuffer_setlen (&token_name, oldlen + len); | 3131 | linebuffer_setlen (&token_name, oldlen + len); |
| 3119 | memcpy (token_name.buffer + oldlen, str, len); | 3132 | memcpyz (token_name.buffer + oldlen, str, len); |
| 3120 | token_name.buffer[oldlen + len] = '\0'; | ||
| 3121 | } | 3133 | } |
| 3122 | return true; | 3134 | return true; |
| 3123 | } | 3135 | } |
| @@ -3228,7 +3240,7 @@ consider_token (char *str, int len, int c, int *c_extp, | |||
| 3228 | */ | 3240 | */ |
| 3229 | static struct | 3241 | static struct |
| 3230 | { | 3242 | { |
| 3231 | long linepos; | 3243 | intmax_t linepos; |
| 3232 | linebuffer lb; | 3244 | linebuffer lb; |
| 3233 | } lbs[2]; | 3245 | } lbs[2]; |
| 3234 | 3246 | ||
| @@ -3302,19 +3314,19 @@ C_entries (int c_ext, FILE *inf) | |||
| 3302 | /* extension of C */ | 3314 | /* extension of C */ |
| 3303 | /* input file */ | 3315 | /* input file */ |
| 3304 | { | 3316 | { |
| 3305 | register char c; /* latest char read; '\0' for end of line */ | 3317 | char c; /* latest char read; '\0' for end of line */ |
| 3306 | register char *lp; /* pointer one beyond the character `c' */ | 3318 | char *lp; /* pointer one beyond the character `c' */ |
| 3307 | int curndx, newndx; /* indices for current and new lb */ | 3319 | bool curndx, newndx; /* indices for current and new lb */ |
| 3308 | register int tokoff; /* offset in line of start of current token */ | 3320 | ptrdiff_t tokoff; /* offset in line of start of current token */ |
| 3309 | register int toklen; /* length of current token */ | 3321 | ptrdiff_t toklen; /* length of current token */ |
| 3310 | const char *qualifier; /* string used to qualify names */ | 3322 | const char *qualifier; /* string used to qualify names */ |
| 3311 | int qlen; /* length of qualifier */ | 3323 | int qlen; /* length of qualifier */ |
| 3312 | int bracelev; /* current brace level */ | 3324 | ptrdiff_t bracelev; /* current brace level */ |
| 3313 | int bracketlev; /* current bracket level */ | 3325 | ptrdiff_t bracketlev; /* current bracket level */ |
| 3314 | int parlev; /* current parenthesis level */ | 3326 | ptrdiff_t parlev; /* current parenthesis level */ |
| 3315 | int attrparlev; /* __attribute__ parenthesis level */ | 3327 | ptrdiff_t attrparlev; /* __attribute__ parenthesis level */ |
| 3316 | int templatelev; /* current template level */ | 3328 | ptrdiff_t templatelev; /* current template level */ |
| 3317 | int typdefbracelev; /* bracelev where a typedef struct body begun */ | 3329 | ptrdiff_t typdefbracelev; /* bracelev where a typedef struct body begun */ |
| 3318 | bool incomm, inquote, inchar, quotednl, midtoken; | 3330 | bool incomm, inquote, inchar, quotednl, midtoken; |
| 3319 | bool yacc_rules; /* in the rules part of a yacc file */ | 3331 | bool yacc_rules; /* in the rules part of a yacc file */ |
| 3320 | struct tok savetoken = {0}; /* token saved during preprocessor handling */ | 3332 | struct tok savetoken = {0}; /* token saved during preprocessor handling */ |
| @@ -3327,7 +3339,7 @@ C_entries (int c_ext, FILE *inf) | |||
| 3327 | cstack.size = (DEBUG) ? 1 : 4; | 3339 | cstack.size = (DEBUG) ? 1 : 4; |
| 3328 | cstack.nl = 0; | 3340 | cstack.nl = 0; |
| 3329 | cstack.cname = xnew (cstack.size, char *); | 3341 | cstack.cname = xnew (cstack.size, char *); |
| 3330 | cstack.bracelev = xnew (cstack.size, int); | 3342 | cstack.bracelev = xnew (cstack.size, ptrdiff_t); |
| 3331 | } | 3343 | } |
| 3332 | 3344 | ||
| 3333 | tokoff = toklen = typdefbracelev = 0; /* keep compiler quiet */ | 3345 | tokoff = toklen = typdefbracelev = 0; /* keep compiler quiet */ |
| @@ -3579,20 +3591,19 @@ C_entries (int c_ext, FILE *inf) | |||
| 3579 | { | 3591 | { |
| 3580 | if (class_qualify) | 3592 | if (class_qualify) |
| 3581 | { | 3593 | { |
| 3582 | int len; | ||
| 3583 | write_classname (&token_name, qualifier); | 3594 | write_classname (&token_name, qualifier); |
| 3584 | len = token_name.len; | 3595 | ptrdiff_t len = token_name.len; |
| 3585 | linebuffer_setlen (&token_name, | 3596 | linebuffer_setlen (&token_name, |
| 3586 | len + qlen + toklen); | 3597 | len + qlen + toklen); |
| 3587 | sprintf (token_name.buffer + len, "%s%.*s", | 3598 | memcpyz (stpcpy (token_name.buffer + len, |
| 3588 | qualifier, toklen, | 3599 | qualifier), |
| 3589 | newlb.buffer + tokoff); | 3600 | newlb.buffer + tokoff, toklen); |
| 3590 | } | 3601 | } |
| 3591 | else | 3602 | else |
| 3592 | { | 3603 | { |
| 3593 | linebuffer_setlen (&token_name, toklen); | 3604 | linebuffer_setlen (&token_name, toklen); |
| 3594 | sprintf (token_name.buffer, "%.*s", | 3605 | memcpyz (token_name.buffer, |
| 3595 | toklen, newlb.buffer + tokoff); | 3606 | newlb.buffer + tokoff, toklen); |
| 3596 | } | 3607 | } |
| 3597 | token.named = true; | 3608 | token.named = true; |
| 3598 | } | 3609 | } |
| @@ -3601,17 +3612,19 @@ C_entries (int c_ext, FILE *inf) | |||
| 3601 | { | 3612 | { |
| 3602 | if (class_qualify) | 3613 | if (class_qualify) |
| 3603 | { | 3614 | { |
| 3604 | int len = strlen (objtag) + 2 + toklen; | 3615 | ptrdiff_t len = strlen (objtag) + 2 + toklen; |
| 3605 | linebuffer_setlen (&token_name, len); | 3616 | linebuffer_setlen (&token_name, len); |
| 3606 | sprintf (token_name.buffer, "%s(%.*s)", | 3617 | char *p1 = stpcpy (token_name.buffer, objtag); |
| 3607 | objtag, toklen, | 3618 | char *p2 = stpcpy (p1, "("); |
| 3608 | newlb.buffer + tokoff); | 3619 | char *p3 = mempcpy (p2, newlb.buffer + tokoff, |
| 3620 | toklen); | ||
| 3621 | strcpy (p3, ")"); | ||
| 3609 | } | 3622 | } |
| 3610 | else | 3623 | else |
| 3611 | { | 3624 | { |
| 3612 | linebuffer_setlen (&token_name, toklen); | 3625 | linebuffer_setlen (&token_name, toklen); |
| 3613 | sprintf (token_name.buffer, "%.*s", | 3626 | memcpyz (token_name.buffer, |
| 3614 | toklen, newlb.buffer + tokoff); | 3627 | newlb.buffer + tokoff, toklen); |
| 3615 | } | 3628 | } |
| 3616 | token.named = true; | 3629 | token.named = true; |
| 3617 | } | 3630 | } |
| @@ -3625,8 +3638,8 @@ C_entries (int c_ext, FILE *inf) | |||
| 3625 | /* GNU DEFUN and similar macros */ | 3638 | /* GNU DEFUN and similar macros */ |
| 3626 | { | 3639 | { |
| 3627 | bool defun = (newlb.buffer[tokoff] == 'F'); | 3640 | bool defun = (newlb.buffer[tokoff] == 'F'); |
| 3628 | int off = tokoff; | 3641 | ptrdiff_t off = tokoff; |
| 3629 | int len = toklen; | 3642 | ptrdiff_t len = toklen; |
| 3630 | 3643 | ||
| 3631 | if (defun) | 3644 | if (defun) |
| 3632 | { | 3645 | { |
| @@ -3635,9 +3648,8 @@ C_entries (int c_ext, FILE *inf) | |||
| 3635 | 3648 | ||
| 3636 | /* First, tag it as its C name */ | 3649 | /* First, tag it as its C name */ |
| 3637 | linebuffer_setlen (&token_name, toklen); | 3650 | linebuffer_setlen (&token_name, toklen); |
| 3638 | memcpy (token_name.buffer, | 3651 | memcpyz (token_name.buffer, |
| 3639 | newlb.buffer + tokoff, toklen); | 3652 | newlb.buffer + tokoff, toklen); |
| 3640 | token_name.buffer[toklen] = '\0'; | ||
| 3641 | token.named = true; | 3653 | token.named = true; |
| 3642 | token.lineno = lineno; | 3654 | token.lineno = lineno; |
| 3643 | token.offset = tokoff; | 3655 | token.offset = tokoff; |
| @@ -3650,9 +3662,8 @@ C_entries (int c_ext, FILE *inf) | |||
| 3650 | /* Rewrite the tag so that emacs lisp DEFUNs | 3662 | /* Rewrite the tag so that emacs lisp DEFUNs |
| 3651 | can be found also by their elisp name */ | 3663 | can be found also by their elisp name */ |
| 3652 | linebuffer_setlen (&token_name, len); | 3664 | linebuffer_setlen (&token_name, len); |
| 3653 | memcpy (token_name.buffer, | 3665 | memcpyz (token_name.buffer, |
| 3654 | newlb.buffer + off, len); | 3666 | newlb.buffer + off, len); |
| 3655 | token_name.buffer[len] = '\0'; | ||
| 3656 | if (defun) | 3667 | if (defun) |
| 3657 | while (--len >= 0) | 3668 | while (--len >= 0) |
| 3658 | if (token_name.buffer[len] == '_') | 3669 | if (token_name.buffer[len] == '_') |
| @@ -3662,9 +3673,8 @@ C_entries (int c_ext, FILE *inf) | |||
| 3662 | else | 3673 | else |
| 3663 | { | 3674 | { |
| 3664 | linebuffer_setlen (&token_name, toklen); | 3675 | linebuffer_setlen (&token_name, toklen); |
| 3665 | memcpy (token_name.buffer, | 3676 | memcpyz (token_name.buffer, |
| 3666 | newlb.buffer + tokoff, toklen); | 3677 | newlb.buffer + tokoff, toklen); |
| 3667 | token_name.buffer[toklen] = '\0'; | ||
| 3668 | /* Name macros and members. */ | 3678 | /* Name macros and members. */ |
| 3669 | token.named = (structdef == stagseen | 3679 | token.named = (structdef == stagseen |
| 3670 | || typdef == ttypeseen | 3680 | || typdef == ttypeseen |
| @@ -3790,7 +3800,7 @@ C_entries (int c_ext, FILE *inf) | |||
| 3790 | objdef = omethodcolon; | 3800 | objdef = omethodcolon; |
| 3791 | if (class_qualify) | 3801 | if (class_qualify) |
| 3792 | { | 3802 | { |
| 3793 | int toklen = token_name.len; | 3803 | ptrdiff_t toklen = token_name.len; |
| 3794 | linebuffer_setlen (&token_name, toklen + 1); | 3804 | linebuffer_setlen (&token_name, toklen + 1); |
| 3795 | strcpy (token_name.buffer + toklen, ":"); | 3805 | strcpy (token_name.buffer + toklen, ":"); |
| 3796 | } | 3806 | } |
| @@ -4061,7 +4071,7 @@ C_entries (int c_ext, FILE *inf) | |||
| 4061 | } | 4071 | } |
| 4062 | if (uqname > token_name.buffer) | 4072 | if (uqname > token_name.buffer) |
| 4063 | { | 4073 | { |
| 4064 | int uqlen = strlen (uqname); | 4074 | ptrdiff_t uqlen = strlen (uqname); |
| 4065 | linebuffer_setlen (&token_name, uqlen); | 4075 | linebuffer_setlen (&token_name, uqlen); |
| 4066 | memmove (token_name.buffer, uqname, uqlen + 1); | 4076 | memmove (token_name.buffer, uqname, uqlen + 1); |
| 4067 | } | 4077 | } |
| @@ -4979,12 +4989,11 @@ Ruby_functions (FILE *inf) | |||
| 4979 | size_t name_len = cp - np + 1; | 4989 | size_t name_len = cp - np + 1; |
| 4980 | char *wr_name = xnew (name_len + 1, char); | 4990 | char *wr_name = xnew (name_len + 1, char); |
| 4981 | 4991 | ||
| 4982 | memcpy (wr_name, np, name_len - 1); | 4992 | strcpy (mempcpy (wr_name, np, name_len - 1), "="); |
| 4983 | memcpy (wr_name + name_len - 1, "=", 2); | ||
| 4984 | pfnote (wr_name, true, lb.buffer, cp - lb.buffer + 1, | 4993 | pfnote (wr_name, true, lb.buffer, cp - lb.buffer + 1, |
| 4985 | lineno, linecharno); | 4994 | lineno, linecharno); |
| 4986 | if (debug) | 4995 | if (debug) |
| 4987 | fprintf (stderr, "%s on %s:%d: %s\n", wr_name, | 4996 | fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n", wr_name, |
| 4988 | curfdp->taggedfname, lineno, lb.buffer); | 4997 | curfdp->taggedfname, lineno, lb.buffer); |
| 4989 | continuation = false; | 4998 | continuation = false; |
| 4990 | } | 4999 | } |
| @@ -5178,8 +5187,8 @@ static void | |||
| 5178 | Pascal_functions (FILE *inf) | 5187 | Pascal_functions (FILE *inf) |
| 5179 | { | 5188 | { |
| 5180 | linebuffer tline; /* mostly copied from C_entries */ | 5189 | linebuffer tline; /* mostly copied from C_entries */ |
| 5181 | long save_lcno; | 5190 | intmax_t save_lcno, save_lineno; |
| 5182 | int save_lineno, namelen, taglen; | 5191 | ptrdiff_t namelen, taglen; |
| 5183 | char c, *name; | 5192 | char c, *name; |
| 5184 | 5193 | ||
| 5185 | bool /* each of these flags is true if: */ | 5194 | bool /* each of these flags is true if: */ |
| @@ -5455,7 +5464,7 @@ Lua_functions (FILE *inf) | |||
| 5455 | if (tp_dot || tp_colon) | 5464 | if (tp_dot || tp_colon) |
| 5456 | { | 5465 | { |
| 5457 | char *p = tp_dot > tp_colon ? tp_dot : tp_colon; | 5466 | char *p = tp_dot > tp_colon ? tp_dot : tp_colon; |
| 5458 | int len_add = p - tag_name + 1; | 5467 | ptrdiff_t len_add = p - tag_name + 1; |
| 5459 | 5468 | ||
| 5460 | get_tag (bp + len_add, NULL); | 5469 | get_tag (bp + len_add, NULL); |
| 5461 | } | 5470 | } |
| @@ -5656,7 +5665,7 @@ TeX_commands (FILE *inf) | |||
| 5656 | if (strneq (cp, key->buffer, key->len)) | 5665 | if (strneq (cp, key->buffer, key->len)) |
| 5657 | { | 5666 | { |
| 5658 | char *p; | 5667 | char *p; |
| 5659 | int namelen, linelen; | 5668 | ptrdiff_t namelen, linelen; |
| 5660 | bool opgrp = false; | 5669 | bool opgrp = false; |
| 5661 | 5670 | ||
| 5662 | cp = skip_spaces (cp + key->len); | 5671 | cp = skip_spaces (cp + key->len); |
| @@ -5693,8 +5702,8 @@ TeX_commands (FILE *inf) | |||
| 5693 | static void | 5702 | static void |
| 5694 | TEX_decode_env (const char *evarname, const char *defenv) | 5703 | TEX_decode_env (const char *evarname, const char *defenv) |
| 5695 | { | 5704 | { |
| 5696 | register const char *env, *p; | 5705 | const char *env, *p; |
| 5697 | int i, len; | 5706 | ptrdiff_t len; |
| 5698 | 5707 | ||
| 5699 | /* Append default string to environment. */ | 5708 | /* Append default string to environment. */ |
| 5700 | env = getenv (evarname); | 5709 | env = getenv (evarname); |
| @@ -5711,7 +5720,7 @@ TEX_decode_env (const char *evarname, const char *defenv) | |||
| 5711 | 5720 | ||
| 5712 | /* Unpack environment string into token table. Be careful about */ | 5721 | /* Unpack environment string into token table. Be careful about */ |
| 5713 | /* zero-length strings (leading ':', "::" and trailing ':') */ | 5722 | /* zero-length strings (leading ':', "::" and trailing ':') */ |
| 5714 | for (i = 0; *env != '\0';) | 5723 | for (ptrdiff_t i = 0; *env != '\0'; ) |
| 5715 | { | 5724 | { |
| 5716 | p = strchr (env, ':'); | 5725 | p = strchr (env, ':'); |
| 5717 | if (!p) /* End of environment string. */ | 5726 | if (!p) /* End of environment string. */ |
| @@ -5811,8 +5820,7 @@ HTML_labels (FILE *inf) | |||
| 5811 | for (end = dbp; *end != '\0' && intoken (*end); end++) | 5820 | for (end = dbp; *end != '\0' && intoken (*end); end++) |
| 5812 | continue; | 5821 | continue; |
| 5813 | linebuffer_setlen (&token_name, end - dbp); | 5822 | linebuffer_setlen (&token_name, end - dbp); |
| 5814 | memcpy (token_name.buffer, dbp, end - dbp); | 5823 | memcpyz (token_name.buffer, dbp, end - dbp); |
| 5815 | token_name.buffer[end - dbp] = '\0'; | ||
| 5816 | 5824 | ||
| 5817 | dbp = end; | 5825 | dbp = end; |
| 5818 | intag = false; /* we found what we looked for */ | 5826 | intag = false; /* we found what we looked for */ |
| @@ -5906,11 +5914,10 @@ Prolog_functions (FILE *inf) | |||
| 5906 | tags later. */ | 5914 | tags later. */ |
| 5907 | if (allocated <= len) | 5915 | if (allocated <= len) |
| 5908 | { | 5916 | { |
| 5909 | xrnew (last, len + 1, char); | 5917 | xrnew (last, len + 1, 1); |
| 5910 | allocated = len + 1; | 5918 | allocated = len + 1; |
| 5911 | } | 5919 | } |
| 5912 | memcpy (last, cp, len); | 5920 | memcpyz (last, cp, len); |
| 5913 | last[len] = '\0'; | ||
| 5914 | lastlen = len; | 5921 | lastlen = len; |
| 5915 | } | 5922 | } |
| 5916 | } | 5923 | } |
| @@ -6031,9 +6038,9 @@ prolog_atom (char *s, size_t pos) | |||
| 6031 | * Assumes that Erlang functions start at column 0. | 6038 | * Assumes that Erlang functions start at column 0. |
| 6032 | * Original code by Anders Lindgren (1996) | 6039 | * Original code by Anders Lindgren (1996) |
| 6033 | */ | 6040 | */ |
| 6034 | static int erlang_func (char *, char *, ptrdiff_t, ptrdiff_t *); | 6041 | static ptrdiff_t erlang_func (char *, char *, ptrdiff_t, ptrdiff_t *); |
| 6035 | static void erlang_attribute (char *); | 6042 | static void erlang_attribute (char *); |
| 6036 | static int erlang_atom (char *); | 6043 | static ptrdiff_t erlang_atom (char *); |
| 6037 | 6044 | ||
| 6038 | static void | 6045 | static void |
| 6039 | Erlang_functions (FILE *inf) | 6046 | Erlang_functions (FILE *inf) |
| @@ -6070,11 +6077,10 @@ Erlang_functions (FILE *inf) | |||
| 6070 | tags later. */ | 6077 | tags later. */ |
| 6071 | if (allocated <= len) | 6078 | if (allocated <= len) |
| 6072 | { | 6079 | { |
| 6073 | xrnew (last, len + 1, char); | 6080 | xrnew (last, len + 1, 1); |
| 6074 | allocated = len + 1; | 6081 | allocated = len + 1; |
| 6075 | } | 6082 | } |
| 6076 | memcpy (last, cp + name_offset, len); | 6083 | memcpyz (last, cp + name_offset, len); |
| 6077 | last[len] = '\0'; | ||
| 6078 | lastlen = len; | 6084 | lastlen = len; |
| 6079 | } | 6085 | } |
| 6080 | } | 6086 | } |
| @@ -6093,7 +6099,7 @@ Erlang_functions (FILE *inf) | |||
| 6093 | * Return the size of the name of the function, or 0 if no function | 6099 | * Return the size of the name of the function, or 0 if no function |
| 6094 | * was found. | 6100 | * was found. |
| 6095 | */ | 6101 | */ |
| 6096 | static int | 6102 | static ptrdiff_t |
| 6097 | erlang_func (char *s, char *last, ptrdiff_t lastlen, ptrdiff_t *name_offset) | 6103 | erlang_func (char *s, char *last, ptrdiff_t lastlen, ptrdiff_t *name_offset) |
| 6098 | { | 6104 | { |
| 6099 | char *name = s; | 6105 | char *name = s; |
| @@ -6133,15 +6139,13 @@ static void | |||
| 6133 | erlang_attribute (char *s) | 6139 | erlang_attribute (char *s) |
| 6134 | { | 6140 | { |
| 6135 | char *cp = s; | 6141 | char *cp = s; |
| 6136 | int pos; | ||
| 6137 | int len; | ||
| 6138 | 6142 | ||
| 6139 | if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record")) | 6143 | if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record")) |
| 6140 | && *cp++ == '(') | 6144 | && *cp++ == '(') |
| 6141 | { | 6145 | { |
| 6142 | cp = skip_spaces (cp); | 6146 | cp = skip_spaces (cp); |
| 6143 | len = erlang_atom (cp); | 6147 | ptrdiff_t len = erlang_atom (cp); |
| 6144 | pos = cp + len - s; | 6148 | ptrdiff_t pos = cp + len - s; |
| 6145 | if (len > 0) | 6149 | if (len > 0) |
| 6146 | { | 6150 | { |
| 6147 | /* If the name is quoted, the quotes are not part of the name. */ | 6151 | /* If the name is quoted, the quotes are not part of the name. */ |
| @@ -6161,10 +6165,10 @@ erlang_attribute (char *s) | |||
| 6161 | * Consume an Erlang atom (or variable). | 6165 | * Consume an Erlang atom (or variable). |
| 6162 | * Return the number of bytes consumed, or -1 if there was an error. | 6166 | * Return the number of bytes consumed, or -1 if there was an error. |
| 6163 | */ | 6167 | */ |
| 6164 | static int | 6168 | static ptrdiff_t |
| 6165 | erlang_atom (char *s) | 6169 | erlang_atom (char *s) |
| 6166 | { | 6170 | { |
| 6167 | int pos = 0; | 6171 | ptrdiff_t pos = 0; |
| 6168 | 6172 | ||
| 6169 | if (c_isalpha (s[pos]) || s[pos] == '_') | 6173 | if (c_isalpha (s[pos]) || s[pos] == '_') |
| 6170 | { | 6174 | { |
| @@ -6437,10 +6441,9 @@ static char * | |||
| 6437 | substitute (char *in, char *out, struct re_registers *regs) | 6441 | substitute (char *in, char *out, struct re_registers *regs) |
| 6438 | { | 6442 | { |
| 6439 | char *result, *t; | 6443 | char *result, *t; |
| 6440 | int size, dig, diglen; | ||
| 6441 | 6444 | ||
| 6442 | result = NULL; | 6445 | result = NULL; |
| 6443 | size = strlen (out); | 6446 | ptrdiff_t size = strlen (out); |
| 6444 | 6447 | ||
| 6445 | /* Pass 1: figure out how much to allocate by finding all \N strings. */ | 6448 | /* Pass 1: figure out how much to allocate by finding all \N strings. */ |
| 6446 | if (out[size - 1] == '\\') | 6449 | if (out[size - 1] == '\\') |
| @@ -6450,8 +6453,8 @@ substitute (char *in, char *out, struct re_registers *regs) | |||
| 6450 | t = strchr (t + 2, '\\')) | 6453 | t = strchr (t + 2, '\\')) |
| 6451 | if (c_isdigit (t[1])) | 6454 | if (c_isdigit (t[1])) |
| 6452 | { | 6455 | { |
| 6453 | dig = t[1] - '0'; | 6456 | int dig = t[1] - '0'; |
| 6454 | diglen = regs->end[dig] - regs->start[dig]; | 6457 | ptrdiff_t diglen = regs->end[dig] - regs->start[dig]; |
| 6455 | size += diglen - 2; | 6458 | size += diglen - 2; |
| 6456 | } | 6459 | } |
| 6457 | else | 6460 | else |
| @@ -6464,8 +6467,8 @@ substitute (char *in, char *out, struct re_registers *regs) | |||
| 6464 | for (t = result; *out != '\0'; out++) | 6467 | for (t = result; *out != '\0'; out++) |
| 6465 | if (*out == '\\' && c_isdigit (*++out)) | 6468 | if (*out == '\\' && c_isdigit (*++out)) |
| 6466 | { | 6469 | { |
| 6467 | dig = *out - '0'; | 6470 | int dig = *out - '0'; |
| 6468 | diglen = regs->end[dig] - regs->start[dig]; | 6471 | ptrdiff_t diglen = regs->end[dig] - regs->start[dig]; |
| 6469 | memcpy (t, in + regs->start[dig], diglen); | 6472 | memcpy (t, in + regs->start[dig], diglen); |
| 6470 | t += diglen; | 6473 | t += diglen; |
| 6471 | } | 6474 | } |
| @@ -6474,7 +6477,7 @@ substitute (char *in, char *out, struct re_registers *regs) | |||
| 6474 | *t = '\0'; | 6477 | *t = '\0'; |
| 6475 | 6478 | ||
| 6476 | assert (t <= result + size); | 6479 | assert (t <= result + size); |
| 6477 | assert (t - result == (int)strlen (result)); | 6480 | assert (t == result + strlen (result)); |
| 6478 | 6481 | ||
| 6479 | return result; | 6482 | return result; |
| 6480 | } | 6483 | } |
| @@ -6511,7 +6514,7 @@ regex_tag_multiline (void) | |||
| 6511 | 6514 | ||
| 6512 | for (rp = p_head; rp != NULL; rp = rp->p_next) | 6515 | for (rp = p_head; rp != NULL; rp = rp->p_next) |
| 6513 | { | 6516 | { |
| 6514 | int match = 0; | 6517 | ptrdiff_t match = 0; |
| 6515 | 6518 | ||
| 6516 | if (!rp->multi_line) | 6519 | if (!rp->multi_line) |
| 6517 | continue; /* skip normal regexps */ | 6520 | continue; /* skip normal regexps */ |
| @@ -6572,7 +6575,7 @@ regex_tag_multiline (void) | |||
| 6572 | charno - linecharno + 1, lineno, linecharno); | 6575 | charno - linecharno + 1, lineno, linecharno); |
| 6573 | 6576 | ||
| 6574 | if (debug) | 6577 | if (debug) |
| 6575 | fprintf (stderr, "%s on %s:%d: %s\n", | 6578 | fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n", |
| 6576 | name ? name : "(unnamed)", curfdp->taggedfname, | 6579 | name ? name : "(unnamed)", curfdp->taggedfname, |
| 6577 | lineno, buffer + linecharno); | 6580 | lineno, buffer + linecharno); |
| 6578 | } | 6581 | } |
| @@ -6589,7 +6592,7 @@ regex_tag_multiline (void) | |||
| 6589 | static bool | 6592 | static bool |
| 6590 | nocase_tail (const char *cp) | 6593 | nocase_tail (const char *cp) |
| 6591 | { | 6594 | { |
| 6592 | int len = 0; | 6595 | ptrdiff_t len = 0; |
| 6593 | 6596 | ||
| 6594 | while (*cp != '\0' && c_tolower (*cp) == c_tolower (dbp[len])) | 6597 | while (*cp != '\0' && c_tolower (*cp) == c_tolower (dbp[len])) |
| 6595 | cp++, len++; | 6598 | cp++, len++; |
| @@ -6648,7 +6651,7 @@ get_lispy_tag (register char *bp) | |||
| 6648 | * If multi-line regular expressions are requested, each line read is | 6651 | * If multi-line regular expressions are requested, each line read is |
| 6649 | * appended to `filebuf'. | 6652 | * appended to `filebuf'. |
| 6650 | */ | 6653 | */ |
| 6651 | static long | 6654 | static ptrdiff_t |
| 6652 | readline_internal (linebuffer *lbp, FILE *stream, char const *filename) | 6655 | readline_internal (linebuffer *lbp, FILE *stream, char const *filename) |
| 6653 | { | 6656 | { |
| 6654 | char *buffer = lbp->buffer; | 6657 | char *buffer = lbp->buffer; |
| @@ -6664,8 +6667,8 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename) | |||
| 6664 | if (p == pend) | 6667 | if (p == pend) |
| 6665 | { | 6668 | { |
| 6666 | /* We're at the end of linebuffer: expand it. */ | 6669 | /* We're at the end of linebuffer: expand it. */ |
| 6670 | xrnew (buffer, lbp->size, 2); | ||
| 6667 | lbp->size *= 2; | 6671 | lbp->size *= 2; |
| 6668 | xrnew (buffer, lbp->size, char); | ||
| 6669 | p += buffer - lbp->buffer; | 6672 | p += buffer - lbp->buffer; |
| 6670 | pend = buffer + lbp->size; | 6673 | pend = buffer + lbp->size; |
| 6671 | lbp->buffer = buffer; | 6674 | lbp->buffer = buffer; |
| @@ -6702,13 +6705,12 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename) | |||
| 6702 | while (filebuf.size <= filebuf.len + lbp->len + 1) /* +1 for \n */ | 6705 | while (filebuf.size <= filebuf.len + lbp->len + 1) /* +1 for \n */ |
| 6703 | { | 6706 | { |
| 6704 | /* Expand filebuf. */ | 6707 | /* Expand filebuf. */ |
| 6708 | xrnew (filebuf.buffer, filebuf.size, 2); | ||
| 6705 | filebuf.size *= 2; | 6709 | filebuf.size *= 2; |
| 6706 | xrnew (filebuf.buffer, filebuf.size, char); | ||
| 6707 | } | 6710 | } |
| 6708 | memcpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len); | 6711 | strcpy (mempcpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len), |
| 6709 | filebuf.len += lbp->len; | 6712 | "\n"); |
| 6710 | filebuf.buffer[filebuf.len++] = '\n'; | 6713 | filebuf.len += lbp->len + 1; |
| 6711 | filebuf.buffer[filebuf.len] = '\0'; | ||
| 6712 | } | 6714 | } |
| 6713 | 6715 | ||
| 6714 | return lbp->len + chars_deleted; | 6716 | return lbp->len + chars_deleted; |
| @@ -6722,10 +6724,8 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename) | |||
| 6722 | static void | 6724 | static void |
| 6723 | readline (linebuffer *lbp, FILE *stream) | 6725 | readline (linebuffer *lbp, FILE *stream) |
| 6724 | { | 6726 | { |
| 6725 | long result; | ||
| 6726 | |||
| 6727 | linecharno = charno; /* update global char number of line start */ | 6727 | linecharno = charno; /* update global char number of line start */ |
| 6728 | result = readline_internal (lbp, stream, infilename); /* read line */ | 6728 | ptrdiff_t result = readline_internal (lbp, stream, infilename); |
| 6729 | lineno += 1; /* increment global line number */ | 6729 | lineno += 1; /* increment global line number */ |
| 6730 | charno += result; /* increment global char number */ | 6730 | charno += result; /* increment global char number */ |
| 6731 | 6731 | ||
| @@ -6737,10 +6737,10 @@ readline (linebuffer *lbp, FILE *stream) | |||
| 6737 | /* Check whether this is a #line directive. */ | 6737 | /* Check whether this is a #line directive. */ |
| 6738 | if (result > 12 && strneq (lbp->buffer, "#line ", 6)) | 6738 | if (result > 12 && strneq (lbp->buffer, "#line ", 6)) |
| 6739 | { | 6739 | { |
| 6740 | unsigned int lno; | 6740 | intmax_t lno; |
| 6741 | int start = 0; | 6741 | int start = 0; |
| 6742 | 6742 | ||
| 6743 | if (sscanf (lbp->buffer, "#line %u \"%n", &lno, &start) >= 1 | 6743 | if (sscanf (lbp->buffer, "#line %"SCNdMAX" \"%n", &lno, &start) >= 1 |
| 6744 | && start > 0) /* double quote character found */ | 6744 | && start > 0) /* double quote character found */ |
| 6745 | { | 6745 | { |
| 6746 | char *endp = lbp->buffer + start; | 6746 | char *endp = lbp->buffer + start; |
| @@ -6850,7 +6850,7 @@ readline (linebuffer *lbp, FILE *stream) | |||
| 6850 | } /* if #line directives should be considered */ | 6850 | } /* if #line directives should be considered */ |
| 6851 | 6851 | ||
| 6852 | { | 6852 | { |
| 6853 | int match; | 6853 | ptrdiff_t match; |
| 6854 | regexp *rp; | 6854 | regexp *rp; |
| 6855 | char *name; | 6855 | char *name; |
| 6856 | 6856 | ||
| @@ -6900,7 +6900,7 @@ readline (linebuffer *lbp, FILE *stream) | |||
| 6900 | /* Force explicit tag name, if a name is there. */ | 6900 | /* Force explicit tag name, if a name is there. */ |
| 6901 | pfnote (name, true, lbp->buffer, match, lineno, linecharno); | 6901 | pfnote (name, true, lbp->buffer, match, lineno, linecharno); |
| 6902 | if (debug) | 6902 | if (debug) |
| 6903 | fprintf (stderr, "%s on %s:%d: %s\n", | 6903 | fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n", |
| 6904 | name ? name : "(unnamed)", curfdp->taggedfname, | 6904 | name ? name : "(unnamed)", curfdp->taggedfname, |
| 6905 | lineno, lbp->buffer); | 6905 | lineno, lbp->buffer); |
| 6906 | } | 6906 | } |
| @@ -6925,11 +6925,11 @@ savestr (const char *cp) | |||
| 6925 | } | 6925 | } |
| 6926 | 6926 | ||
| 6927 | /* | 6927 | /* |
| 6928 | * Return a pointer to a space of size LEN+1 allocated with xnew where | 6928 | * Return a pointer to a space of size LEN+1 allocated with xnew |
| 6929 | * the string CP has been copied for at most the first LEN characters. | 6929 | * with a copy of CP (containing LEN bytes) followed by a NUL byte. |
| 6930 | */ | 6930 | */ |
| 6931 | static char * | 6931 | static char * |
| 6932 | savenstr (const char *cp, int len) | 6932 | savenstr (const char *cp, ptrdiff_t len) |
| 6933 | { | 6933 | { |
| 6934 | char *dp = xnew (len + 1, char); | 6934 | char *dp = xnew (len + 1, char); |
| 6935 | dp[len] = '\0'; | 6935 | dp[len] = '\0'; |
| @@ -7013,13 +7013,9 @@ verror (char const *format, va_list ap) | |||
| 7013 | static char * | 7013 | static char * |
| 7014 | concat (const char *s1, const char *s2, const char *s3) | 7014 | concat (const char *s1, const char *s2, const char *s3) |
| 7015 | { | 7015 | { |
| 7016 | int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); | 7016 | ptrdiff_t len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); |
| 7017 | char *result = xnew (len1 + len2 + len3 + 1, char); | 7017 | char *result = xnew (len1 + len2 + len3 + 1, char); |
| 7018 | 7018 | strcpy (stpcpy (stpcpy (result, s1), s2), s3); | |
| 7019 | strcpy (result, s1); | ||
| 7020 | strcpy (result + len1, s2); | ||
| 7021 | strcpy (result + len1 + len2, s3); | ||
| 7022 | |||
| 7023 | return result; | 7019 | return result; |
| 7024 | } | 7020 | } |
| 7025 | 7021 | ||
| @@ -7029,16 +7025,16 @@ concat (const char *s1, const char *s2, const char *s3) | |||
| 7029 | static char * | 7025 | static char * |
| 7030 | etags_getcwd (void) | 7026 | etags_getcwd (void) |
| 7031 | { | 7027 | { |
| 7032 | int bufsize = 200; | 7028 | ptrdiff_t bufsize = 200; |
| 7033 | char *path = xnew (bufsize, char); | 7029 | char *path = xnew (bufsize, char); |
| 7034 | 7030 | ||
| 7035 | while (getcwd (path, bufsize) == NULL) | 7031 | while (getcwd (path, bufsize) == NULL) |
| 7036 | { | 7032 | { |
| 7037 | if (errno != ERANGE) | 7033 | if (errno != ERANGE) |
| 7038 | pfatal ("getcwd"); | 7034 | pfatal ("getcwd"); |
| 7039 | bufsize *= 2; | ||
| 7040 | free (path); | 7035 | free (path); |
| 7041 | path = xnew (bufsize, char); | 7036 | path = xnmalloc (bufsize, 2 * sizeof *path); |
| 7037 | bufsize *= 2; | ||
| 7042 | } | 7038 | } |
| 7043 | 7039 | ||
| 7044 | canonicalize_filename (path); | 7040 | canonicalize_filename (path); |
| @@ -7099,7 +7095,7 @@ static char * | |||
| 7099 | relative_filename (char *file, char *dir) | 7095 | relative_filename (char *file, char *dir) |
| 7100 | { | 7096 | { |
| 7101 | char *fp, *dp, *afn, *res; | 7097 | char *fp, *dp, *afn, *res; |
| 7102 | int i; | 7098 | ptrdiff_t i; |
| 7103 | 7099 | ||
| 7104 | /* Find the common root of file and dir (with a trailing slash). */ | 7100 | /* Find the common root of file and dir (with a trailing slash). */ |
| 7105 | afn = absolute_filename (file, cwd); | 7101 | afn = absolute_filename (file, cwd); |
| @@ -7282,32 +7278,54 @@ linebuffer_init (linebuffer *lbp) | |||
| 7282 | 7278 | ||
| 7283 | /* Set the minimum size of a string contained in a linebuffer. */ | 7279 | /* Set the minimum size of a string contained in a linebuffer. */ |
| 7284 | static void | 7280 | static void |
| 7285 | linebuffer_setlen (linebuffer *lbp, int toksize) | 7281 | linebuffer_setlen (linebuffer *lbp, ptrdiff_t toksize) |
| 7286 | { | 7282 | { |
| 7287 | while (lbp->size <= toksize) | 7283 | if (lbp->size <= toksize) |
| 7288 | { | 7284 | { |
| 7289 | lbp->size *= 2; | 7285 | ptrdiff_t multiplier = toksize / lbp->size + 1; |
| 7290 | xrnew (lbp->buffer, lbp->size, char); | 7286 | xrnew (lbp->buffer, lbp->size, multiplier); |
| 7287 | lbp->size *= multiplier; | ||
| 7291 | } | 7288 | } |
| 7292 | lbp->len = toksize; | 7289 | lbp->len = toksize; |
| 7293 | } | 7290 | } |
| 7294 | 7291 | ||
| 7295 | /* Like malloc but get fatal error if memory is exhausted. */ | 7292 | /* Memory allocators with a fatal error if memory is exhausted. */ |
| 7296 | static void * ATTRIBUTE_MALLOC | 7293 | |
| 7297 | xmalloc (size_t size) | 7294 | static void |
| 7295 | memory_full (void) | ||
| 7296 | { | ||
| 7297 | fatal ("virtual memory exhausted"); | ||
| 7298 | } | ||
| 7299 | |||
| 7300 | static void * | ||
| 7301 | xmalloc (ptrdiff_t size) | ||
| 7298 | { | 7302 | { |
| 7303 | if (SIZE_MAX < size) | ||
| 7304 | memory_full (); | ||
| 7299 | void *result = malloc (size); | 7305 | void *result = malloc (size); |
| 7300 | if (result == NULL) | 7306 | if (result == NULL) |
| 7301 | fatal ("virtual memory exhausted"); | 7307 | memory_full (); |
| 7302 | return result; | 7308 | return result; |
| 7303 | } | 7309 | } |
| 7304 | 7310 | ||
| 7305 | static void * | 7311 | static void * |
| 7306 | xrealloc (void *ptr, size_t size) | 7312 | xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) |
| 7307 | { | 7313 | { |
| 7308 | void *result = realloc (ptr, size); | 7314 | ptrdiff_t nbytes; |
| 7309 | if (result == NULL) | 7315 | if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes)) |
| 7310 | fatal ("virtual memory exhausted"); | 7316 | memory_full (); |
| 7317 | return xmalloc (nbytes); | ||
| 7318 | } | ||
| 7319 | |||
| 7320 | static void * | ||
| 7321 | xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) | ||
| 7322 | { | ||
| 7323 | ptrdiff_t nbytes; | ||
| 7324 | if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes) || SIZE_MAX < nbytes) | ||
| 7325 | memory_full (); | ||
| 7326 | void *result = realloc (pa, nbytes); | ||
| 7327 | if (!result) | ||
| 7328 | memory_full (); | ||
| 7311 | return result; | 7329 | return result; |
| 7312 | } | 7330 | } |
| 7313 | 7331 | ||