diff options
| author | Francesco Potortì | 1997-04-30 14:57:39 +0000 |
|---|---|---|
| committer | Francesco Potortì | 1997-04-30 14:57:39 +0000 |
| commit | e0903a92eaaf1fbac37eeb92e4c44c35e9f3ea17 (patch) | |
| tree | e45626a8b518f6199b4ce9144f51a599c7914981 | |
| parent | 39445e62161bcaf9b905eda1e9fd325c8d1d7ee1 (diff) | |
| download | emacs-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.c | 171 |
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 | ||
| 34 | char pot_etags_version[] = "@(#) pot revision number is $Revision: 11.84 $"; | 34 | char 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 | */ |
| 249 | struct linebuffer | 255 | struct 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 = "\ | |||
| 3341 | void TEX_mode (); | 3349 | void TEX_mode (); |
| 3342 | struct TEX_tabent *TEX_decode_env (); | 3350 | struct TEX_tabent *TEX_decode_env (); |
| 3343 | int TEX_Token (); | 3351 | int TEX_Token (); |
| 3344 | #if TeX_named_tokens | 3352 | static void TEX_getit (); |
| 3345 | void TEX_getit (); | ||
| 3346 | #endif | ||
| 3347 | 3353 | ||
| 3348 | char TEX_esc = '\\'; | 3354 | char TEX_esc = '\\'; |
| 3349 | char TEX_opgrp = '{'; | 3355 | char 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. */ |
| 3492 | void | 3496 | static void |
| 3493 | TEX_getit (name, len) | 3497 | TEX_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 | */ |
| 4161 | long | 4171 | long |
| 4162 | readline (linebuffer, stream) | 4172 | readline (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 | ||