summaryrefslogtreecommitdiffstats
path: root/contrib/bind/bin/named/ns_lexer.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/bin/named/ns_lexer.c')
-rw-r--r--contrib/bind/bin/named/ns_lexer.c826
1 files changed, 0 insertions, 826 deletions
diff --git a/contrib/bind/bin/named/ns_lexer.c b/contrib/bind/bin/named/ns_lexer.c
deleted file mode 100644
index 3c09cf0..0000000
--- a/contrib/bind/bin/named/ns_lexer.c
+++ /dev/null
@@ -1,826 +0,0 @@
-#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: ns_lexer.c,v 8.31.10.1 2003/06/02 09:56:35 marka Exp $";
-#endif /* not lint */
-
-/*
- * Copyright (c) 1996-2000 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#include "port_before.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <arpa/inet.h>
-
-#include <resolv.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-#include <stdarg.h>
-#include <syslog.h>
-
-#include <isc/eventlib.h>
-#include <isc/logging.h>
-#include <isc/memcluster.h>
-
-#include "port_after.h"
-
-#include "named.h"
-#include "ns_parser.h"
-#include "ns_parseutil.h"
-#include "ns_lexer.h"
-
-typedef enum lexer_state {
- scan, number, identifier, ipv4, quoted_string
-} LexerState;
-
-#define LEX_EOF 0x01
-#define LEXER_MAX_PUSHBACK 2
-
-typedef struct lexer_file_context {
- char * name;
- FILE * stream;
- int line_number;
- LexerState state;
- u_int flags;
- int warnings;
- int errors;
- u_int pushback_count;
- char pushback[LEXER_MAX_PUSHBACK];
- struct lexer_file_context *
- next;
-} *LexerFileContext;
-
-LexerFileContext current_file = NULL;
-
-#define LEX_LAST_WAS_DOT 0x01
-#define LEX_CONSECUTIVE_DOTS 0x02
-
-typedef struct lexer_identifier {
- char buffer[LEX_MAX_IDENT_SIZE+1];
- int index;
- int num_dots;
- unsigned int flags;
-} *LexerIdentifier;
-
-static LexerIdentifier id;
-
-static char special_chars[256];
-
-#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
-#define domain_char(c) (isalnum((c)) || (c) == '.' || (c) == '-')
-#define special_char(c) (special_chars[(c)] == 1)
-#define identifier_char(c) (!whitespace(c) && !special_char(c))
-
-static int last_token;
-static YYSTYPE last_yylval;
-
-static int lexer_initialized = 0;
-
-/*
- * Problem Reporting
- */
-
-static char *
-token_to_text(int token, YYSTYPE lval) {
- static char buffer[LEX_MAX_IDENT_SIZE+50];
-
- if (token < 128) {
- if (token == 0)
- strcpy(buffer, "<end of file>");
- else
- sprintf(buffer, "'%c'", token);
- } else {
- switch (token) {
- case L_EOS:
- strcpy(buffer, ";");
- break;
- case L_STRING:
- sprintf(buffer, "'%s'", lval.cp);
- break;
- case L_QSTRING:
- sprintf(buffer, "\"%s\"", lval.cp);
- break;
- case L_IPADDR:
- sprintf(buffer, "%s", inet_ntoa(lval.ip_addr));
- break;
- case L_NUMBER:
- sprintf(buffer, "%ld", lval.num);
- break;
- case L_END_INCLUDE:
- sprintf(buffer, "<end of include>");
- break;
- default:
- sprintf(buffer, "%s", lval.cp);
- }
- }
-
- return (buffer);
-}
-
-static char where[MAXPATHLEN + 100];
-static char message[20480];
-
-static void
-parser_complain(int is_warning, int print_last_token, const char *format,
- va_list args) ISC_FORMAT_PRINTF(3, 0);
-
-static void
-parser_complain(int is_warning, int print_last_token, const char *format,
- va_list args)
-{
- LexerFileContext lf;
- int severity;
-
- if (is_warning) {
- severity = log_warning;
- } else {
- severity = log_error;
- }
-
- INSIST(current_file != NULL);
- if (current_file->next != NULL) {
- for (lf = current_file; lf != NULL; lf = lf->next) {
- log_write(log_ctx, ns_log_parser, severity,
- "%s '%s' line %d",
- (lf == current_file) ?
- "In" : "included from",
- lf->name, lf->line_number);
- }
- }
- sprintf(where, "%s:%d: ", current_file->name,
- current_file->line_number);
- vsprintf(message, format, args);
- if (print_last_token)
- log_write(log_ctx, ns_log_parser, severity, "%s%s near %s",
- where, message,
- token_to_text(last_token, last_yylval));
- else
- log_write(log_ctx, ns_log_parser, severity,
- "%s%s", where, message);
-}
-
-int
-parser_warning(int print_last_token, const char *format, ...) {
- va_list args;
-
- va_start(args, format);
- parser_complain(1, print_last_token, format, args);
- va_end(args);
- current_file->warnings++;
- return (1);
-}
-
-int
-parser_error(int print_last_token, const char *format, ...) {
- va_list args;
-
- va_start(args, format);
- parser_complain(0, print_last_token, format, args);
- va_end(args);
- current_file->errors++;
- return (1);
-}
-
-void
-yyerror(const char *message) {
- parser_error(1, "%s", message);
-}
-
-/*
- * Keywords
- */
-
-struct keyword {
- const char *name;
- int token;
-};
-
-/*
- * "keywords" is an array of the keywords which are the fixed syntactic
- * elements of the configuration file. Each keyword has a string version
- * of the keyword and a token id, which should be an identifier which
- * matches that in a %token statement inside the parser.y file.
- */
-static struct keyword keywords[] = {
- {"acl", T_ACL},
- {"address", T_ADDRESS},
- {"algorithm", T_ALGID},
- {"allow", T_ALLOW},
- {"allow-query", T_ALLOW_QUERY},
- {"allow-recursion", T_ALLOW_RECURSION},
- {"allow-transfer", T_ALLOW_TRANSFER},
- {"allow-update", T_ALLOW_UPDATE},
-#ifdef BIND_NOTIFY
- {"also-notify", T_ALSO_NOTIFY},
-#endif
- {"auth-nxdomain", T_AUTH_NXDOMAIN},
- {"blackhole", T_BLACKHOLE},
- {"bogus", T_BOGUS},
- {"category", T_CATEGORY},
- {"class", T_CLASS},
- {"channel", T_CHANNEL},
- {"check-names", T_CHECK_NAMES},
- {"cleaning-interval", T_CLEAN_INTERVAL},
- {"controls", T_CONTROLS},
- {"coresize", T_CORESIZE},
- {"datasize", T_DATASIZE},
- {"deallocate-on-exit", T_DEALLOC_ON_EXIT},
- {"debug", T_DEBUG},
- {"default", T_DEFAULT},
- {"dialup", T_DIALUP},
- {"directory", T_DIRECTORY},
- {"dump-file", T_DUMP_FILE},
- {"dynamic", T_DYNAMIC},
- {"edns", T_EDNS},
- {"edns-udp-size", T_EDNS_UDP_SIZE},
- {"explicit", T_EXPLICIT},
- {"fail", T_FAIL},
- {"fake-iquery", T_FAKE_IQUERY},
- {"false", T_FALSE},
- {"fetch-glue", T_FETCH_GLUE},
- {"file", T_FILE},
- {"files", T_FILES},
- {"first", T_FIRST},
- {"forward", T_FORWARD},
- {"forwarders", T_FORWARDERS},
- {"group", T_GROUP},
- {"has-old-clients", T_HAS_OLD_CLIENTS},
- {"heartbeat-interval", T_HEARTBEAT},
- {"hint", T_HINT},
-#ifdef HITCOUNTS
- {"hit-count", T_HITCOUNT},
-#endif /* HITCOUNTS */
- {"host-statistics", T_HOSTSTATS},
- {"host-statistics-max", T_HOSTSTATSMAX},
- {"hostname", T_HOSTNAME},
- {"if-no-answer", T_IF_NO_ANSWER},
- {"if-no-domain", T_IF_NO_DOMAIN},
- {"ignore", T_IGNORE},
- {"include", T_INCLUDE},
- {"inet", T_INET},
- {"interface-interval", T_INTERFACE_INTERVAL},
- {"ixfr-base", T_FILE_IXFR},
- {"ixfr-tmp-file", T_IXFR_TMP},
- {"key", T_SEC_KEY},
- {"keys", T_KEYS},
- {"lame-ttl", T_LAME_TTL},
- {"listen-on", T_LISTEN_ON},
- {"logging", T_LOGGING},
- {"maintain-ixfr-base", T_MAINTAIN_IXFR_BASE},
- {"many-answers", T_MANY_ANSWERS},
- {"master", T_MASTER},
- {"masters", T_MASTERS},
- {"max-ixfr-log-size", T_MAX_LOG_SIZE_IXFR},
- {"max-ncache-ttl", T_MAX_NCACHE_TTL},
- {"max-transfer-time-in", T_MAX_TRANSFER_TIME_IN},
- {"memstatistics-file", T_MEMSTATS_FILE},
- {"min-roots", T_MIN_ROOTS},
- {"multiple-cnames", T_MULTIPLE_CNAMES},
- {"name", T_NAME},
- {"named-xfer", T_NAMED_XFER},
- {"no", T_NO},
-#ifdef BIND_NOTIFY
- {"notify", T_NOTIFY},
-#endif
- {"null", T_NULL_OUTPUT},
- {"one-answer", T_ONE_ANSWER},
- {"only", T_ONLY},
- {"order", T_ORDER},
- {"options", T_OPTIONS},
- {"owner", T_OWNER},
- {"perm", T_PERM},
- {"pid-file", T_PIDFILE},
- {"port", T_PORT},
- {"preferred-glue", T_PREFERRED_GLUE},
- {"print-category", T_PRINT_CATEGORY},
- {"print-severity", T_PRINT_SEVERITY},
- {"print-time", T_PRINT_TIME},
- {"pubkey", T_PUBKEY},
- {"query-source", T_QUERY_SOURCE},
- {"rfc2308-type1", T_RFC2308_TYPE1},
- {"rrset-order", T_RRSET_ORDER},
- {"recursion", T_RECURSION},
- {"response", T_RESPONSE},
- {"secret", T_SECRET},
- {"serial-queries", T_SERIAL_QUERIES},
- {"server", T_SERVER},
- {"severity", T_SEVERITY},
- {"size", T_SIZE},
- {"slave", T_SLAVE},
- {"sortlist", T_SORTLIST},
- {"stacksize", T_STACKSIZE},
- {"statistics-file", T_STATS_FILE},
- {"statistics-interval", T_STATS_INTERVAL},
- {"stub", T_STUB},
- {"support-ixfr", T_SUPPORT_IXFR},
-#ifdef BIND_NOTIFY
- {"suppress-initial-notify", T_NOTIFY_INITIAL},
-#endif
- {"syslog", T_SYSLOG},
- {"topology", T_TOPOLOGY},
- {"transfer-format", T_TRANSFER_FORMAT},
- {"transfer-source", T_TRANSFER_SOURCE},
- {"transfers", T_TRANSFERS},
- {"transfers-in", T_TRANSFERS_IN},
- {"transfers-out", T_TRANSFERS_OUT},
- {"transfers-per-ns", T_TRANSFERS_PER_NS},
- {"treat-cr-as-space", T_TREAT_CR_AS_SPACE},
- {"true", T_TRUE},
- {"trusted-keys", T_TRUSTED_KEYS},
- {"type", T_TYPE},
- {"unix", T_UNIX},
- {"unlimited", T_UNLIMITED},
- {"use-id-pool", T_USE_ID_POOL},
- {"use-ixfr", T_USE_IXFR},
- {"version", T_VERSION},
- {"versions", T_VERSIONS},
- {"warn", T_WARN},
- {"yes", T_YES},
- {"zone", T_ZONE},
- {(char *) NULL, 0},
-};
-
-/*
- * The table size should be a prime chosen to minimize collisions.
- */
-#define KEYWORD_TABLE_SIZE 461
-
-static symbol_table keyword_table = NULL;
-
-static void
-init_keywords() {
- struct keyword *k;
- symbol_value value;
-
- if (keyword_table != NULL)
- free_symbol_table(keyword_table);
- keyword_table = new_symbol_table(KEYWORD_TABLE_SIZE, NULL);
- for (k = keywords; k->name != NULL; k++) {
- value.integer = k->token;
- define_symbol(keyword_table, k->name, 0, value, 0);
- }
- dprint_symbol_table(99, keyword_table);
-}
-
-/*
- * File Contexts
- */
-
-void
-lexer_begin_file(const char *filename, FILE *stream) {
- LexerFileContext lf;
-
- if (stream == NULL) {
- stream = fopen(filename, "r");
- if (stream == NULL) {
- parser_error(0, "couldn't open include file '%s'",
- filename);
- return;
- }
- }
- lf = (LexerFileContext)memget(sizeof (struct lexer_file_context));
- if (lf == NULL)
- panic("memget failed in lexer_begin_file", NULL);
- INSIST(stream != NULL);
- lf->stream = stream;
- lf->name = savestr(filename, 1);
- lf->line_number = 1;
- lf->state = scan;
- lf->flags = 0;
- lf->warnings = 0;
- lf->errors = 0;
- lf->pushback_count = 0;
- lf->next = current_file;
- current_file = lf;
-}
-
-void
-lexer_end_file(void) {
- LexerFileContext lf;
-
- INSIST(current_file != NULL);
- lf = current_file;
- current_file = lf->next;
- fclose(lf->stream);
- freestr(lf->name);
- memput(lf, sizeof *lf);
-}
-
-/*
- * Character Input
- */
-
-#define LEXER_GETC(c, cf) \
- do { \
- if ((cf)->pushback_count > 0) { \
- (cf)->pushback_count--; \
- (c) = (cf)->pushback[(cf)->pushback_count]; \
- } else \
- (c) = getc((cf)->stream); \
- } while (0);
-
-#define LEXER_UNGETC(c, cf) \
- do { \
- INSIST((cf)->pushback_count < LEXER_MAX_PUSHBACK); \
- (cf)->pushback[(cf)->pushback_count++] = (c); \
- } while (0);
-
-static void
-scan_to_comment_end(int c_plus_plus_style) {
- int c;
- int done = 0;
- int prev_was_star = 0;
-
- while (!done) {
- LEXER_GETC(c, current_file);
- switch (c) {
- case EOF:
- if (!c_plus_plus_style)
- parser_error(0, "EOF in comment");
- current_file->flags |= LEX_EOF;
- done = 1;
- break;
- case '*':
- prev_was_star = 1;
- break;
- case '/':
- if (prev_was_star && !c_plus_plus_style)
- done = 1;
- prev_was_star = 0;
- break;
- case '\n':
- if (c_plus_plus_style) {
- /* don't consume the newline because
- we want it to be a delimiter for
- anything before the comment
- started */
- LEXER_UNGETC(c, current_file);
- done = 1;
- } else {
- current_file->line_number++;
- }
- prev_was_star = 0;
- break;
- default:
- prev_was_star = 0;
- }
- }
-}
-
-static int
-get_next_char(int comment_ok) {
- int c, nc;
-
- if (current_file->flags & LEX_EOF)
- return (EOF);
-
- LEXER_GETC(c, current_file);
-
- if (comment_ok) {
- while (c == '/' || c == '#') {
- if (c == '#') {
- scan_to_comment_end(1);
- if (current_file->flags & LEX_EOF)
- return (EOF);
- LEXER_GETC(c, current_file);
- } else {
- LEXER_GETC(nc, current_file);
- switch (nc) {
- case EOF:
- current_file->flags |= LEX_EOF;
- return ('/');
- case '*':
- case '/':
- scan_to_comment_end((nc == '/'));
- if (current_file->flags & LEX_EOF)
- return (EOF);
- LEXER_GETC(c, current_file);
- break;
- default:
- LEXER_UNGETC(nc, current_file);
- return ('/');
- }
- }
- }
- }
-
- if (c == EOF)
- current_file->flags |= LEX_EOF;
- else if (c == '\n')
- current_file->line_number++;
- return (c);
-}
-
-static void
-put_back_char(int c) {
- if (c == EOF)
- current_file->flags |= LEX_EOF;
- else {
- LEXER_UNGETC(c, current_file);
- if (c == '\n')
- current_file->line_number--;
- }
-}
-
-
-/*
- * Identifiers
- */
-
-static void
-clear_identifier(LexerIdentifier id) {
- INSIST(id != NULL);
- id->index = 0;
- id->num_dots = 0;
- id->flags = 0;
-}
-
-static char *
-dup_identifier(LexerIdentifier id) {
- char *duplicate;
-
- INSIST(id != NULL);
- duplicate = savestr(id->buffer, 1);
- return (duplicate);
-}
-
-static void
-finish_identifier(LexerIdentifier id) {
- INSIST(id != NULL && id->index < LEX_MAX_IDENT_SIZE);
- id->buffer[id->index] = '\0';
-}
-
-static void
-add_to_identifier(LexerIdentifier id, int c) {
- INSIST(id != NULL);
- id->buffer[id->index] = c;
- id->index++;
- if (id->index >= LEX_MAX_IDENT_SIZE) {
- parser_error(0, "identifier too long");
- current_file->state = scan;
- /* discard chars until we hit a non-identifier char */
- while (c != EOF && identifier_char(c)) {
- c = get_next_char(1);
- }
- put_back_char(c);
- clear_identifier(id);
- } else {
- if (c == '.') {
- if (id->flags & LEX_LAST_WAS_DOT)
- id->flags |= LEX_CONSECUTIVE_DOTS;
- id->flags |= LEX_LAST_WAS_DOT;
- id->num_dots++;
- } else {
- id->flags &= ~LEX_LAST_WAS_DOT;
- }
- }
-}
-
-/*
- * yylex() -- return the next token from the current input stream
- */
-int
-yylex() {
- int c;
- int comment_ok = 1;
- int token = -1;
- symbol_value value;
-
- while (token < 0) {
- c = get_next_char(comment_ok);
- switch(current_file->state) {
- case scan:
- if (c == EOF) {
- if (current_file->next == NULL)
- /*
- * We don't want to call
- * lexer_end_file() here because we
- * want to keep the toplevel file
- * context to log errors against.
- */
- token = 0;
- else {
- lexer_end_file();
- token = L_END_INCLUDE;
- }
- break;
- }
- if (whitespace(c))
- break;
- if (identifier_char(c)) {
- if (isdigit(c))
- current_file->state = number;
- else
- current_file->state = identifier;
- clear_identifier(id);
- add_to_identifier(id, c);
- } else
- if (special_char(c)) {
- if (c == ';') {
- token = L_EOS;
- break;
- }
- if (c == '"') {
- clear_identifier(id);
- current_file->state =
- quoted_string;
- comment_ok = 0;
- break;
- }
- token = c;
- } else {
- parser_error(0,
- "invalid character '%c'",
- c);
- }
- break;
-
- case number:
- if (c != EOF && identifier_char(c)) {
- if (!isdigit(c))
- current_file->state =
- (c == '.') ? ipv4 : identifier;
- add_to_identifier(id, c);
- } else {
- put_back_char(c);
- current_file->state = scan;
- finish_identifier(id);
- yylval.num = strtol(id->buffer, (char**)0, 0);
- token = L_NUMBER;
- }
- break;
-
- case identifier:
- if (c != EOF && identifier_char(c)) {
- add_to_identifier(id, c);
- } else {
- put_back_char(c);
- current_file->state = scan;
- finish_identifier(id);
- /* is it a keyword? */
- if (lookup_symbol(keyword_table, id->buffer,
- 0, &value)) {
- yylval.cp = id->buffer;
- token = value.integer;
- } else {
- yylval.cp = dup_identifier(id);
- token = L_STRING;
- }
- }
- break;
-
- case ipv4:
- if (c != EOF && identifier_char(c)) {
- if (!isdigit(c)) {
- if (c != '.' ||
- (id->flags & LEX_CONSECUTIVE_DOTS))
- current_file->state =
- identifier;
- }
- add_to_identifier(id, c);
- } else {
- put_back_char(c);
- if (id->num_dots > 3 ||
- (id->flags & LEX_LAST_WAS_DOT))
- current_file->state = identifier;
- else {
- if (id->num_dots == 1) {
- add_to_identifier(id, '.');
- add_to_identifier(id, '0');
- add_to_identifier(id, '.');
- add_to_identifier(id, '0');
- } else if (id->num_dots == 2) {
- add_to_identifier(id, '.');
- add_to_identifier(id, '0');
- }
- current_file->state = scan;
- finish_identifier(id);
- token = L_IPADDR;
- if (inet_aton(id->buffer,
- &(yylval.ip_addr))==0) {
- yylval.cp = dup_identifier(id);
- token = L_STRING;
- }
- }
- }
- break;
-
- case quoted_string:
- if (c == EOF) {
- parser_error(0, "EOF in quoted string");
- return 0;
- } else {
- if (c == '"') {
- comment_ok = 1;
- current_file->state = scan;
- finish_identifier(id);
- yylval.cp = dup_identifier(id);
- token = L_QSTRING;
- } else {
- /* XXX add backslash escapes here */
- add_to_identifier(id, c);
- }
- }
- break;
-
- default:
- panic("unhandled state in yylex", NULL);
- }
- }
-
- last_token = token;
- last_yylval = yylval;
- return (token);
-}
-
-/*
- * Initialization
- */
-
-symbol_table constants;
-
-static void
-import_constants(const struct ns_sym *s, int type) {
- symbol_value value;
- for ((void)NULL; s != NULL && s->name != NULL; s++) {
- value.integer = s->number;
- define_symbol(constants, s->name, type, value, 0);
- }
-}
-
-static void
-import_res_constants(const struct res_sym *r, int type) {
- symbol_value value;
- for ((void)NULL; r != NULL && r->name != NULL; r++) {
- value.integer = r->number;
- define_symbol(constants, r->name, type, value, 0);
- }
-}
-
-#define CONSTANTS_TABLE_SIZE 397 /* should be prime */
-
-static void
-import_all_constants() {
- constants = new_symbol_table(CONSTANTS_TABLE_SIZE, NULL);
- import_res_constants(__p_class_syms, SYM_CLASS);
- import_constants(category_constants, SYM_CATEGORY);
- import_constants(logging_constants, SYM_LOGGING);
- import_constants(syslog_constants, SYM_SYSLOG);
-}
-
-void
-lexer_initialize() {
- memset(special_chars, 0, sizeof special_chars);
- special_chars[';'] = 1;
- special_chars['{'] = 1;
- special_chars['}'] = 1;
- special_chars['!'] = 1;
- special_chars['/'] = 1;
- special_chars['"'] = 1;
- special_chars['*'] = 1;
- id = (LexerIdentifier)memget(sizeof (struct lexer_identifier));
- if (id == NULL)
- panic("memget failed in lexer_initialize", NULL);
- init_keywords();
- import_all_constants();
- lexer_initialized = 1;
-}
-
-void
-lexer_setup(void) {
- REQUIRE(lexer_initialized);
-
- current_file = NULL; /* XXX should we INSIST(current_file==NULL)? */
- INSIST(id != NULL);
-}
-
-void
-lexer_shutdown(void) {
- REQUIRE(lexer_initialized);
-
- free_symbol_table(keyword_table);
- free_symbol_table(constants);
- memput(id, sizeof (struct lexer_identifier));
- id = NULL;
- lexer_initialized = 0;
-}
OpenPOWER on IntegriCloud