summaryrefslogtreecommitdiffstats
path: root/src/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lex.c')
-rw-r--r--src/lex.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/src/lex.c b/src/lex.c
index 92a3866..47f6847 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -23,30 +23,42 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Config scanner for the fastd configuration file format
+*/
+
#include "lex.h"
#include <stdlib.h>
+/** The scanner context */
struct fastd_lex {
- FILE *file;
+ FILE *file; /**< The input file */
- bool needspace;
+ bool needspace; /**< Specifies if some kind of whitespace (or similar separator like a semicolon) is needed before the next token is parsed */
- size_t start;
- size_t end;
- size_t tok_len;
- char buffer[1024];
+ size_t start; /**< The start of the current token in the input buffer */
+ size_t end; /**< The end of the input read into the input buffer so far */
+ size_t tok_len; /**< The number of characters in the current token */
+ char buffer[1024]; /**< The input buffer */
};
-
+/** A keyword with the corresponding token ID */
typedef struct keyword {
- const char *keyword;
- int token;
+ const char *keyword; /**< The keyword */
+ int token; /**< The numerical token ID as generated by the parser */
} keyword_t;
-/* the keyword list must be sorted */
+
+/**
+ The list of known keywords
+
+ The keyword list must be sorted so binary search can work.
+*/
static const keyword_t keywords[] = {
{ "addresses", TOK_ADDRESSES },
{ "any", TOK_ANY },
@@ -116,12 +128,14 @@ static const keyword_t keywords[] = {
{ "yes", TOK_YES },
};
+/** Compares two keyword_t instances by their keyword */
static int compare_keywords(const void *v1, const void *v2) {
const keyword_t *k1 = v1, *k2 = v2;
return strcmp(k1->keyword, k2->keyword);
}
+/** Reads the next part of the input file into the input buffer */
static bool advance(fastd_lex_t *lex) {
if (lex->start > 0) {
memmove(lex->buffer, lex->buffer+lex->start, lex->end - lex->start);
@@ -138,14 +152,17 @@ static bool advance(fastd_lex_t *lex) {
return l;
}
+/** Returns the current character (not yet added to the current token) */
static inline char current(fastd_lex_t *lex) {
return lex->buffer[lex->start + lex->tok_len];
}
+/** Returns the current token as a newly allocated string */
static char* get_token(fastd_lex_t *lex) {
return strndup(lex->buffer+lex->start, lex->tok_len);
}
+/** Tries to add the next character to the current token */
static bool next(YYLTYPE *yylloc, fastd_lex_t *lex, bool move) {
if (lex->start + lex->tok_len >= lex->end)
return false;
@@ -170,6 +187,7 @@ static bool next(YYLTYPE *yylloc, fastd_lex_t *lex, bool move) {
return true;
}
+/** Removes the current token from the input buffer */
static void consume(fastd_lex_t *lex, bool needspace) {
lex->start += lex->tok_len;
lex->tok_len = 0;
@@ -177,11 +195,13 @@ static void consume(fastd_lex_t *lex, bool needspace) {
lex->needspace = needspace;
}
+/** Signals an error caused by an I/O error */
static int io_error(YYSTYPE *yylval, fastd_lex_t *lex UNUSED) {
yylval->error = "I/O error";
return -1;
}
+/** Signals an error caused by a syntax error */
static int syntax_error(YYSTYPE *yylval, fastd_lex_t *lex) {
if (ferror(lex->file))
return io_error(yylval, lex);
@@ -190,6 +210,7 @@ static int syntax_error(YYSTYPE *yylval, fastd_lex_t *lex) {
return -1;
}
+/** Skips a block comment */
static int consume_comment(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
char prev = 0;
@@ -210,6 +231,7 @@ static int consume_comment(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
return -1;
}
+/** Signals an error caused by an unterminated string */
static int unterminated_string(YYSTYPE *yylval, fastd_lex_t *lex) {
if (ferror(lex->file))
return io_error(yylval, lex);
@@ -218,6 +240,7 @@ static int unterminated_string(YYSTYPE *yylval, fastd_lex_t *lex) {
return -1;
}
+/** Tries to process the current input as a string */
static int parse_string(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
char *buf = NULL;
size_t len = 1024;
@@ -268,6 +291,7 @@ static int parse_string(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
return TOK_STRING;
}
+/** Tries to process the current input as an IPv6 address */
static int parse_ipv6_address(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
if (lex->needspace)
return syntax_error(yylval, lex);
@@ -332,6 +356,7 @@ static int parse_ipv6_address(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex
return ifname ? TOK_ADDR6_SCOPED : TOK_ADDR6;
}
+/** Tries to process the current input as an IPv4 address */
static int parse_ipv4_address(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
if (lex->needspace)
return syntax_error(yylval, lex);
@@ -356,6 +381,7 @@ static int parse_ipv4_address(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex
return TOK_ADDR4;
}
+/** Tries to process the current input as a number */
static int parse_number(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
bool digitonly = true;
@@ -390,6 +416,7 @@ static int parse_number(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
return TOK_UINT;
}
+/** Tries to process the current input as a keyword */
static int parse_keyword(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
if (lex->needspace)
return syntax_error(yylval, lex);
@@ -414,6 +441,8 @@ static int parse_keyword(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
return ret->token;
}
+
+/** Initializes a new scanner for the given file */
fastd_lex_t* fastd_lex_init(FILE *file) {
fastd_lex_t *lex = calloc(1, sizeof(fastd_lex_t));
lex->file = file;
@@ -423,10 +452,12 @@ fastd_lex_t* fastd_lex_init(FILE *file) {
return lex;
}
+/** Destroys the scanner */
void fastd_lex_destroy(fastd_lex_t *lex) {
free(lex);
}
+/** Returns a single lexeme of the scanned file */
int fastd_lex(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) {
int token;