aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorFrancesco Potortì1997-04-15 14:50:46 +0000
committerFrancesco Potortì1997-04-15 14:50:46 +0000
commit2f608d34a6e27761d00a9ffdfbb7e4187a16d77d (patch)
treea2cb36d4a10a58aa44fdad46ca3b1ee122e73668 /lib-src
parent9ba38b85f481bffcc67a297ca2808f3da468a185 (diff)
downloademacs-2f608d34a6e27761d00a9ffdfbb7e4187a16d77d.tar.gz
emacs-2f608d34a6e27761d00a9ffdfbb7e4187a16d77d.zip
Tue Apr 15 16:09:15 1997 Francesco Potorti` <F.Potorti@cnuce.cnr.it>
* etags.c (xnew): Add support for debugging with chkmalloc. (error): Use this instead of printf whenever possible. (main): Only call xnew after having initialised progname. (substitute): Bad memory corruption error corrected. * etags.c (add_regex): Undo previous change. (relative_filename): Small memory leak closed. (absolute_filename): Cleaned up the code, possibly closing a bug. (absolute_dirname): Always return a newly allocated string.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/etags.c178
1 files changed, 87 insertions, 91 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index d05962503ec..8b21906b88f 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -31,7 +31,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
31 * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer. 31 * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer.
32 */ 32 */
33 33
34char pot_etags_version[] = "@(#) pot revision number is 11.82"; 34char pot_etags_version[] = "@(#) pot revision number is $Revision: 11.84 $";
35 35
36#define TRUE 1 36#define TRUE 1
37#define FALSE 0 37#define FALSE 0
@@ -134,7 +134,13 @@ extern int errno;
134 * 134 *
135 * SYNOPSIS: Type *xnew (int n, Type); 135 * SYNOPSIS: Type *xnew (int n, Type);
136 */ 136 */
137#define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) 137#ifdef chkmalloc
138# include "chkmalloc.h"
139# define xnew(n,Type) ((Type *) trace_xmalloc (__FILE__, __LINE__, \
140 (n) * sizeof (Type)))
141#else
142# define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
143#endif
138 144
139typedef int logical; 145typedef int logical;
140 146
@@ -570,7 +576,7 @@ enum argument_type
570 at_filename 576 at_filename
571}; 577};
572 578
573/* This structure helps us allow mixing of --lang and filenames. */ 579/* This structure helps us allow mixing of --lang and file names. */
574typedef struct 580typedef struct
575{ 581{
576 enum argument_type arg_type; 582 enum argument_type arg_type;
@@ -592,7 +598,7 @@ typedef struct {
592 598
593/* 599/*
594 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names 600 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
595 returning in each successive call the next filename matching the input 601 returning in each successive call the next file name matching the input
596 spec. The function expects that each in_spec passed 602 spec. The function expects that each in_spec passed
597 to it will be processed to completion; in particular, up to and 603 to it will be processed to completion; in particular, up to and
598 including the call following that in which the last matching name 604 including the call following that in which the last matching name
@@ -601,7 +607,7 @@ typedef struct {
601 If an error occurs, on return out_spec contains the value 607 If an error occurs, on return out_spec contains the value
602 of in_spec when the error occurred. 608 of in_spec when the error occurred.
603 609
604 With each successive filename returned in out_spec, the 610 With each successive file name returned in out_spec, the
605 function's return value is one. When there are no more matching 611 function's return value is one. When there are no more matching
606 names the function returns zero. If on the first call no file 612 names the function returns zero. If on the first call no file
607 matches in_spec, or there is any other error, -1 is returned. 613 matches in_spec, or there is any other error, -1 is returned.
@@ -680,7 +686,7 @@ gfnames (arg, p_error)
680system (cmd) 686system (cmd)
681 char *cmd; 687 char *cmd;
682{ 688{
683 fprintf (stderr, "system() function not implemented under VMS\n"); 689 error ("%s", "system() function not implemented under VMS");
684} 690}
685#endif 691#endif
686 692
@@ -709,11 +715,11 @@ main (argc, argv)
709 char *argv[]; 715 char *argv[];
710{ 716{
711 int i; 717 int i;
712 unsigned int nincluded_files = 0; 718 unsigned int nincluded_files;
713 char **included_files = xnew (argc, char *); 719 char **included_files;
714 char *this_file; 720 char *this_file;
715 argument *argbuffer; 721 argument *argbuffer;
716 int current_arg = 0, file_count = 0; 722 int current_arg, file_count;
717 struct linebuffer filename_lb; 723 struct linebuffer filename_lb;
718#ifdef VMS 724#ifdef VMS
719 logical got_err; 725 logical got_err;
@@ -724,6 +730,10 @@ main (argc, argv)
724#endif /* DOS_NT */ 730#endif /* DOS_NT */
725 731
726 progname = argv[0]; 732 progname = argv[0];
733 nincluded_files = 0;
734 included_files = xnew (argc, char *);
735 current_arg = 0;
736 file_count = 0;
727 737
728 /* Allocate enough no matter what happens. Overkill, but each one 738 /* Allocate enough no matter what happens. Overkill, but each one
729 is small. */ 739 is small. */
@@ -757,7 +767,7 @@ main (argc, argv)
757 break; 767 break;
758 768
759 case 1: 769 case 1:
760 /* This means that a filename has been seen. Record it. */ 770 /* This means that a file name has been seen. Record it. */
761 argbuffer[current_arg].arg_type = at_filename; 771 argbuffer[current_arg].arg_type = at_filename;
762 argbuffer[current_arg].what = optarg; 772 argbuffer[current_arg].what = optarg;
763 ++current_arg; 773 ++current_arg;
@@ -781,8 +791,7 @@ main (argc, argv)
781 case 'o': 791 case 'o':
782 if (tagfile) 792 if (tagfile)
783 { 793 {
784 fprintf (stderr, "%s: -%c option may only be given once.\n", 794 error ("-%c option may only be given once.", opt);
785 progname, opt);
786 suggest_asking_for_help (); 795 suggest_asking_for_help ();
787 } 796 }
788 tagfile = optarg; 797 tagfile = optarg;
@@ -859,7 +868,7 @@ main (argc, argv)
859 868
860 if (nincluded_files == 0 && file_count == 0) 869 if (nincluded_files == 0 && file_count == 0)
861 { 870 {
862 fprintf (stderr, "%s: No input files specified.\n", progname); 871 error ("%s", "No input files specified.");
863 suggest_asking_for_help (); 872 suggest_asking_for_help ();
864 } 873 }
865 874
@@ -1009,8 +1018,7 @@ get_language_from_name (name)
1009 return lang->function; 1018 return lang->function;
1010 } 1019 }
1011 1020
1012 fprintf (stderr, "%s: language \"%s\" not recognized.\n", 1021 error ("language \"%s\" not recognized.", optarg);
1013 progname, optarg);
1014 suggest_asking_for_help (); 1022 suggest_asking_for_help ();
1015 1023
1016 /* This point should never be reached. The function should either 1024 /* This point should never be reached. The function should either
@@ -1085,12 +1093,12 @@ process_file (file)
1085 1093
1086 if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode)) 1094 if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode))
1087 { 1095 {
1088 fprintf (stderr, "Skipping %s: it is not a regular file.\n", file); 1096 error ("Skipping %s: it is not a regular file.", file);
1089 return; 1097 return;
1090 } 1098 }
1091 if (streq (file, tagfile) && !streq (tagfile, "-")) 1099 if (streq (file, tagfile) && !streq (tagfile, "-"))
1092 { 1100 {
1093 fprintf (stderr, "Skipping inclusion of %s in self.\n", file); 1101 error ("Skipping inclusion of %s in self.", file);
1094 return; 1102 return;
1095 } 1103 }
1096 inf = fopen (file, "r"); 1104 inf = fopen (file, "r");
@@ -1108,12 +1116,12 @@ process_file (file)
1108 1116
1109 if (absolutefn (file)) 1117 if (absolutefn (file))
1110 { 1118 {
1111 /* file is an absolute filename. Canonicalise it. */ 1119 /* file is an absolute file name. Canonicalise it. */
1112 filename = absolute_filename (file, cwd); 1120 filename = absolute_filename (file, cwd);
1113 } 1121 }
1114 else 1122 else
1115 { 1123 {
1116 /* file is a filename relative to cwd. Make it relative 1124 /* file is a file name relative to cwd. Make it relative
1117 to the directory of the tags file. */ 1125 to the directory of the tags file. */
1118 filename = relative_filename (file, tagfiledir); 1126 filename = relative_filename (file, tagfiledir);
1119 } 1127 }
@@ -3973,7 +3981,7 @@ add_regex (regexp_pattern)
3973{ 3981{
3974 char *name; 3982 char *name;
3975 const char *err; 3983 const char *err;
3976 struct re_pattern_buffer *patbuf, patbuf_init = { 0 }; 3984 struct re_pattern_buffer *patbuf;
3977 3985
3978 if (regexp_pattern == NULL) 3986 if (regexp_pattern == NULL)
3979 { 3987 {
@@ -4002,7 +4010,10 @@ add_regex (regexp_pattern)
4002 (void) scan_separators (name); 4010 (void) scan_separators (name);
4003 4011
4004 patbuf = xnew (1, struct re_pattern_buffer); 4012 patbuf = xnew (1, struct re_pattern_buffer);
4005 *patbuf = patbuf_init; 4013 patbuf->translate = NULL;
4014 patbuf->fastmap = NULL;
4015 patbuf->buffer = NULL;
4016 patbuf->allocated = 0;
4006 4017
4007 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf); 4018 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
4008 if (err != NULL) 4019 if (err != NULL)
@@ -4032,52 +4043,40 @@ substitute (in, out, regs)
4032 char *in, *out; 4043 char *in, *out;
4033 struct re_registers *regs; 4044 struct re_registers *regs;
4034{ 4045{
4035 char *result = NULL, *t; 4046 char *result, *t;
4036 int size = 0; 4047 int size, i;
4048
4049 result = NULL;
4050 size = strlen (out);
4037 4051
4038 /* Pass 1: figure out how much size to allocate. */ 4052 /* Pass 1: figure out how much size to allocate. */
4039 for (t = out; *t; ++t) 4053 if (out[strlen (out) - 1] == '\\')
4040 { 4054 fatal ("pattern error in %s", out);
4041 if (*t == '\\') 4055 for (t = out; *t != '\0'; ++t)
4042 { 4056 if (*t == '\\' && isdigit (*++t))
4043 ++t; 4057 {
4044 if (!*t) 4058 int dig = *t - '0';
4045 { 4059 size += regs->end[dig] - regs->start[dig] - 2;
4046 fprintf (stderr, "%s: pattern substitution ends prematurely\n", 4060 }
4047 progname);
4048 return NULL;
4049 }
4050 if (isdigit (*t))
4051 {
4052 int dig = *t - '0';
4053 size += regs->end[dig] - regs->start[dig];
4054 }
4055 }
4056 }
4057 4061
4058 /* Allocate space and do the substitutions. */ 4062 /* Allocate space and do the substitutions. */
4059 result = xnew (size + 1, char); 4063 result = xnew (size + 1, char);
4060 size = 0; 4064 for (i = 0; *out != '\0'; ++out)
4061 for (; *out; ++out)
4062 { 4065 {
4063 if (*out == '\\') 4066 if (*out == '\\' && isdigit (*++out))
4064 { 4067 {
4065 ++out; 4068 /* Using "dig2" satisfies my debugger. Bleah. */
4066 if (isdigit (*out)) 4069 int dig2 = *out - '0';
4067 { 4070 int diglen = regs->end[dig2] - regs->start[dig2];
4068 /* Using "dig2" satisfies my debugger. Bleah. */ 4071 strncpy (result + i, in + regs->start[dig2], diglen);
4069 int dig2 = *out - '0'; 4072 i += diglen;
4070 strncpy (result + size, in + regs->start[dig2],
4071 regs->end[dig2] - regs->start[dig2]);
4072 size += regs->end[dig2] - regs->start[dig2];
4073 }
4074 else
4075 result[size++] = *out;
4076 } 4073 }
4077 else 4074 else
4078 result[size++] = *out; 4075 result[i++] = *out;
4079 } 4076 }
4080 result[size] = '\0'; 4077 result[i] = '\0';
4078 if (DEBUG && i > size)
4079 abort ();
4081 4080
4082 return result; 4081 return result;
4083} 4082}
@@ -4410,7 +4409,7 @@ etags_getcwd ()
4410#endif /* not HAVE_GETCWD */ 4409#endif /* not HAVE_GETCWD */
4411} 4410}
4412 4411
4413/* Return a newly allocated string containing the filename 4412/* Return a newly allocated string containing the file name
4414 of FILE relative to the absolute directory DIR (which 4413 of FILE relative to the absolute directory DIR (which
4415 should end with a slash). */ 4414 should end with a slash). */
4416char * 4415char *
@@ -4418,6 +4417,7 @@ relative_filename (file, dir)
4418 char *file, *dir; 4417 char *file, *dir;
4419{ 4418{
4420 char *fp, *dp, *abs, *res; 4419 char *fp, *dp, *abs, *res;
4420 int i;
4421 4421
4422 /* Find the common root of file and dir (with a trailing slash). */ 4422 /* Find the common root of file and dir (with a trailing slash). */
4423 abs = absolute_filename (file, cwd); 4423 abs = absolute_filename (file, cwd);
@@ -4426,27 +4426,28 @@ relative_filename (file, dir)
4426 while (*fp++ == *dp++) 4426 while (*fp++ == *dp++)
4427 continue; 4427 continue;
4428 fp--, dp--; /* back to the first differing char */ 4428 fp--, dp--; /* back to the first differing char */
4429 do /* look at the equal chars until / */ 4429 do /* look at the equal chars until '/' */
4430 fp--, dp--; 4430 fp--, dp--;
4431 while (*fp != '/'); 4431 while (*fp != '/');
4432 4432
4433 /* Build a sequence of "../" strings for the resulting relative filename. */ 4433 /* Build a sequence of "../" strings for the resulting relative file name. */
4434 for (dp = etags_strchr (dp + 1, '/'), res = ""; 4434 i = 0;
4435 dp != NULL; 4435 while ((dp = etags_strchr (dp + 1, '/')) != NULL)
4436 dp = etags_strchr (dp + 1, '/')) 4436 i += 1;
4437 { 4437 res = xnew (3*i + strlen (fp + 1) + 1, char);
4438 res = concat (res, "../", ""); 4438 res[0] = '\0';
4439 } 4439 while (i-- > 0)
4440 4440 strcat (res, "../");
4441 /* Add the filename relative to the common root of file and dir. */ 4441
4442 res = concat (res, fp + 1, ""); 4442 /* Add the file name relative to the common root of file and dir. */
4443 strcat (res, fp + 1);
4443 free (abs); 4444 free (abs);
4444 4445
4445 return res; 4446 return res;
4446} 4447}
4447 4448
4448/* Return a newly allocated string containing the 4449/* Return a newly allocated string containing the
4449 absolute filename of FILE given CWD (which should 4450 absolute file name of FILE given CWD (which should
4450 end with a slash). */ 4451 end with a slash). */
4451char * 4452char *
4452absolute_filename (file, cwd) 4453absolute_filename (file, cwd)
@@ -4455,12 +4456,12 @@ absolute_filename (file, cwd)
4455 char *slashp, *cp, *res; 4456 char *slashp, *cp, *res;
4456 4457
4457 if (absolutefn (file)) 4458 if (absolutefn (file))
4458 res = concat (file, "", ""); 4459 res = savestr (file);
4459#ifdef DOS_NT 4460#ifdef DOS_NT
4460 /* We don't support non-absolute filenames with a drive 4461 /* We don't support non-absolute file names with a drive
4461 letter, like `d:NAME' (it's too much hassle). */ 4462 letter, like `d:NAME' (it's too much hassle). */
4462 else if (file[1] == ':') 4463 else if (file[1] == ':')
4463 fatal ("%s: relative filenames with drive letters not supported", file); 4464 fatal ("%s: relative file names with drive letters not supported", file);
4464#endif 4465#endif
4465 else 4466 else
4466 res = concat (cwd, file, ""); 4467 res = concat (cwd, file, "");
@@ -4478,24 +4479,16 @@ absolute_filename (file, cwd)
4478 do 4479 do
4479 cp--; 4480 cp--;
4480 while (cp >= res && !absolutefn (cp)); 4481 while (cp >= res && !absolutefn (cp));
4481 if (*cp == '/') 4482 if (cp < res)
4482 { 4483 cp = slashp; /* the absolute name begins with "/.." */
4483 strcpy (cp, slashp + 3);
4484 }
4485#ifdef DOS_NT 4484#ifdef DOS_NT
4486 /* Under MSDOS and NT we get `d:/NAME' as absolute 4485 /* Under MSDOS and NT we get `d:/NAME' as absolute
4487 filename, so the luser could say `d:/../NAME'. 4486 file name, so the luser could say `d:/../NAME'.
4488 We silently treat this as `d:/NAME'. */ 4487 We silently treat this as `d:/NAME'. */
4489 else if (cp[1] == ':') 4488 else if (cp[0] != '/')
4490 strcpy (cp + 3, slashp + 4); 4489 cp = slashp;
4491#endif 4490#endif
4492 else /* else (cp == res) */ 4491 strcpy (cp, slashp + 3);
4493 {
4494 if (slashp[3] != '\0')
4495 strcpy (cp, slashp + 4);
4496 else
4497 return ".";
4498 }
4499 slashp = cp; 4492 slashp = cp;
4500 continue; 4493 continue;
4501 } 4494 }
@@ -4508,12 +4501,15 @@ absolute_filename (file, cwd)
4508 4501
4509 slashp = etags_strchr (slashp + 1, '/'); 4502 slashp = etags_strchr (slashp + 1, '/');
4510 } 4503 }
4511 4504
4512 return res; 4505 if (res[0] == '\0')
4506 return savestr ("/");
4507 else
4508 return res;
4513} 4509}
4514 4510
4515/* Return a newly allocated string containing the absolute 4511/* Return a newly allocated string containing the absolute
4516 filename of dir where FILE resides given CWD (which should 4512 file name of dir where FILE resides given CWD (which should
4517 end with a slash). */ 4513 end with a slash). */
4518char * 4514char *
4519absolute_dirname (file, cwd) 4515absolute_dirname (file, cwd)
@@ -4531,7 +4527,7 @@ absolute_dirname (file, cwd)
4531 4527
4532 slashp = etags_strrchr (file, '/'); 4528 slashp = etags_strrchr (file, '/');
4533 if (slashp == NULL) 4529 if (slashp == NULL)
4534 return cwd; 4530 return savestr (cwd);
4535 save = slashp[1]; 4531 save = slashp[1];
4536 slashp[1] = '\0'; 4532 slashp[1] = '\0';
4537 res = absolute_filename (file, cwd); 4533 res = absolute_filename (file, cwd);