diff options
Diffstat (limited to 'src/lex.c')
-rw-r--r-- | src/lex.c | 51 |
1 files changed, 41 insertions, 10 deletions
@@ -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; |