diff --git a/src/lib-sieve/sieve-lexer.c b/src/lib-sieve/sieve-lexer.c index 1d94a0a2670c9a90a483b54e2f9c3fa3d8ec8bd4..9e8b0a655a7051c8465b40511831025bf4c064b6 100644 --- a/src/lib-sieve/sieve-lexer.c +++ b/src/lib-sieve/sieve-lexer.c @@ -56,6 +56,8 @@ struct sieve_lexical_scanner { size_t buffer_pos; struct sieve_lexer lexer; + + int current_line; }; const struct sieve_lexer *sieve_lexer_create @@ -100,10 +102,12 @@ const struct sieve_lexer *sieve_lexer_create scanner->buffer_size = 0; scanner->buffer_pos = 0; - scanner->lexer.current_line = 1; scanner->lexer.token_type = STT_NONE; scanner->lexer.token_str_value = str_new(pool, 256); scanner->lexer.token_int_value = 0; + scanner->lexer.token_line = 1; + + scanner->current_line = 1; return &scanner->lexer; } @@ -138,7 +142,7 @@ inline static void sieve_lexer_error T_BEGIN { sieve_verror(scanner->ehandler, - sieve_error_script_location(scanner->script, lexer->current_line), + sieve_error_script_location(scanner->script, scanner->current_line), fmt, args); } T_END; @@ -155,7 +159,7 @@ inline static void sieve_lexer_warning T_BEGIN { sieve_vwarning(scanner->ehandler, - sieve_error_script_location(scanner->script, lexer->current_line), + sieve_error_script_location(scanner->script, scanner->current_line), fmt, args); } T_END; @@ -237,7 +241,7 @@ void sieve_lexer_token_print(const struct sieve_lexer *lexer) static void sieve_lexer_shift(struct sieve_lexical_scanner *scanner) { if ( scanner->buffer != NULL && scanner->buffer[scanner->buffer_pos] == '\n' ) - scanner->lexer.current_line++; + scanner->current_line++; if ( scanner->buffer != NULL && scanner->buffer_pos + 1 < scanner->buffer_size ) @@ -278,7 +282,6 @@ static inline const char *_char_sanitize(int ch) static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) { struct sieve_lexer *lexer = &scanner->lexer; - sieve_number_t start_line; string_t *str; /* Read first character */ @@ -286,14 +289,17 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) i_stream_read(scanner->input); sieve_lexer_shift(scanner); } + + lexer->token_line = scanner->current_line; switch ( sieve_lexer_curchar(scanner) ) { /* whitespace */ // hash-comment = ( "#" *CHAR-NOT-CRLF CRLF ) - case '#': + case '#': sieve_lexer_shift(scanner); + while ( sieve_lexer_curchar(scanner) != '\n' ) { switch( sieve_lexer_curchar(scanner) ) { case -1: @@ -325,8 +331,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) // ;; (No * is allowed unless it is the last character, // ;; or unless it is followed by a character that isn't a // ;; slash.) - case '/': - start_line = lexer->current_line; + case '/': sieve_lexer_shift(scanner); if ( sieve_lexer_curchar(scanner) == '*' ) { @@ -337,7 +342,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) case -1: sieve_lexer_error(lexer, "end of file before end of bracket comment ('/* ... */') " - "started at line %d", start_line); + "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; case '*': @@ -352,7 +357,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) } else if ( sieve_lexer_curchar(scanner) == -1 ) { sieve_lexer_error(lexer, "end of file before end of bracket comment ('/* ... */') " - "started at line %d", start_line); + "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; } @@ -395,8 +400,8 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) /* quoted-string */ case '"': - start_line = lexer->current_line; sieve_lexer_shift(scanner); + str_truncate(lexer->token_str_value, 0); str = lexer->token_str_value; @@ -411,7 +416,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) case -1: sieve_lexer_error(lexer, "end of file before end of quoted string " - "started at line %d", start_line); + "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; @@ -419,7 +424,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) case '\0': sieve_lexer_error(lexer, "encountered NUL character in quoted string " - "started at line %d", start_line); + "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; @@ -430,7 +435,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) if ( sieve_lexer_curchar(scanner) != '\n' ) { sieve_lexer_error(lexer, "found stray carriage-return (CR) character " - "in quoted string started at line %d", start_line); + "in quoted string started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; } @@ -459,7 +464,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) if ( str_len(str) > SIEVE_MAX_STRING_LEN ) { sieve_lexer_error(lexer, "quoted string started at line %d is too long " - "(longer than %llu bytes)", start_line, + "(longer than %llu bytes)", lexer->token_line, (long long) SIEVE_MAX_STRING_LEN); lexer->token_type = STT_ERROR; return FALSE; @@ -614,8 +619,6 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) type == STT_IDENTIFIER && str_len(str) == 4 && strncasecmp(str_c(str), "text", 4) == 0 ) { sieve_lexer_shift(scanner); // discard colon - - start_line = lexer->current_line; /* Discard SP and HTAB whitespace */ while ( sieve_lexer_curchar(scanner) == ' ' || @@ -678,7 +681,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) if ( str_len(str) > SIEVE_MAX_STRING_LEN ) { sieve_lexer_error(lexer, "multi-line string started at line %d is too long " - "(longer than %llu bytes)", start_line, + "(longer than %llu bytes)", lexer->token_line, (long long) SIEVE_MAX_STRING_LEN); lexer->token_type = STT_ERROR; return FALSE; @@ -690,7 +693,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) /* Seen CR, but no LF */ sieve_lexer_error(lexer, "found stray carriage-return (CR) character " - "in multi-line string started at line %d", start_line); + "in multi-line string started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; } @@ -715,7 +718,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) case '\0': sieve_lexer_error(lexer, "encountered NUL character in quoted string " - "started at line %d", start_line); + "started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; default: @@ -735,7 +738,7 @@ static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner) if ( sieve_lexer_curchar(scanner) != '\n' ) { sieve_lexer_error(lexer, "found stray carriage-return (CR) character " - "in multi-line string started at line %d", start_line); + "in multi-line string started at line %d", lexer->token_line); lexer->token_type = STT_ERROR; return FALSE; } diff --git a/src/lib-sieve/sieve-lexer.h b/src/lib-sieve/sieve-lexer.h index b5e9b244bd19087f7433f729b553395612ab062b..b96e9a8210ab086f9a2feb788b0caacf915b3fdc 100644 --- a/src/lib-sieve/sieve-lexer.h +++ b/src/lib-sieve/sieve-lexer.h @@ -55,7 +55,7 @@ struct sieve_lexer { string_t *token_str_value; int token_int_value; - int current_line; + int token_line; }; const struct sieve_lexer *sieve_lexer_create @@ -110,10 +110,10 @@ static inline bool sieve_lexer_eof return lexer->token_type == STT_EOF; } -static inline int sieve_lexer_current_line +static inline int sieve_lexer_token_line (const struct sieve_lexer *lexer) { - return lexer->current_line; + return lexer->token_line; } const char *sieve_lexer_token_description diff --git a/src/lib-sieve/sieve-parser.c b/src/lib-sieve/sieve-parser.c index 68e4dbe95c95b7872bc3b127d46831314b827d40..cc638b6fdb9eda96bf3cdeb89ab0f493c1080976 100644 --- a/src/lib-sieve/sieve-parser.c +++ b/src/lib-sieve/sieve-parser.c @@ -105,7 +105,7 @@ inline static void sieve_parser_error T_BEGIN { sieve_verror(parser->ehandler, sieve_error_script_location(parser->script, - sieve_lexer_current_line(parser->lexer)), + sieve_lexer_token_line(parser->lexer)), fmt, args); } T_END; } @@ -124,7 +124,7 @@ inline static void sieve_parser_warning T_BEGIN { sieve_vwarning(parser->ehandler, sieve_error_script_location(parser->script, - sieve_lexer_current_line(parser->lexer)), + sieve_lexer_token_line(parser->lexer)), fmt, args); } T_END; @@ -171,7 +171,7 @@ static int sieve_parse_arguments case STT_LSQUARE: /* Create stinglist object */ arg = sieve_ast_argument_stringlist_create - (node, sieve_lexer_current_line(parser->lexer)); + (node, sieve_lexer_token_line(parser->lexer)); if ( arg == NULL ) break; @@ -183,7 +183,7 @@ static int sieve_parse_arguments /* Add the string to the list */ if ( !sieve_ast_stringlist_add (arg, sieve_lexer_token_str(lexer), - sieve_lexer_current_line(parser->lexer)) ) + sieve_lexer_token_line(parser->lexer)) ) add_failed = TRUE; sieve_lexer_skip_token(lexer); @@ -201,7 +201,7 @@ static int sieve_parse_arguments /* Add the string to the list */ if ( !sieve_ast_stringlist_add (arg, sieve_lexer_token_str(lexer), - sieve_lexer_current_line(parser->lexer)) ) + sieve_lexer_token_line(parser->lexer)) ) add_failed = TRUE; sieve_lexer_skip_token(lexer); @@ -246,7 +246,7 @@ static int sieve_parse_arguments case STT_STRING: arg = sieve_ast_argument_string_create (node, sieve_lexer_token_str(lexer), - sieve_lexer_current_line(parser->lexer)); + sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); break; @@ -255,7 +255,7 @@ static int sieve_parse_arguments case STT_NUMBER: arg = sieve_ast_argument_number_create (node, sieve_lexer_token_int(lexer), - sieve_lexer_current_line(parser->lexer)); + sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); break; @@ -263,7 +263,7 @@ static int sieve_parse_arguments case STT_TAG: arg = sieve_ast_argument_tag_create (node, sieve_lexer_token_ident(lexer), - sieve_lexer_current_line(parser->lexer)); + sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); break; @@ -305,7 +305,7 @@ static int sieve_parse_arguments test = sieve_ast_test_create (node, sieve_lexer_token_ident(lexer), - sieve_lexer_current_line(parser->lexer)); + sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); /* Theoretically, test can be NULL */ @@ -338,7 +338,7 @@ static int sieve_parse_arguments if ( sieve_lexer_token_type(lexer) == STT_IDENTIFIER ) { test = sieve_ast_test_create (node, sieve_lexer_token_ident(lexer), - sieve_lexer_current_line(parser->lexer)); + sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); if ( test == NULL ) break; @@ -360,7 +360,7 @@ static int sieve_parse_arguments if ( sieve_lexer_token_type(lexer) == STT_IDENTIFIER ) { test = sieve_ast_test_create (node, sieve_lexer_token_ident(lexer), - sieve_lexer_current_line(parser->lexer)); + sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); if ( test == NULL ) break; @@ -454,7 +454,7 @@ static int sieve_parse_commands /* Create command node */ command = sieve_ast_command_create (block, sieve_lexer_token_ident(lexer), - sieve_lexer_current_line(parser->lexer)); + sieve_lexer_token_line(parser->lexer)); sieve_lexer_skip_token(lexer); if ( command == NULL ) {