aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancesco Potortì1997-04-30 14:57:39 +0000
committerFrancesco Potortì1997-04-30 14:57:39 +0000
commite0903a92eaaf1fbac37eeb92e4c44c35e9f3ea17 (patch)
treee45626a8b518f6199b4ce9144f51a599c7914981
parent39445e62161bcaf9b905eda1e9fd325c8d1d7ee1 (diff)
downloademacs-e0903a92eaaf1fbac37eeb92e4c44c35e9f3ea17.tar.gz
emacs-e0903a92eaaf1fbac37eeb92e4c44c35e9f3ea17.zip
* etags.c [TeX_named_tokens]: Set to FALSE if undefined.
(struct linebuffer): New member `len' is the length of the string. (find_entries, Pascal_functions, TeX_functions, TEX_getit): Use it instead of strlen. (TEX_getit): Declare and define unconditionally as static. (TeX_functions): Use if instead of #if TeX_named_tokens. (add_regex): Set RE_INTERVALS flag for regex compilation. (substitute): Code cleanup. (readline_internal): Code cleanup, set new member `len'. (readline): Bug corrected.
-rw-r--r--lib-src/etags.c171
1 files changed, 91 insertions, 80 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 8b21906b88f..b07028296a4 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 $Revision: 11.84 $"; 34char pot_etags_version[] = "@(#) pot revision number is 11.85";
35 35
36#define TRUE 1 36#define TRUE 1
37#define FALSE 0 37#define FALSE 0
@@ -40,6 +40,10 @@ char pot_etags_version[] = "@(#) pot revision number is $Revision: 11.84 $";
40# define DEBUG FALSE 40# define DEBUG FALSE
41#endif 41#endif
42 42
43#ifndef TeX_named_tokens
44# define TeX_named_tokens FALSE
45#endif
46
43#ifdef MSDOS 47#ifdef MSDOS
44# include <string.h> 48# include <string.h>
45# include <fcntl.h> 49# include <fcntl.h>
@@ -245,10 +249,13 @@ NODE *head; /* the head of the binary tree of tags */
245 * A `struct linebuffer' is a structure which holds a line of text. 249 * A `struct linebuffer' is a structure which holds a line of text.
246 * `readline' reads a line from a stream into a linebuffer and works 250 * `readline' reads a line from a stream into a linebuffer and works
247 * regardless of the length of the line. 251 * regardless of the length of the line.
252 * SIZE is the size of BUFFER, LEN is the length of the string in
253 * BUFFER after readline reads it.
248 */ 254 */
249struct linebuffer 255struct linebuffer
250{ 256{
251 long size; 257 long size;
258 int len;
252 char *buffer; 259 char *buffer;
253}; 260};
254 261
@@ -1206,7 +1213,8 @@ find_entries (file, inf)
1206 } 1213 }
1207 1214
1208 /* Look for sharp-bang as the first two characters. */ 1215 /* Look for sharp-bang as the first two characters. */
1209 if (readline_internal (&lb, inf) > 2 1216 if (readline_internal (&lb, inf)
1217 && lb.len >= 2
1210 && lb.buffer[0] == '#' 1218 && lb.buffer[0] == '#'
1211 && lb.buffer[1] == '!') 1219 && lb.buffer[1] == '!')
1212 { 1220 {
@@ -3114,7 +3122,7 @@ Pascal_functions (inf)
3114 continue; 3122 continue;
3115 3123
3116 /* save all values for later tagging */ 3124 /* save all values for later tagging */
3117 grow_linebuffer (&tline, strlen (lb.buffer) + 1); 3125 grow_linebuffer (&tline, lb.len + 1);
3118 strcpy (tline.buffer, lb.buffer); 3126 strcpy (tline.buffer, lb.buffer);
3119 save_lineno = lineno; 3127 save_lineno = lineno;
3120 save_lcno = linecharno; 3128 save_lcno = linecharno;
@@ -3341,9 +3349,7 @@ char *TEX_defenv = "\
3341void TEX_mode (); 3349void TEX_mode ();
3342struct TEX_tabent *TEX_decode_env (); 3350struct TEX_tabent *TEX_decode_env ();
3343int TEX_Token (); 3351int TEX_Token ();
3344#if TeX_named_tokens 3352static void TEX_getit ();
3345void TEX_getit ();
3346#endif
3347 3353
3348char TEX_esc = '\\'; 3354char TEX_esc = '\\';
3349char TEX_opgrp = '{'; 3355char TEX_opgrp = '{';
@@ -3387,10 +3393,9 @@ TeX_functions (inf)
3387 if (0 <= i) 3393 if (0 <= i)
3388 { 3394 {
3389 pfnote ((char *)NULL, TRUE, 3395 pfnote ((char *)NULL, TRUE,
3390 lb.buffer, strlen (lb.buffer), lineno, linecharno); 3396 lb.buffer, lb.len, lineno, linecharno);
3391#if TeX_named_tokens 3397 if (TeX_named_tokens)
3392 TEX_getit (lasthit, TEX_toktab[i].len); 3398 TEX_getit (lasthit, TEX_toktab[i].len);
3393#endif
3394 break; /* We only save a line once */ 3399 break; /* We only save a line once */
3395 } 3400 }
3396 } 3401 }
@@ -3485,11 +3490,10 @@ TEX_decode_env (evarname, defenv)
3485 return tab; 3490 return tab;
3486} 3491}
3487 3492
3488#if TeX_named_tokens
3489/* Record a tag defined by a TeX command of length LEN and starting at NAME. 3493/* Record a tag defined by a TeX command of length LEN and starting at NAME.
3490 The name being defined actually starts at (NAME + LEN + 1). 3494 The name being defined actually starts at (NAME + LEN + 1).
3491 But we seem to include the TeX command in the tag name. */ 3495 But we seem to include the TeX command in the tag name. */
3492void 3496static void
3493TEX_getit (name, len) 3497TEX_getit (name, len)
3494 char *name; 3498 char *name;
3495 int len; 3499 int len;
@@ -3503,9 +3507,8 @@ TEX_getit (name, len)
3503 while (*p && *p != TEX_clgrp) 3507 while (*p && *p != TEX_clgrp)
3504 p++; 3508 p++;
3505 pfnote (savenstr (name, p-name), TRUE, 3509 pfnote (savenstr (name, p-name), TRUE,
3506 lb.buffer, strlen (lb.buffer), lineno, linecharno); 3510 lb.buffer, lb.len, lineno, linecharno);
3507} 3511}
3508#endif
3509 3512
3510/* If the text at CP matches one of the tag-defining TeX command names, 3513/* If the text at CP matches one of the tag-defining TeX command names,
3511 return the pointer to the first occurrence of that command in TEX_toktab. 3514 return the pointer to the first occurrence of that command in TEX_toktab.
@@ -4015,6 +4018,7 @@ add_regex (regexp_pattern)
4015 patbuf->buffer = NULL; 4018 patbuf->buffer = NULL;
4016 patbuf->allocated = 0; 4019 patbuf->allocated = 0;
4017 4020
4021 re_syntax_options = RE_INTERVALS;
4018 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf); 4022 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
4019 if (err != NULL) 4023 if (err != NULL)
4020 { 4024 {
@@ -4044,38 +4048,43 @@ substitute (in, out, regs)
4044 struct re_registers *regs; 4048 struct re_registers *regs;
4045{ 4049{
4046 char *result, *t; 4050 char *result, *t;
4047 int size, i; 4051 int size, dig, diglen;
4048 4052
4049 result = NULL; 4053 result = NULL;
4050 size = strlen (out); 4054 size = strlen (out);
4051 4055
4052 /* Pass 1: figure out how much size to allocate. */ 4056 /* Pass 1: figure out how much to allocate by finding all \N strings. */
4053 if (out[strlen (out) - 1] == '\\') 4057 if (out[size - 1] == '\\')
4054 fatal ("pattern error in %s", out); 4058 fatal ("pattern error in \"%s\"", out);
4055 for (t = out; *t != '\0'; ++t) 4059 for (t = etags_strchr (out, '\\');
4056 if (*t == '\\' && isdigit (*++t)) 4060 t != NULL;
4061 t = etags_strchr (t + 2, '\\'))
4062 if (isdigit (t[1]))
4057 { 4063 {
4058 int dig = *t - '0'; 4064 dig = t[1] - '0';
4059 size += regs->end[dig] - regs->start[dig] - 2; 4065 diglen = regs->end[dig] - regs->start[dig];
4066 size += diglen - 2;
4060 } 4067 }
4068 else
4069 size -= 1;
4061 4070
4062 /* Allocate space and do the substitutions. */ 4071 /* Allocate space and do the substitutions. */
4063 result = xnew (size + 1, char); 4072 result = xnew (size + 1, char);
4064 for (i = 0; *out != '\0'; ++out) 4073
4065 { 4074 for (t = result; *out != '\0'; out++)
4066 if (*out == '\\' && isdigit (*++out)) 4075 if (*out == '\\' && isdigit (*++out))
4067 { 4076 {
4068 /* Using "dig2" satisfies my debugger. Bleah. */ 4077 /* Using "dig2" satisfies my debugger. Bleah. */
4069 int dig2 = *out - '0'; 4078 dig = *out - '0';
4070 int diglen = regs->end[dig2] - regs->start[dig2]; 4079 diglen = regs->end[dig] - regs->start[dig];
4071 strncpy (result + i, in + regs->start[dig2], diglen); 4080 strncpy (t, in + regs->start[dig], diglen);
4072 i += diglen; 4081 t += diglen;
4073 } 4082 }
4074 else 4083 else
4075 result[i++] = *out; 4084 *t++ = *out;
4076 } 4085 *t = '\0';
4077 result[i] = '\0'; 4086
4078 if (DEBUG && i > size) 4087 if (DEBUG && (t > result + size || t - result != strlen (result)))
4079 abort (); 4088 abort ();
4080 4089
4081 return result; 4090 return result;
@@ -4129,7 +4138,7 @@ readline_internal (linebuffer, stream)
4129 { 4138 {
4130 if (p > buffer && p[-1] == '\r') 4139 if (p > buffer && p[-1] == '\r')
4131 { 4140 {
4132 *--p = '\0'; 4141 p -= 1;
4133#ifdef DOS_NT 4142#ifdef DOS_NT
4134 /* Assume CRLF->LF translation will be performed by Emacs 4143 /* Assume CRLF->LF translation will be performed by Emacs
4135 when loading this file, so CRs won't appear in the buffer. 4144 when loading this file, so CRs won't appear in the buffer.
@@ -4143,20 +4152,21 @@ readline_internal (linebuffer, stream)
4143 } 4152 }
4144 else 4153 else
4145 { 4154 {
4146 *p = '\0';
4147 chars_deleted = 1; 4155 chars_deleted = 1;
4148 } 4156 }
4157 *p = '\0';
4149 break; 4158 break;
4150 } 4159 }
4151 *p++ = c; 4160 *p++ = c;
4152 } 4161 }
4162 linebuffer->len = p - buffer;
4153 4163
4154 return p - buffer + chars_deleted; 4164 return linebuffer->len + chars_deleted;
4155} 4165}
4156 4166
4157/* 4167/*
4158 * Like readline_internal, above, but try to match the input 4168 * Like readline_internal, above, but in addition try to match the
4159 * line against any existing regular expressions. 4169 * input line against any existing regular expressions.
4160 */ 4170 */
4161long 4171long
4162readline (linebuffer, stream) 4172readline (linebuffer, stream)
@@ -4169,46 +4179,47 @@ readline (linebuffer, stream)
4169 int i; 4179 int i;
4170 4180
4171 /* Match against all listed patterns. */ 4181 /* Match against all listed patterns. */
4172 for (i = 0; i < num_patterns; ++i) 4182 if (linebuffer->len > 0)
4173 { 4183 for (i = 0; i < num_patterns; ++i)
4174 int match = re_match (patterns[i].pattern, linebuffer->buffer, 4184 {
4175 (int)result, 0, &patterns[i].regs); 4185 int match = re_match (patterns[i].pattern, linebuffer->buffer,
4176 switch (match) 4186 linebuffer->len, 0, &patterns[i].regs);
4177 { 4187 switch (match)
4178 case -2: 4188 {
4179 /* Some error. */ 4189 case -2:
4180 if (!patterns[i].error_signaled) 4190 /* Some error. */
4181 { 4191 if (!patterns[i].error_signaled)
4182 error ("error while matching pattern %d", i); 4192 {
4183 patterns[i].error_signaled = TRUE; 4193 error ("error while matching pattern %d", i);
4184 } 4194 patterns[i].error_signaled = TRUE;
4185 break; 4195 }
4186 case -1: 4196 break;
4187 /* No match. */ 4197 case -1:
4188 break; 4198 /* No match. */
4189 default: 4199 break;
4190 /* Match occurred. Construct a tag. */ 4200 default:
4191 if (patterns[i].name_pattern[0] != '\0') 4201 /* Match occurred. Construct a tag. */
4192 { 4202 if (patterns[i].name_pattern[0] != '\0')
4193 /* Make a named tag. */ 4203 {
4194 char *name = substitute (linebuffer->buffer, 4204 /* Make a named tag. */
4195 patterns[i].name_pattern, 4205 char *name = substitute (linebuffer->buffer,
4196 &patterns[i].regs); 4206 patterns[i].name_pattern,
4197 if (name != NULL) 4207 &patterns[i].regs);
4198 pfnote (name, TRUE, 4208 if (name != NULL)
4209 pfnote (name, TRUE,
4210 linebuffer->buffer, match, lineno, linecharno);
4211 }
4212 else
4213 {
4214 /* Make an unnamed tag. */
4215 pfnote ((char *)NULL, TRUE,
4199 linebuffer->buffer, match, lineno, linecharno); 4216 linebuffer->buffer, match, lineno, linecharno);
4200 } 4217 }
4201 else 4218 break;
4202 { 4219 }
4203 /* Make an unnamed tag. */ 4220 }
4204 pfnote ((char *)NULL, TRUE,
4205 linebuffer->buffer, match, lineno, linecharno);
4206 }
4207 break;
4208 }
4209 }
4210#endif /* ETAGS_REGEXPS */ 4221#endif /* ETAGS_REGEXPS */
4211 4222
4212 return result; 4223 return result;
4213} 4224}
4214 4225