PostgreSQL Source Code git master
lexi.c
Go to the documentation of this file.
1/*-
2 * Copyright (c) 1985 Sun Microsystems, Inc.
3 * Copyright (c) 1980, 1993
4 * The Regents of the University of California. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#if 0
33#ifndef lint
34static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93";
35#endif /* not lint */
36#endif
37
38#include "c.h"
39
40/*
41 * Here we have the token scanner for indent. It scans off one token and puts
42 * it in the global variable "token". It returns a code, indicating the type
43 * of token scanned.
44 */
45
46#include <err.h>
47#include <stdio.h>
48#include <ctype.h>
49#include <stdlib.h>
50#include <string.h>
51#include "indent_globs.h"
52#include "indent_codes.h"
53#include "indent.h"
54
55#define alphanum 1
56#ifdef undef
57#define opchar 3
58#endif
59
60struct templ {
61 const char *rwd;
62 int rwcode;
63};
64
65/*
66 * This table has to be sorted alphabetically, because it'll be used in binary
67 * search. For the same reason, string must be the first thing in struct templ.
68 */
69struct templ specials[] =
70{
71 {"_Bool", 4},
72 {"_Complex", 4},
73 {"_Imaginary", 4},
74 {"auto", 10},
75 {"bool", 4},
76 {"break", 9},
77 {"case", 8},
78 {"char", 4},
79 {"complex", 4},
80 {"const", 4},
81 {"continue", 12},
82 {"default", 8},
83 {"do", 6},
84 {"double", 4},
85 {"else", 6},
86 {"enum", 3},
87 {"extern", 10},
88 {"float", 4},
89 {"for", 5},
90 {"global", 4},
91 {"goto", 9},
92 {"if", 5},
93 {"imaginary", 4},
94 {"inline", 12},
95 {"int", 4},
96 {"long", 4},
97 {"offsetof", 1},
98 {"register", 10},
99 {"restrict", 12},
100 {"return", 9},
101 {"short", 4},
102 {"signed", 4},
103 {"sizeof", 2},
104 {"static", 10},
105 {"struct", 3},
106 {"switch", 7},
107 {"typedef", 11},
108 {"union", 3},
109 {"unsigned", 4},
110 {"void", 4},
111 {"volatile", 4},
112 {"while", 5}
113};
114
115const char **typenames;
118
119char chartype[128] =
120{ /* this is used to facilitate the decision of
121 * what type (alphanumeric, operator) each
122 * character is */
123 0, 0, 0, 0, 0, 0, 0, 0,
124 0, 0, 0, 0, 0, 0, 0, 0,
125 0, 0, 0, 0, 0, 0, 0, 0,
126 0, 0, 0, 0, 0, 0, 0, 0,
127 0, 3, 0, 0, 1, 3, 3, 0,
128 0, 0, 3, 3, 0, 3, 0, 3,
129 1, 1, 1, 1, 1, 1, 1, 1,
130 1, 1, 0, 0, 3, 3, 3, 3,
131 0, 1, 1, 1, 1, 1, 1, 1,
132 1, 1, 1, 1, 1, 1, 1, 1,
133 1, 1, 1, 1, 1, 1, 1, 1,
134 1, 1, 1, 0, 0, 0, 3, 1,
135 0, 1, 1, 1, 1, 1, 1, 1,
136 1, 1, 1, 1, 1, 1, 1, 1,
137 1, 1, 1, 1, 1, 1, 1, 1,
138 1, 1, 1, 0, 3, 0, 3, 0
139};
140
141static int
142strcmp_type(const void *e1, const void *e2)
143{
144 return (strcmp(e1, *(const char * const *)e2));
145}
146
147/*
148 * Decide whether "foo(..." is a function definition or declaration.
149 *
150 * At call, we are looking at the '('. Look ahead to find the first
151 * '{', ';' or ',' that is not within parentheses or comments; then
152 * it's a definition if we found '{', otherwise a declaration.
153 * Note that this rule is fooled by K&R-style parameter declarations,
154 * but telling the difference between those and function attributes
155 * seems like more trouble than it's worth. This code could also be
156 * fooled by mismatched parens or apparent comment starts within string
157 * literals, but that seems unlikely in the context it's used in.
158 */
159static int
161{
162 int paren_depth = 0;
163 int in_comment = false;
164 int in_slash_comment = false;
165 int lastc = 0;
166
167 /* We may need to look past the end of the current buffer. */
169 for (;;) {
170 int c;
171
172 /* Fetch next character. */
173 if (tp < buf_end)
174 c = *tp++;
175 else {
176 c = lookahead();
177 if (c == EOF)
178 break;
179 }
180 /* Handle comments. */
181 if (in_comment) {
182 if (lastc == '*' && c == '/')
183 in_comment = false;
184 } else if (lastc == '/' && c == '*' && !in_slash_comment)
185 in_comment = true;
186 else if (in_slash_comment) {
187 if (c == '\n')
188 in_slash_comment = false;
189 } else if (lastc == '/' && c == '/')
190 in_slash_comment = true;
191 /* Count nested parens properly. */
192 else if (c == '(')
193 paren_depth++;
194 else if (c == ')') {
195 paren_depth--;
196 /*
197 * If we find unbalanced parens, we must have started inside a
198 * declaration.
199 */
200 if (paren_depth < 0)
201 return false;
202 } else if (paren_depth == 0) {
203 /* We are outside any parentheses or comments. */
204 if (c == '{')
205 return true;
206 else if (c == ';' || c == ',')
207 return false;
208 }
209 lastc = c;
210 }
211 /* Hit EOF --- for lack of anything better, assume "not a definition". */
212 return false;
213}
214
215int
217{
218 int unary_delim; /* this is set to 1 if the current token
219 * forces a following operator to be unary */
220 int code; /* internal code to be returned */
221 char qchar; /* the delimiter character for a string */
222
223 e_token = s_token; /* point to start of place to save token */
224 unary_delim = false;
225 state->col_1 = state->last_nl; /* tell world that this token started
226 * in column 1 iff the last thing
227 * scanned was a newline */
228 state->last_nl = false;
229
230 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
231 state->col_1 = false; /* leading blanks imply token is not in column
232 * 1 */
233 if (++buf_ptr >= buf_end)
234 fill_buffer();
235 }
236
237 /* Scan an alphanumeric token */
238 if (chartype[*buf_ptr & 127] == alphanum ||
239 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
240 /*
241 * we have a character or number
242 */
243 struct templ *p;
244
245 if (isdigit((unsigned char)*buf_ptr) ||
246 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
247 int seendot = 0,
248 seenexp = 0,
249 seensfx = 0;
250
251 /*
252 * base 2, base 8, base 16:
253 */
254 if (buf_ptr[0] == '0' && buf_ptr[1] != '.') {
255 int len;
256
257 if (buf_ptr[1] == 'b' || buf_ptr[1] == 'B')
258 len = strspn(buf_ptr + 2, "01") + 2;
259 else if (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')
260 len = strspn(buf_ptr + 2, "0123456789ABCDEFabcdef") + 2;
261 else
262 len = strspn(buf_ptr + 1, "012345678") + 1;
263 if (len > 0) {
265 memcpy(e_token, buf_ptr, len);
266 e_token += len;
267 buf_ptr += len;
268 }
269 else
270 diag2(1, "Unterminated literal");
271 }
272 else /* base 10: */
273 while (1) {
274 if (*buf_ptr == '.') {
275 if (seendot)
276 break;
277 else
278 seendot++;
279 }
281 *e_token++ = *buf_ptr++;
282 if (!isdigit((unsigned char)*buf_ptr) && *buf_ptr != '.') {
283 if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
284 break;
285 else {
286 seenexp++;
287 seendot++;
288 *e_token++ = *buf_ptr++;
289 if (*buf_ptr == '+' || *buf_ptr == '-')
290 *e_token++ = *buf_ptr++;
291 }
292 }
293 }
294
295 while (1) {
297 if (!(seensfx & 1) && (*buf_ptr == 'U' || *buf_ptr == 'u')) {
298 *e_token++ = *buf_ptr++;
299 seensfx |= 1;
300 continue;
301 }
302 if (!(seensfx & 2) && (strchr("fFlL", *buf_ptr) != NULL)) {
303 if (buf_ptr[1] == buf_ptr[0])
304 *e_token++ = *buf_ptr++;
305 *e_token++ = *buf_ptr++;
306 seensfx |= 2;
307 continue;
308 }
309 break;
310 }
311 }
312 else
313 while (chartype[*buf_ptr & 127] == alphanum || *buf_ptr == BACKSLASH) {
314 /* fill_buffer() terminates buffer with newline */
315 if (*buf_ptr == BACKSLASH) {
316 if (*(buf_ptr + 1) == '\n') {
317 buf_ptr += 2;
318 if (buf_ptr >= buf_end)
319 fill_buffer();
320 } else
321 break;
322 }
324 /* copy it over */
325 *e_token++ = *buf_ptr++;
326 if (buf_ptr >= buf_end)
327 fill_buffer();
328 }
329 *e_token = '\0';
330
331 if (s_token[0] == 'L' && s_token[1] == '\0' &&
332 (*buf_ptr == '"' || *buf_ptr == '\''))
333 return (strpfx);
334
335 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
336 if (++buf_ptr >= buf_end)
337 fill_buffer();
338 }
339 state->keyword = 0;
340 if (state->last_token == structure && !state->p_l_follow) {
341 /* if last token was 'struct' and we're not
342 * in parentheses, then this token
343 * should be treated as a declaration */
344 state->last_u_d = true;
345 return (decl);
346 }
347 /*
348 * Operator after identifier is binary unless last token was 'struct'
349 */
350 state->last_u_d = (state->last_token == structure);
351
352 p = bsearch(s_token,
353 specials,
354 sizeof(specials) / sizeof(specials[0]),
355 sizeof(specials[0]),
357 if (p == NULL) { /* not a special keyword... */
358 char *u;
359
360 /* ... so maybe a type_t or a typedef */
361 if ((auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) &&
362 strcmp(u, "_t") == 0) || (typename_top >= 0 &&
363 bsearch(s_token, typenames, typename_top + 1,
364 sizeof(typenames[0]), strcmp_type))) {
365 state->keyword = 4; /* a type name */
366 state->last_u_d = true;
367 goto found_typename;
368 }
369 } else { /* we have a keyword */
370 state->keyword = p->rwcode;
371 state->last_u_d = true;
372 switch (p->rwcode) {
373 case 7: /* it is a switch */
374 return (swstmt);
375 case 8: /* a case or default */
376 return (casestmt);
377
378 case 3: /* a "struct" */
379 /* FALLTHROUGH */
380 case 4: /* one of the declaration keywords */
381 found_typename:
382 if (state->p_l_follow) {
383 /* inside parens: cast, param list, offsetof or sizeof */
384 state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask;
385 }
386 if (state->last_token == period || state->last_token == unary_op) {
387 state->keyword = 0;
388 break;
389 }
390 if (p != NULL && p->rwcode == 3)
391 return (structure);
392 if (state->p_l_follow)
393 break;
394 return (decl);
395
396 case 5: /* if, while, for */
397 return (sp_paren);
398
399 case 6: /* do, else */
400 return (sp_nparen);
401
402 case 10: /* storage class specifier */
403 return (storage);
404
405 case 11: /* typedef */
406 return (type_def);
407
408 default: /* all others are treated like any other
409 * identifier */
410 return (ident);
411 } /* end of switch */
412 } /* end of if (found_it) */
413 if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 &&
414 state->in_parameter_declaration == 0 && state->block_init == 0) {
416 strncpy(state->procname, token, sizeof state->procname - 1);
417 if (state->in_decl)
418 state->in_parameter_declaration = 1;
419 return (funcname);
420 }
421 }
422 /*
423 * The following hack attempts to guess whether or not the current
424 * token is in fact a declaration keyword -- one that has been
425 * typedefd
426 */
427 else if (!state->p_l_follow && !state->block_init &&
428 !state->in_stmt &&
429 ((*buf_ptr == '*' && buf_ptr[1] != '=') ||
430 isalpha((unsigned char)*buf_ptr)) &&
431 (state->last_token == semicolon || state->last_token == lbrace ||
432 state->last_token == rbrace)) {
433 state->keyword = 4; /* a type name */
434 state->last_u_d = true;
435 return decl;
436 }
437 if (state->last_token == decl) /* if this is a declared variable,
438 * then following sign is unary */
439 state->last_u_d = true; /* will make "int a -1" work */
440 return (ident); /* the ident is not in the list */
441 } /* end of processing for alphanum character */
442
443 /* Scan a non-alphanumeric token */
444
445 CHECK_SIZE_TOKEN(3); /* things like "<<=" */
446 *e_token++ = *buf_ptr; /* if it is only a one-character token, it is
447 * moved here */
448 *e_token = '\0';
449 if (++buf_ptr >= buf_end)
450 fill_buffer();
451
452 switch (*token) {
453 case '\n':
454 unary_delim = state->last_u_d;
455 state->last_nl = true; /* remember that we just had a newline */
456 code = (had_eof ? 0 : newline);
457
458 /*
459 * if data has been exhausted, the newline is a dummy, and we should
460 * return code to stop
461 */
462 break;
463
464 case '\'': /* start of quoted character */
465 case '"': /* start of string */
466 qchar = *token;
467 do { /* copy the string */
468 while (1) { /* move one character or [/<char>]<char> */
469 if (*buf_ptr == '\n') {
470 diag2(1, "Unterminated literal");
471 goto stop_lit;
472 }
474 *e_token = *buf_ptr++;
475 if (buf_ptr >= buf_end)
476 fill_buffer();
477 if (*e_token == BACKSLASH) { /* if escape, copy extra char */
478 if (*buf_ptr == '\n') /* check for escaped newline */
479 ++line_no;
480 *++e_token = *buf_ptr++;
481 ++e_token; /* we must increment this again because we
482 * copied two chars */
483 if (buf_ptr >= buf_end)
484 fill_buffer();
485 }
486 else
487 break; /* we copied one character */
488 } /* end of while (1) */
489 } while (*e_token++ != qchar);
490stop_lit:
491 code = ident;
492 break;
493
494 case ('('):
495 case ('['):
496 unary_delim = true;
497 code = lparen;
498 break;
499
500 case (')'):
501 case (']'):
502 code = rparen;
503 break;
504
505 case '#':
506 unary_delim = state->last_u_d;
507 code = preesc;
508 break;
509
510 case '?':
511 unary_delim = true;
512 code = question;
513 break;
514
515 case (':'):
516 code = colon;
517 unary_delim = true;
518 break;
519
520 case (';'):
521 unary_delim = true;
522 code = semicolon;
523 break;
524
525 case ('{'):
526 unary_delim = true;
527
528 /*
529 * if (state->in_or_st) state->block_init = 1;
530 */
531 /* ? code = state->block_init ? lparen : lbrace; */
532 code = lbrace;
533 break;
534
535 case ('}'):
536 unary_delim = true;
537 /* ? code = state->block_init ? rparen : rbrace; */
538 code = rbrace;
539 break;
540
541 case 014: /* a form feed */
542 unary_delim = state->last_u_d;
543 state->last_nl = true; /* remember this so we can set 'state->col_1'
544 * right */
545 code = form_feed;
546 break;
547
548 case (','):
549 unary_delim = true;
550 code = comma;
551 break;
552
553 case '.':
554 unary_delim = false;
555 code = period;
556 break;
557
558 case '-':
559 case '+': /* check for -, +, --, ++ */
560 code = (state->last_u_d ? unary_op : binary_op);
561 unary_delim = true;
562
563 if (*buf_ptr == token[0]) {
564 /* check for doubled character */
565 *e_token++ = *buf_ptr++;
566 /* buffer overflow will be checked at end of loop */
567 if (state->last_token == ident || state->last_token == rparen) {
568 code = (state->last_u_d ? unary_op : postop);
569 /* check for following ++ or -- */
570 unary_delim = false;
571 }
572 }
573 else if (*buf_ptr == '=')
574 /* check for operator += */
575 *e_token++ = *buf_ptr++;
576 else if (*buf_ptr == '>') {
577 /* check for operator -> */
578 *e_token++ = *buf_ptr++;
579 unary_delim = false;
580 code = unary_op;
581 state->want_blank = false;
582 }
583 break; /* buffer overflow will be checked at end of
584 * switch */
585
586 case '=':
587 if (state->in_or_st)
588 state->block_init = 1;
589#ifdef undef
590 if (chartype[*buf_ptr & 127] == opchar) { /* we have two char assignment */
591 e_token[-1] = *buf_ptr++;
592 if ((e_token[-1] == '<' || e_token[-1] == '>') && e_token[-1] == *buf_ptr)
593 *e_token++ = *buf_ptr++;
594 *e_token++ = '='; /* Flip =+ to += */
595 *e_token = 0;
596 }
597#else
598 if (*buf_ptr == '=') {/* == */
599 *e_token++ = '='; /* Flip =+ to += */
600 buf_ptr++;
601 *e_token = 0;
602 }
603#endif
604 code = binary_op;
605 unary_delim = true;
606 break;
607 /* can drop thru!!! */
608
609 case '>':
610 case '<':
611 case '!': /* ops like <, <<, <=, !=, etc */
612 if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
613 *e_token++ = *buf_ptr;
614 if (++buf_ptr >= buf_end)
615 fill_buffer();
616 }
617 if (*buf_ptr == '=')
618 *e_token++ = *buf_ptr++;
619 code = (state->last_u_d ? unary_op : binary_op);
620 unary_delim = true;
621 break;
622
623 case '*':
624 unary_delim = true;
625 if (!state->last_u_d) {
626 if (*buf_ptr == '=')
627 *e_token++ = *buf_ptr++;
628 code = binary_op;
629 break;
630 }
631 while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) {
632 if (*buf_ptr == '*') {
634 *e_token++ = *buf_ptr;
635 }
636 if (++buf_ptr >= buf_end)
637 fill_buffer();
638 }
639 code = unary_op;
640 break;
641
642 default:
643 if (token[0] == '/' && *buf_ptr == '*') {
644 /* it is start of comment */
645 *e_token++ = '*';
646
647 if (++buf_ptr >= buf_end)
648 fill_buffer();
649
650 code = comment;
651 unary_delim = state->last_u_d;
652 break;
653 }
654 while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') {
655 /*
656 * handle ||, &&, etc, and also things as in int *****i
657 */
659 *e_token++ = *buf_ptr;
660 if (++buf_ptr >= buf_end)
661 fill_buffer();
662 }
663 code = (state->last_u_d ? unary_op : binary_op);
664 unary_delim = true;
665
666
667 } /* end of switch */
668 if (buf_ptr >= buf_end) /* check for input buffer empty */
669 fill_buffer();
670 state->last_u_d = unary_delim;
672 *e_token = '\0'; /* null terminate the token */
673 return (code);
674}
675
676void
678{
679
680 typenames = (const char **)malloc(sizeof(typenames[0]) *
681 (typename_count = 16));
682 if (typenames == NULL)
683 err(1, NULL);
684}
685
686void
687add_typename(const char *key)
688{
689 int comparison;
690 const char *copy;
691
692 if (typename_top + 1 >= typename_count) {
693 typenames = realloc((void *)typenames,
694 sizeof(typenames[0]) * (typename_count *= 2));
695 if (typenames == NULL)
696 err(1, NULL);
697 }
698 if (typename_top == -1)
699 typenames[++typename_top] = copy = strdup(key);
700 else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) {
701 /* take advantage of sorted input */
702 if (comparison == 0) /* remove duplicates */
703 return;
704 typenames[++typename_top] = copy = strdup(key);
705 }
706 else {
707 int p;
708
709 for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++)
710 /* find place for the new key */;
711 if (comparison == 0) /* remove duplicates */
712 return;
713 memmove(&typenames[p + 1], &typenames[p],
714 sizeof(typenames[0]) * (++typename_top - p));
715 typenames[p] = copy = strdup(key);
716 }
717
718 if (copy == NULL)
719 err(1, NULL);
720}
void err(int eval, const char *fmt,...)
Definition: err.c:43
#define realloc(a, b)
Definition: header.h:60
#define malloc(a)
Definition: header.h:50
int lookahead(void)
Definition: io.c:275
void diag2(int, const char *)
Definition: io.c:590
void lookahead_reset(void)
Definition: io.c:320
void fill_buffer(void)
Definition: io.c:346
#define comma
Definition: indent_codes.h:48
#define form_feed
Definition: indent_codes.h:52
#define lparen
Definition: indent_codes.h:36
#define swstmt
Definition: indent_codes.h:50
#define sp_nparen
Definition: indent_codes.h:55
#define rbrace
Definition: indent_codes.h:46
#define colon
Definition: indent_codes.h:43
#define postop
Definition: indent_codes.h:40
#define period
Definition: indent_codes.h:66
#define comment
Definition: indent_codes.h:49
#define question
Definition: indent_codes.h:41
#define lbrace
Definition: indent_codes.h:45
#define semicolon
Definition: indent_codes.h:44
#define ident
Definition: indent_codes.h:47
#define type_def
Definition: indent_codes.h:70
#define preesc
Definition: indent_codes.h:51
#define structure
Definition: indent_codes.h:71
#define funcname
Definition: indent_codes.h:69
#define binary_op
Definition: indent_codes.h:39
#define casestmt
Definition: indent_codes.h:42
#define storage
Definition: indent_codes.h:68
#define newline
Definition: indent_codes.h:35
#define sp_paren
Definition: indent_codes.h:54
#define decl
Definition: indent_codes.h:53
#define unary_op
Definition: indent_codes.h:38
#define strpfx
Definition: indent_codes.h:67
#define rparen
Definition: indent_codes.h:37
int auto_typedefs
#define token
Definition: indent_globs.h:126
int had_eof
#define CHECK_SIZE_TOKEN(desired_size)
Definition: indent_globs.h:99
char * buf_ptr
char * e_token
int line_no
char * buf_end
char * s_token
#define BACKSLASH
Definition: indent_globs.h:35
void add_typename(const char *key)
Definition: lexi.c:687
char chartype[128]
Definition: lexi.c:119
int typename_count
Definition: lexi.c:116
static int strcmp_type(const void *e1, const void *e2)
Definition: lexi.c:142
int typename_top
Definition: lexi.c:117
int lexi(struct parser_state *state)
Definition: lexi.c:216
const char ** typenames
Definition: lexi.c:115
void alloc_typenames(void)
Definition: lexi.c:677
static int is_func_definition(char *tp)
Definition: lexi.c:160
#define alphanum
Definition: lexi.c:55
struct templ specials[]
Definition: lexi.c:69
const void size_t len
char * c
Definition: regguts.h:323
Definition: lexi.c:60
const char * rwd
Definition: lexi.c:61
int rwcode
Definition: lexi.c:62