Mercurial > emacs
comparison lib-src/etags.c @ 5940:e663f6626075
* etags.c (absolute_pathnames, cwd): added global vars.
(longopts, print_help, main, process_file): put absolute filenames
in the tag file if the -A --absolute-pathnames option is used.
(print_help): alfabetically order the options.
(malloc, realloc, strcpy, strncpy, strcmp): remove extern declar.
author | Francesco Potortì <pot@gnu.org> |
---|---|
date | Mon, 14 Feb 1994 14:28:22 +0000 |
parents | 517d8eb361f8 |
children | 77cdcc5fda2d |
comparison
equal
deleted
inserted
replaced
5939:454dc146502d | 5940:e663f6626075 |
---|---|
23 * FORTRAN added by Jim Kleckner. | 23 * FORTRAN added by Jim Kleckner. |
24 * Ed Pelegri-Llopart added C typedefs. | 24 * Ed Pelegri-Llopart added C typedefs. |
25 * Gnu Emacs TAGS format and modifications by RMS? | 25 * Gnu Emacs TAGS format and modifications by RMS? |
26 * Sam Kendall added C++. | 26 * Sam Kendall added C++. |
27 * | 27 * |
28 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 10.6 | 28 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 10.7 |
29 */ | 29 */ |
30 | 30 |
31 #ifdef MSDOS | 31 #ifdef MSDOS |
32 #include <fcntl.h> | 32 #include <fcntl.h> |
33 #endif /* MSDOS */ | 33 #endif /* MSDOS */ |
45 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | 45 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) |
46 #endif | 46 #endif |
47 | 47 |
48 #include "getopt.h" | 48 #include "getopt.h" |
49 | 49 |
50 extern char *malloc (), *realloc (); | |
51 extern char *getenv (); | 50 extern char *getenv (); |
52 extern char *strcpy (), *strncpy (); | 51 extern char *getcwd (); |
53 extern int strcmp (); | |
54 | 52 |
55 char *etags_index (), *etags_rindex (); | 53 char *etags_index (), *etags_rindex (); |
56 char *savenstr (); | 54 char *savenstr (); |
57 | 55 |
58 /* Define the symbol ETAGS to make the program "etags", | 56 /* Define the symbol ETAGS to make the program "etags", |
246 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", | 244 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", |
247 /* valid in-token chars */ | 245 /* valid in-token chars */ |
248 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; | 246 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; |
249 | 247 |
250 int append_to_tagfile; /* -a: append to tags */ | 248 int append_to_tagfile; /* -a: append to tags */ |
249 int absolute_pathnames; /* -A: use absolute pathnames in tag file */ | |
251 int emacs_tags_format; /* emacs style output (no -e option any more) */ | 250 int emacs_tags_format; /* emacs style output (no -e option any more) */ |
252 /* The following three default to 1 for etags, but to 0 for ctags. */ | 251 /* The following three default to 1 for etags, but to 0 for ctags. */ |
253 int typedefs; /* -t: create tags for typedefs */ | 252 int typedefs; /* -t: create tags for typedefs */ |
254 int typedefs_and_cplusplus; /* -T: create tags for typedefs, level */ | 253 int typedefs_and_cplusplus; /* -T: create tags for typedefs, level */ |
255 /* 0 struct/enum/union decls, and C++ */ | 254 /* 0 struct/enum/union decls, and C++ */ |
266 int noindentypedefs; /* -S: ignore indentation in C */ | 265 int noindentypedefs; /* -S: ignore indentation in C */ |
267 | 266 |
268 /* Name this program was invoked with. */ | 267 /* Name this program was invoked with. */ |
269 char *progname; | 268 char *progname; |
270 | 269 |
270 /* The current working directory, used if --absolute-pathnames. */ | |
271 char *cwd; | |
272 | |
271 struct option longopts[] = { | 273 struct option longopts[] = { |
272 { "append", no_argument, NULL, 'a' }, | 274 { "append", no_argument, NULL, 'a' }, |
275 { "absolute-pathnames", no_argument, NULL, 'A' }, | |
273 { "backward-search", no_argument, NULL, 'B' }, | 276 { "backward-search", no_argument, NULL, 'B' }, |
274 { "c++", no_argument, NULL, 'C' }, | 277 { "c++", no_argument, NULL, 'C' }, |
275 { "cxref", no_argument, NULL, 'x' }, | 278 { "cxref", no_argument, NULL, 'x' }, |
276 { "defines", no_argument, NULL, 'd' }, | 279 { "defines", no_argument, NULL, 'd' }, |
277 { "forward-search", no_argument, NULL, 'F' }, | 280 { "forward-search", no_argument, NULL, 'F' }, |
326 #ifdef ETAGS | 329 #ifdef ETAGS |
327 printf ("ETAGS "); | 330 printf ("ETAGS "); |
328 #endif | 331 #endif |
329 printf ("for Emacs version 19.\n"); | 332 printf ("for Emacs version 19.\n"); |
330 | 333 |
331 exit (0); | 334 exit (GOOD); |
332 } | 335 } |
333 | 336 |
334 void | 337 void |
335 print_help () | 338 print_help () |
336 { | 339 { |
337 printf ("These are the options accepted by %s. You may use unambiguous\n\ | 340 printf ("These are the options accepted by %s. You may use unambiguous\n\ |
338 abbreviations for the long option names.\n\n", progname); | 341 abbreviations for the long option names. A - as file name means read file\n\ |
342 names from stdin.\n\n", progname); | |
339 | 343 |
340 puts ("-a, --append\n\ | 344 puts ("-a, --append\n\ |
341 Append tag entries to existing tags file."); | 345 Append tag entries to existing tags file."); |
346 puts ("-A, --absolute-pathnames\n\ | |
347 Use absolute pathnames for tagged files."); | |
348 | |
349 #ifdef CTAGS | |
350 puts ("-B, --backward-search\n\ | |
351 Write the search commands for the tag entries using '?', the\n\ | |
352 backward-search command."); | |
353 #endif | |
354 | |
342 puts ("-C, --c++\n\ | 355 puts ("-C, --c++\n\ |
343 Treat files with `.c' and `.h' extensions as C++ code, not C\n\ | 356 Treat files with `.c' and `.h' extensions as C++ code, not C\n\ |
344 code. Files with `.C', `.H', `.cxx', `.hxx', or `.cc'\n\ | 357 code. Files with `.C', `.H', `.cxx', `.hxx', or `.cc'\n\ |
345 extensions are always assumed to be C++ code."); | 358 extensions are always assumed to be C++ code."); |
346 fputs ("-d, --defines\n\ | |
347 Create tag entries for #defines, too.", stdout); | |
348 | 359 |
349 #ifdef ETAGS | 360 #ifdef ETAGS |
350 fputs (" This is the default\n\ | 361 puts ("-d, --defines\n\ |
351 behavior.", stdout); | 362 Create tag entries for #defines, too. This is the default\n\ |
363 behavior."); | |
364 #else | |
365 puts ("-d, --defines\n\ | |
366 Create tag entries for #defines, too."); | |
352 #endif | 367 #endif |
353 | 368 |
354 fputs ("\n\ | |
355 -D, --no-defines\n\ | |
356 Don't create tag entries for #defines.", stdout); | |
357 | |
358 #ifdef CTAGS | 369 #ifdef CTAGS |
359 fputs (" This is the default\n\ | 370 puts ("-D, --no-defines\n\ |
360 behavior.", stdout); | 371 Don't create tag entries for #defines. This is the default\n\ |
372 behavior."); | |
373 #else | |
374 puts ("-D, --no-defines\n\ | |
375 Don't create tag entries for #defines."); | |
361 #endif | 376 #endif |
362 | 377 |
363 puts ("\n\ | 378 #ifdef CTAGS |
364 -o FILE, --output=FILE\n\ | 379 puts ("-F, --forward-search\n\ |
365 Write the tags to FILE.\n\ | 380 Write the search commands for the tag entries using '/', the\n\ |
366 -S, --ignore-indentation\n\ | 381 forward-search command."); |
382 #endif | |
383 | |
384 | |
385 #ifdef ETAGS | |
386 puts ("-i FILE, --include=FILE\n\ | |
387 Include a note in tag file indicating that, when searching for\n\ | |
388 a tag, one should also consult the tags file FILE after\n\ | |
389 checking the current file."); | |
390 #endif | |
391 | |
392 puts ("-o FILE, --output=FILE\n\ | |
393 Write the tags to FILE."); | |
394 puts ("-S, --ignore-indentation\n\ | |
367 Don't rely on indentation quite as much as normal. Currently,\n\ | 395 Don't rely on indentation quite as much as normal. Currently,\n\ |
368 this means not to assume that a closing brace in the first\n\ | 396 this means not to assume that a closing brace in the first\n\ |
369 column is the final brace of a function or structure\n\ | 397 column is the final brace of a function or structure\n\ |
370 definition."); | 398 definition."); |
371 puts ("-t, --typedefs\n\ | 399 puts ("-t, --typedefs\n\ |
373 behavior."); | 401 behavior."); |
374 puts ("-T, --typedefs-and-c++\n\ | 402 puts ("-T, --typedefs-and-c++\n\ |
375 Generate tag entries for typedefs, struct/enum/union tags, and\n\ | 403 Generate tag entries for typedefs, struct/enum/union tags, and\n\ |
376 C++ member functions."); | 404 C++ member functions."); |
377 | 405 |
378 #ifdef ETAGS | |
379 puts ("-i FILE, --include=FILE\n\ | |
380 Include a note in tag file indicating that, when searching for\n\ | |
381 a tag, one should also consult the tags file FILE after\n\ | |
382 checking the current file."); | |
383 #endif | |
384 | |
385 #ifdef CTAGS | 406 #ifdef CTAGS |
386 puts ("-B, --backward-search\n\ | |
387 Write the search commands for the tag entries using '?', the\n\ | |
388 backward-search command."); | |
389 puts ("-F, --forward-search\n\ | |
390 Write the search commands for the tag entries using '/', the\n\ | |
391 forward-search command."); | |
392 puts ("-u, --update\n\ | 407 puts ("-u, --update\n\ |
393 Update the tag entries for the given files, leaving tag\n\ | 408 Update the tag entries for the given files, leaving tag\n\ |
394 entries for other files in place. Currently, this is\n\ | 409 entries for other files in place. Currently, this is\n\ |
395 implemented by deleting the existing entries for the given\n\ | 410 implemented by deleting the existing entries for the given\n\ |
396 files and then rewriting the new entries at the end of the\n\ | 411 files and then rewriting the new entries at the end of the\n\ |
413 puts ("-V, --version\n\ | 428 puts ("-V, --version\n\ |
414 Print the version of the program.\n\ | 429 Print the version of the program.\n\ |
415 -H, --help\n\ | 430 -H, --help\n\ |
416 Print this help message."); | 431 Print this help message."); |
417 | 432 |
418 exit (0); | 433 exit (GOOD); |
419 } | 434 } |
420 | 435 |
421 | 436 |
422 void | 437 void |
423 main (argc, argv) | 438 main (argc, argv) |
456 typedefs = typedefs_and_cplusplus = constantypedefs = 1; | 471 typedefs = typedefs_and_cplusplus = constantypedefs = 1; |
457 | 472 |
458 for (;;) | 473 for (;;) |
459 { | 474 { |
460 int opt; | 475 int opt; |
461 opt = getopt_long (argc, argv, "aCdDo:f:StTi:BFuvxwVH", longopts, 0); | 476 opt = getopt_long (argc, argv, "aACdDo:f:StTi:BFuvxwVH", longopts, 0); |
462 | 477 |
463 if (opt == EOF) | 478 if (opt == EOF) |
464 break; | 479 break; |
465 | 480 |
466 switch (opt) | 481 switch (opt) |
471 break; | 486 break; |
472 | 487 |
473 /* Common options. */ | 488 /* Common options. */ |
474 case 'a': | 489 case 'a': |
475 append_to_tagfile++; | 490 append_to_tagfile++; |
491 break; | |
492 case 'A': | |
493 absolute_pathnames++; | |
476 break; | 494 break; |
477 case 'C': | 495 case 'C': |
478 cplusplus = 1; | 496 cplusplus = 1; |
479 break; | 497 break; |
480 case 'd': | 498 case 'd': |
580 { | 598 { |
581 if (streq (outfile, "-")) | 599 if (streq (outfile, "-")) |
582 outf = stdout; | 600 outf = stdout; |
583 else | 601 else |
584 outf = fopen (outfile, append_to_tagfile ? "a" : "w"); | 602 outf = fopen (outfile, append_to_tagfile ? "a" : "w"); |
585 if (!outf) | 603 if (outf == NULL) |
586 { | 604 { |
587 perror (outfile); | 605 perror (outfile); |
588 exit (1); | 606 exit (BAD); |
589 } | 607 } |
590 } | 608 } |
591 | 609 |
592 #ifdef VMS | 610 #ifdef VMS |
593 argc -= optind; | 611 argc -= optind; |
605 #if 0 | 623 #if 0 |
606 } | 624 } |
607 } /* solely to balance out the ifdef'd parens above */ | 625 } /* solely to balance out the ifdef'd parens above */ |
608 #endif | 626 #endif |
609 #else | 627 #else |
628 if (absolute_pathnames) | |
629 { | |
630 cwd = getcwd (NULL, 2*BUFSIZ); | |
631 if (cwd == NULL) | |
632 { | |
633 perror ("pwd"); | |
634 exit (BAD); | |
635 } | |
636 strcat (cwd, "/"); | |
637 } | |
610 for (; optind < argc; optind++) | 638 for (; optind < argc; optind++) |
611 { | 639 { |
612 this_file = argv[optind]; | 640 this_file = argv[optind]; |
613 #endif | 641 #endif |
614 /* Input file named "-" means read file names from stdin and use them. */ | 642 /* Input file named "-" means read file names from stdin and use them. */ |
629 { | 657 { |
630 while (nincluded_files-- > 0) | 658 while (nincluded_files-- > 0) |
631 fprintf (outf, "\f\n%s,include\n", *included_files++); | 659 fprintf (outf, "\f\n%s,include\n", *included_files++); |
632 | 660 |
633 (void) fclose (outf); | 661 (void) fclose (outf); |
634 exit (0); | 662 exit (GOOD); |
635 } | 663 } |
636 | 664 |
637 if (cxref_style) | 665 if (cxref_style) |
638 { | 666 { |
639 put_entries (head); | 667 put_entries (head); |
692 { | 720 { |
693 return; | 721 return; |
694 } | 722 } |
695 if (emacs_tags_format) | 723 if (emacs_tags_format) |
696 { | 724 { |
697 fprintf (outf, "\f\n%s,%d\n", file, total_size_of_entries (head)); | 725 fprintf (outf, "\f\n%s%s,%d\n", |
726 ((absolute_pathnames && file[0] != '/') ? cwd : ""), | |
727 file, total_size_of_entries (head)); | |
698 put_entries (head); | 728 put_entries (head); |
699 free_tree (head); | 729 free_tree (head); |
700 head = NULL; | 730 head = NULL; |
701 } | 731 } |
702 } | 732 } |
886 register char *fp; | 916 register char *fp; |
887 register NODE *np; | 917 register NODE *np; |
888 char tem[51]; | 918 char tem[51]; |
889 char c; | 919 char c; |
890 | 920 |
891 np = (NODE *) malloc (sizeof (NODE)); | 921 np = xnew (1, NODE); |
892 if (np == NULL) | 922 if (np == NULL) |
893 { | 923 { |
894 if (!emacs_tags_format) | 924 if (!emacs_tags_format) |
895 { | 925 { |
896 /* It's okay to output early in etags -- it only disrupts the | 926 /* It's okay to output early in etags -- it only disrupts the |
897 * character count of the tag entries, which is no longer used | 927 * character count of the tag entries, which is no longer used |
898 * by tags.el anyway. | 928 * by tags.el anyway. |
899 */ | 929 */ |
900 error ("too many entries to sort"); | 930 error ("too many entries to sort", 0); |
901 } | 931 } |
902 put_entries (head); | 932 put_entries (head); |
903 free_tree (head); | 933 free_tree (head); |
904 head = NULL; | 934 head = NULL; |
905 np = xnew (1, NODE); | 935 np = xnew (1, NODE); |
988 } | 1018 } |
989 | 1019 |
990 if (emacs_tags_format) | 1020 if (emacs_tags_format) |
991 { | 1021 { |
992 /* Etags Mode */ | 1022 /* Etags Mode */ |
993 if (!last_node) | 1023 if (last_node == NULL) |
994 fatal ("internal error in add_node"); | 1024 fatal ("internal error in add_node", 0); |
995 last_node->right = node; | 1025 last_node->right = node; |
996 last_node = node; | 1026 last_node = node; |
997 } | 1027 } |
998 else | 1028 else |
999 { | 1029 { |
1027 } | 1057 } |
1028 | 1058 |
1029 /* Maybe refuse to add duplicate nodes. */ | 1059 /* Maybe refuse to add duplicate nodes. */ |
1030 if (!permit_duplicates) | 1060 if (!permit_duplicates) |
1031 { | 1061 { |
1032 if (!strcmp (node->name, cur_node->name) | 1062 if (streq (node->name, cur_node->name) |
1033 && !strcmp (node->file, cur_node->file)) | 1063 && streq (node->file, cur_node->file)) |
1034 return; | 1064 return; |
1035 } | 1065 } |
1036 | 1066 |
1037 /* Actually add the node */ | 1067 /* Actually add the node */ |
1038 add_node (node, dif < 0 ? &cur_node->left : &cur_node->right); | 1068 add_node (node, dif < 0 ? &cur_node->left : &cur_node->right); |
1272 | 1302 |
1273 if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) | 1303 if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) |
1274 { | 1304 { |
1275 register char *s = wordlist[key].name; | 1305 register char *s = wordlist[key].name; |
1276 | 1306 |
1277 if (*s == *str && !strncmp (str + 1, s + 1, len - 1)) | 1307 if (*s == *str && strneq (str + 1, s + 1, len - 1)) |
1278 return &wordlist[key]; | 1308 return &wordlist[key]; |
1279 } | 1309 } |
1280 } | 1310 } |
1281 return 0; | 1311 return 0; |
1282 } | 1312 } |
1801 if (cblev == 0) | 1831 if (cblev == 0) |
1802 { | 1832 { |
1803 if (typdef == tinbody) | 1833 if (typdef == tinbody) |
1804 typdef = tend; | 1834 typdef = tend; |
1805 structdef = snone; | 1835 structdef = snone; |
1806 (void) strcpy (structtag, "<error 2>"); | 1836 strcpy (structtag, "<error 2>"); |
1807 } | 1837 } |
1808 break; | 1838 break; |
1809 case '=': | 1839 case '=': |
1810 case '#': case '+': case '-': case '~': case '&': case '%': case '/': | 1840 case '#': case '+': case '-': case '~': case '&': case '%': case '/': |
1811 case '|': case '^': case '!': case '<': case '>': case '.': case '?': | 1841 case '|': case '^': case '!': case '<': case '>': case '.': case '?': |
1888 else | 1918 else |
1889 return (TRUE); | 1919 return (TRUE); |
1890 case dignorerest: | 1920 case dignorerest: |
1891 return (FALSE); | 1921 return (FALSE); |
1892 default: | 1922 default: |
1893 error ("internal error: definedef value"); | 1923 error ("internal error: definedef value is %d", definedef); |
1894 } | 1924 } |
1895 | 1925 |
1896 /* | 1926 /* |
1897 * Now typedefs | 1927 * Now typedefs |
1898 */ | 1928 */ |
1959 } | 1989 } |
1960 if (structdef == skeyseen) | 1990 if (structdef == skeyseen) |
1961 { | 1991 { |
1962 if (structtype == st_C_struct) | 1992 if (structtype == st_C_struct) |
1963 { | 1993 { |
1964 (void) strncpy (structtag, tokp->p, tokp->len); | 1994 strncpy (structtag, tokp->p, tokp->len); |
1965 structtag[tokp->len] = '\0'; /* for struct/union/class */ | 1995 structtag[tokp->len] = '\0'; /* for struct/union/class */ |
1966 } | 1996 } |
1967 else | 1997 else |
1968 { | 1998 { |
1969 structtag[0] = '\0'; /* for enum (why is it treated differently?) */ | 1999 structtag[0] = '\0'; /* for enum (why is it treated differently?) */ |
2177 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$'))); | 2207 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$'))); |
2178 cp++) | 2208 cp++) |
2179 continue; | 2209 continue; |
2180 c = *cp; | 2210 c = *cp; |
2181 *cp = '\0'; | 2211 *cp = '\0'; |
2182 (void) strcpy (nambuf, dbp); | 2212 strcpy (nambuf, dbp); |
2183 *cp = c; | 2213 *cp = c; |
2184 pfnote (nambuf, TRUE, FALSE, lb.buffer, | 2214 pfnote (nambuf, TRUE, FALSE, lb.buffer, |
2185 cp - lb.buffer + 1, lineno, linecharno); | 2215 cp - lb.buffer + 1, lineno, linecharno); |
2186 pfcnt++; | 2216 pfcnt++; |
2187 } | 2217 } |
2508 if (cp == dbp) | 2538 if (cp == dbp) |
2509 return; | 2539 return; |
2510 | 2540 |
2511 c = cp[0]; | 2541 c = cp[0]; |
2512 cp[0] = 0; | 2542 cp[0] = 0; |
2513 (void) strcpy (nambuf, dbp); | 2543 strcpy (nambuf, dbp); |
2514 cp[0] = c; | 2544 cp[0] = c; |
2515 pfnote (nambuf, TRUE, FALSE, lb.buffer, | 2545 pfnote (nambuf, TRUE, FALSE, lb.buffer, |
2516 cp - lb.buffer + 1, lineno, linecharno); | 2546 cp - lb.buffer + 1, lineno, linecharno); |
2517 pfcnt++; | 2547 pfcnt++; |
2518 } | 2548 } |
2775 return; | 2805 return; |
2776 | 2806 |
2777 /* Let tag name extend to next group close (or end of line) */ | 2807 /* Let tag name extend to next group close (or end of line) */ |
2778 while (*p && *p != TEX_clgrp) | 2808 while (*p && *p != TEX_clgrp) |
2779 p++; | 2809 p++; |
2780 (void) strncpy (nambuf, name, p - name); | 2810 strncpy (nambuf, name, p - name); |
2781 nambuf[p - name] = 0; | 2811 nambuf[p - name] = 0; |
2782 | 2812 |
2783 pfnote (nambuf, TRUE, FALSE, lb.buffer, strlen (lb.buffer), lineno, linecharno); | 2813 pfnote (nambuf, TRUE, FALSE, lb.buffer, strlen (lb.buffer), lineno, linecharno); |
2784 pfcnt++; | 2814 pfcnt++; |
2785 } | 2815 } |
2795 char *cp; | 2825 char *cp; |
2796 { | 2826 { |
2797 int i; | 2827 int i; |
2798 | 2828 |
2799 for (i = 0; TEX_toktab[i].len > 0; i++) | 2829 for (i = 0; TEX_toktab[i].len > 0; i++) |
2800 if (strncmp (TEX_toktab[i].name, cp, TEX_toktab[i].len) == 0) | 2830 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len)) |
2801 return i; | 2831 return i; |
2802 return -1; | 2832 return -1; |
2803 } | 2833 } |
2804 | 2834 |
2805 /* Support for Prolog. */ | 2835 /* Support for Prolog. */ |
2994 int len; | 3024 int len; |
2995 { | 3025 { |
2996 register char *dp; | 3026 register char *dp; |
2997 | 3027 |
2998 dp = xnew (len + 1, char); | 3028 dp = xnew (len + 1, char); |
2999 (void) strncpy (dp, cp, len); | 3029 strncpy (dp, cp, len); |
3000 dp[len] = '\0'; | 3030 dp[len] = '\0'; |
3001 return dp; | 3031 return dp; |
3002 } | 3032 } |
3003 | 3033 |
3004 /* | 3034 /* |
3049 void | 3079 void |
3050 fatal (s1, s2) | 3080 fatal (s1, s2) |
3051 char *s1, *s2; | 3081 char *s1, *s2; |
3052 { | 3082 { |
3053 error (s1, s2); | 3083 error (s1, s2); |
3054 exit (1); | 3084 exit (BAD); |
3055 } | 3085 } |
3056 | 3086 |
3057 /* Print error message. `s1' is printf control string, `s2' is arg for it. */ | 3087 /* Print error message. `s1' is printf control string, `s2' is arg for it. */ |
3058 | 3088 |
3059 /* VARARGS1 */ | 3089 /* VARARGS1 */ |
3073 char *s1, *s2, *s3; | 3103 char *s1, *s2, *s3; |
3074 { | 3104 { |
3075 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); | 3105 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); |
3076 char *result = xnew (len1 + len2 + len3 + 1, char); | 3106 char *result = xnew (len1 + len2 + len3 + 1, char); |
3077 | 3107 |
3078 (void) strcpy (result, s1); | 3108 strcpy (result, s1); |
3079 (void) strcpy (result + len1, s2); | 3109 strcpy (result + len1, s2); |
3080 (void) strcpy (result + len1 + len2, s3); | 3110 strcpy (result + len1 + len2, s3); |
3081 *(result + len1 + len2 + len3) = 0; | 3111 *(result + len1 + len2 + len3) = 0; |
3082 | 3112 |
3083 return result; | 3113 return result; |
3084 } | 3114 } |
3085 | 3115 |
3087 | 3117 |
3088 char * | 3118 char * |
3089 xmalloc (size) | 3119 xmalloc (size) |
3090 unsigned int size; | 3120 unsigned int size; |
3091 { | 3121 { |
3092 char *result = malloc (size); | 3122 char *result = (char *) malloc (size); |
3093 if (!result) | 3123 if (result == NULL) |
3094 fatal ("virtual memory exhausted", 0); | 3124 fatal ("virtual memory exhausted", 0); |
3095 return result; | 3125 return result; |
3096 } | 3126 } |
3097 | 3127 |
3098 char * | 3128 char * |
3099 xrealloc (ptr, size) | 3129 xrealloc (ptr, size) |
3100 char *ptr; | 3130 char *ptr; |
3101 unsigned int size; | 3131 unsigned int size; |
3102 { | 3132 { |
3103 char *result = realloc (ptr, size); | 3133 char *result = (char *) realloc (ptr, size); |
3104 if (!result) | 3134 if (result == NULL) |
3105 fatal ("virtual memory exhausted"); | 3135 fatal ("virtual memory exhausted"); |
3106 return result; | 3136 return result; |
3107 } | 3137 } |