lex.c revision 386fef57fa9849c733d68ae3b4c7fc4bdb28f11e
/*
* Copyright (C) 1998, 1999 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 <config.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <isc/assertions.h>
typedef struct inputsource {
unsigned int char_count;
int chars[2];
void * input;
char * name;
unsigned long line;
} inputsource;
struct isc_lex {
/* Unlocked. */
unsigned int magic;
char * data;
unsigned int options;
unsigned int comments;
unsigned int paren_count;
};
static inline isc_result_t
char *new;
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
/*
* Create a lexer.
*/
return (ISC_R_NOMEMORY);
return (ISC_R_NOMEMORY);
}
lex->paren_count = 0;
return (ISC_R_SUCCESS);
}
void
/*
* Destroy the lexer.
*/
}
unsigned int
/*
* Return the current lexer commenting styles.
*/
}
void
/*
* Set allowed lexer commenting styles.
*/
}
void
/*
* Put the current list of specials into 'specials'.
*/
}
void
/*
* The characters in 'specials' are returned as tokens. Along with
* whitespace, they delimit strings and numbers.
*/
}
static inline isc_result_t
{
return (ISC_R_NOMEMORY);
source->char_count = 0;
return (ISC_R_NOMEMORY);
}
return (ISC_R_SUCCESS);
}
/*
* Open 'filename' and make it the current input source for 'lex'.
*/
/*
* XXX we should really call something like isc_file_open() to
* get maximally safe file opening.
*/
/*
* The C standard doesn't say that errno is set by fopen(), so
* we just return a generic error.
*/
return (ISC_R_FAILURE);
}
char name[128];
/*
* Make 'stream' the current input source for 'lex'.
*/
/* This is safe. */
}
char name[128];
/*
* Make 'buffer' the current input source for 'lex'.
*/
/* This is safe. */
}
/*
* Close the most recently opened object (i.e. file or buffer).
*/
return (ISC_R_NOMORE);
if (source->need_close)
}
return (ISC_R_SUCCESS);
}
typedef enum {
} lexstate;
int c;
unsigned long ulong;
unsigned int saved_options;
char *e;
/*
* Get the next token.
*/
if ((options & ISC_LEXOPT_NOMORE) != 0) {
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMORE);
}
if (source->have_token) {
return (ISC_R_SUCCESS);
}
if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
lex->paren_count != 0)
return (ISC_R_UNBALANCED);
if ((options & ISC_LEXOPT_EOF) != 0) {
return (ISC_R_SUCCESS);
}
return (ISC_R_EOF);
}
do {
if (source->char_count > 0) {
source->char_count--;
c = getc_unlocked(stream);
if (c == EOF) {
}
}
} else {
c = EOF;
} else {
}
}
if (c == '\n') {
}
if (!escaped && c == ';' &&
!= 0)) {
saved_state = state;
continue;
} else if (c == '/' &&
ISC_LEXCOMMENT_CPLUSPLUS)) != 0) {
saved_state = state;
continue;
} else if (c == '#' &&
!= 0)) {
saved_state = state;
continue;
}
}
/* INSIST(c == EOF || (c >= 0 && c <= 255)); */
switch (state) {
case lexstate_start:
if (c == EOF) {
if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
lex->paren_count != 0)
return (ISC_R_UNBALANCED);
if ((options & ISC_LEXOPT_EOF) == 0)
return (ISC_R_EOF);
} else if (c == ' ' || c == '\t') {
if (lex->last_was_eol &&
!= 0) {
}
} else if (c == '\n') {
if ((options & ISC_LEXOPT_EOL) != 0) {
}
} else if (c == '\r') {
if ((options & ISC_LEXOPT_EOL) != 0)
} else if (c == '"' &&
(options & ISC_LEXOPT_QSTRING) != 0) {
if ((c == '(' || c == ')') &&
(options & ISC_LEXOPT_DNSMULTILINE) != 0) {
if (c == '(') {
if (lex->paren_count == 0)
lex->paren_count++;
} else {
if (lex->paren_count == 0)
return (ISC_R_UNBALANCED);
lex->paren_count--;
if (lex->paren_count == 0)
options =
}
continue;
}
} else if (isdigit(c) &&
(options & ISC_LEXOPT_NUMBER) != 0) {
goto no_read;
} else {
goto no_read;
}
break;
case lexstate_crlf:
if (c != '\n') {
}
break;
case lexstate_number:
if (!isdigit(c)) {
if (c == ' ' || c == '\t' || c == '\r' ||
c == '\n' || c == EOF ||
c;
if (*e == 0) {
} else {
isc_tokenvalue_t *v;
v->as_textregion.base =
v->as_textregion.length =
}
continue;
} else if (!(options & ISC_LEXOPT_CNUMBER) ||
((c != 'x' && c != 'X') ||
/* Above test supports hex numbers */
}
}
if (remaining == 0) {
if (result != ISC_R_SUCCESS)
return (result);
}
*curr++ = c;
*curr = '\0';
remaining--;
break;
case lexstate_string:
if ((!escaped &&
continue;
}
if ((options & ISC_LEXOPT_ESCAPE) != 0)
if (remaining == 0) {
if (result != ISC_R_SUCCESS)
return (result);
}
*curr++ = c;
*curr = 0;
remaining--;
break;
case lexstate_maybecomment:
if (c == '*' &&
continue;
} else if (c == '/' &&
continue;
}
c = '/';
state = saved_state;
goto no_read;
case lexstate_ccomment:
if (c == EOF)
return (ISC_R_UNEXPECTEDEND);
if (c == '*')
break;
case lexstate_ccommentend:
if (c == EOF)
return (ISC_R_UNEXPECTEDEND);
if (c == '/') {
/*
* C-style comments become a single space.
* We do this to ensure that a comment will
* act as a delimiter for strings and
* numbers.
*/
c = ' ';
state = saved_state;
goto no_read;
} else
break;
case lexstate_eatline:
if (c == EOF)
return (ISC_R_UNEXPECTEDEND);
if (c == '\n') {
state = saved_state;
goto no_read;
}
break;
case lexstate_qstring:
if (c == EOF)
return (ISC_R_UNEXPECTEDEND);
if (c == '"') {
if (escaped) {
/*
* Overwrite the preceding backslash.
*/
*prev = '"';
} else {
}
} else {
if (c == '\\' && !escaped)
else
if (remaining == 0) {
if (result != ISC_R_SUCCESS)
return (result);
}
*curr++ = c;
*curr = 0;
remaining--;
}
break;
default:
"Unexpected state %d", state);
/* Does not return. */
}
} while (!done);
return (ISC_R_SUCCESS);
}
void
/*
* Unget the current token.
*/
}
char *
return(NULL);
}
int
return(0);
}