diff options
Diffstat (limited to 'src/libstrongswan/settings')
-rw-r--r-- | src/libstrongswan/settings/settings.c | 69 | ||||
-rw-r--r-- | src/libstrongswan/settings/settings.h | 54 | ||||
-rw-r--r-- | src/libstrongswan/settings/settings_lexer.c | 233 | ||||
-rw-r--r-- | src/libstrongswan/settings/settings_lexer.l | 19 | ||||
-rw-r--r-- | src/libstrongswan/settings/settings_parser.c | 171 | ||||
-rw-r--r-- | src/libstrongswan/settings/settings_parser.h | 8 | ||||
-rw-r--r-- | src/libstrongswan/settings/settings_parser.y | 39 |
7 files changed, 381 insertions, 212 deletions
diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c index acf9160d2..305ebe620 100644 --- a/src/libstrongswan/settings/settings.c +++ b/src/libstrongswan/settings/settings.c @@ -37,9 +37,10 @@ typedef struct private_settings_t private_settings_t; /** - * Parse function provided by the generated parser. + * Parse functions provided by the generated parser. */ bool settings_parser_parse_file(section_t *root, char *name); +bool settings_parser_parse_string(section_t *root, char *settings); /** * Private data of settings @@ -843,16 +844,17 @@ METHOD(settings_t, add_fallback, void, } /** - * Load settings from files matching the given file pattern. + * Load settings from files matching the given file pattern or from a string. * All sections and values are added relative to "parent". * All files (even included ones) have to be loaded successfully. * If merge is FALSE the contents of parent are replaced with the parsed * contents, otherwise they are merged together. */ -static bool load_files_internal(private_settings_t *this, section_t *parent, - char *pattern, bool merge) +static bool load_internal(private_settings_t *this, section_t *parent, + char *pattern, bool merge, bool string) { section_t *section; + bool loaded; if (pattern == NULL || !pattern[0]) { /* TODO: Clear parent if merge is FALSE? */ @@ -860,7 +862,9 @@ static bool load_files_internal(private_settings_t *this, section_t *parent, } section = settings_section_create(NULL); - if (!settings_parser_parse_file(section, pattern)) + loaded = string ? settings_parser_parse_string(section, pattern) : + settings_parser_parse_file(section, pattern); + if (!loaded) { settings_section_destroy(section, NULL); return FALSE; @@ -877,7 +881,7 @@ static bool load_files_internal(private_settings_t *this, section_t *parent, METHOD(settings_t, load_files, bool, private_settings_t *this, char *pattern, bool merge) { - return load_files_internal(this, this->top, pattern, merge); + return load_internal(this, this->top, pattern, merge, FALSE); } METHOD(settings_t, load_files_section, bool, @@ -894,7 +898,30 @@ METHOD(settings_t, load_files_section, bool, { return FALSE; } - return load_files_internal(this, section, pattern, merge); + return load_internal(this, section, pattern, merge, FALSE); +} + +METHOD(settings_t, load_string, bool, + private_settings_t *this, char *settings, bool merge) +{ + return load_internal(this, this->top, settings, merge, TRUE); +} + +METHOD(settings_t, load_string_section, bool, + private_settings_t *this, char *settings, bool merge, char *key, ...) +{ + section_t *section; + va_list args; + + va_start(args, key); + section = ensure_section(this, this->top, key, args); + va_end(args); + + if (!section) + { + return FALSE; + } + return load_internal(this, section, settings, merge, TRUE); } METHOD(settings_t, destroy, void, @@ -906,10 +933,7 @@ METHOD(settings_t, destroy, void, free(this); } -/* - * see header file - */ -settings_t *settings_create(char *file) +static private_settings_t *settings_create_base() { private_settings_t *this; @@ -931,14 +955,37 @@ settings_t *settings_create(char *file) .add_fallback = _add_fallback, .load_files = _load_files, .load_files_section = _load_files_section, + .load_string = _load_string, + .load_string_section = _load_string_section, .destroy = _destroy, }, .top = settings_section_create(NULL), .contents = array_create(0, 0), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); + return this; +} + +/* + * see header file + */ +settings_t *settings_create(char *file) +{ + private_settings_t *this = settings_create_base(); load_files(this, file, FALSE); return &this->public; } + +/* + * see header file + */ +settings_t *settings_create_string(char *settings) +{ + private_settings_t *this = settings_create_base(); + + load_string(this, settings, FALSE); + + return &this->public; +} diff --git a/src/libstrongswan/settings/settings.h b/src/libstrongswan/settings/settings.h index 3b87c8feb..4ef80d0f6 100644 --- a/src/libstrongswan/settings/settings.h +++ b/src/libstrongswan/settings/settings.h @@ -335,6 +335,50 @@ struct settings_t { char *section, ...); /** + * Load settings from the given string. + * + * If merge is TRUE, existing sections are extended, existing values + * replaced, by those found in the string. If it is FALSE, existing + * sections are purged before reading the new config. + * + * @note If the string contains _include_ statements they should be + * absolute paths. + * + * @note If any failures occur, no settings are added at all. So, it's all + * or nothing. + * + * @param settings string to parse + * @param merge TRUE to merge config with existing values + * @return TRUE, if settings were loaded successfully + */ + bool (*load_string)(settings_t *this, char *settings, bool merge); + + /** + * Load settings from the given string. + * + * If merge is TRUE, existing sections are extended, existing values + * replaced, by those found in the string. If it is FALSE, existing + * sections are purged before reading the new config. + * + * All settings are loaded relative to the given section. The section is + * created, if it does not yet exist. + * + * @note If the string contains _include_ statements they should be + * absolute paths. + * + * @note If any failures occur, no settings are added at all. So, it's all + * or nothing. + * + * @param settings string to parse + * @param merge TRUE to merge config with existing values + * @param section section name of parent section, printf style + * @param ... argument list for section + * @return TRUE, if settings were loaded successfully + */ + bool (*load_string_section)(settings_t *this, char *settings, bool merge, + char *section, ...); + + /** * Destroy a settings instance. */ void (*destroy)(settings_t *this); @@ -350,4 +394,14 @@ struct settings_t { */ settings_t *settings_create(char *file); +/** + * Load settings from a string. + * + * @note If parsing the file fails the object is still created. + * + * @param settings string to read settings from + * @return settings object, or NULL + */ +settings_t *settings_create_string(char *settings); + #endif /** SETTINGS_H_ @}*/ diff --git a/src/libstrongswan/settings/settings_lexer.c b/src/libstrongswan/settings/settings_lexer.c index 0d71a1d01..6e64e15a6 100644 --- a/src/libstrongswan/settings/settings_lexer.c +++ b/src/libstrongswan/settings/settings_lexer.c @@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_c_buf_p = yy_cp; /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ -#define YY_NUM_RULES 26 -#define YY_END_OF_BUFFER 27 +#define YY_NUM_RULES 23 +#define YY_END_OF_BUFFER 24 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -465,14 +465,13 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[52] = +static yyconst flex_int16_t yy_accept[49] = { 0, - 0, 0, 0, 0, 0, 0, 27, 9, 2, 3, + 0, 0, 0, 0, 0, 0, 24, 9, 2, 3, 8, 1, 6, 9, 4, 5, 14, 10, 11, 12, - 25, 16, 15, 17, 9, 2, 1, 1, 3, 9, - 14, 13, 25, 24, 23, 24, 21, 22, 18, 19, - 20, 1, 9, 9, 9, 9, 9, 0, 7, 7, - 0 + 22, 15, 16, 9, 2, 1, 1, 3, 9, 14, + 13, 22, 21, 20, 21, 17, 18, 19, 1, 9, + 9, 9, 9, 9, 0, 7, 7, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -486,11 +485,11 @@ static yyconst flex_int32_t yy_ec[256] = 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 9, 1, 1, 1, 1, 1, 10, 11, 12, + 1, 9, 1, 1, 1, 1, 1, 1, 10, 11, - 13, 14, 1, 1, 15, 1, 1, 16, 1, 17, - 1, 1, 1, 18, 1, 19, 20, 1, 1, 1, - 1, 1, 21, 1, 22, 1, 1, 1, 1, 1, + 12, 1, 1, 1, 13, 1, 1, 14, 1, 15, + 1, 1, 1, 16, 1, 17, 18, 1, 1, 1, + 1, 1, 19, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -507,92 +506,91 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[23] = +static yyconst flex_int32_t yy_meta[21] = { 0, 1, 2, 3, 1, 4, 5, 4, 6, 7, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 8, 4 + 1, 1, 1, 1, 1, 1, 1, 1, 8, 9 } ; -static yyconst flex_int16_t yy_base[62] = +static yyconst flex_int16_t yy_base[60] = { 0, - 0, 0, 21, 42, 26, 28, 63, 0, 31, 155, - 155, 59, 155, 44, 155, 155, 0, 155, 155, 0, - 0, 155, 155, 62, 0, 48, 0, 57, 155, 47, - 0, 155, 0, 155, 155, 49, 155, 155, 155, 155, - 155, 0, 30, 21, 28, 12, 37, 52, 155, 54, - 155, 81, 89, 97, 104, 112, 117, 122, 130, 138, - 146 + 0, 0, 19, 38, 21, 23, 55, 0, 47, 161, + 161, 50, 161, 37, 161, 161, 0, 161, 161, 0, + 0, 161, 56, 0, 44, 0, 47, 161, 39, 0, + 161, 0, 161, 161, 45, 161, 161, 161, 0, 32, + 24, 26, 11, 29, 31, 161, 33, 161, 73, 82, + 91, 97, 101, 110, 115, 124, 133, 142, 151 } ; -static yyconst flex_int16_t yy_def[62] = +static yyconst flex_int16_t yy_def[60] = { 0, - 51, 1, 52, 52, 53, 53, 51, 54, 51, 51, - 51, 55, 51, 54, 51, 51, 56, 51, 51, 57, - 58, 51, 51, 59, 54, 51, 60, 55, 51, 54, - 56, 51, 58, 51, 51, 51, 51, 51, 51, 51, - 51, 60, 54, 54, 54, 54, 54, 61, 51, 61, - 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51 + 48, 1, 49, 49, 50, 50, 48, 51, 52, 48, + 48, 53, 48, 51, 48, 48, 54, 48, 48, 55, + 56, 48, 57, 51, 52, 58, 53, 48, 51, 54, + 48, 56, 48, 48, 48, 48, 48, 48, 58, 51, + 51, 51, 51, 51, 59, 48, 59, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48 } ; -static yyconst flex_int16_t yy_nxt[178] = +static yyconst flex_int16_t yy_nxt[182] = { 0, 8, 9, 10, 8, 9, 11, 12, 13, 8, 8, - 8, 8, 8, 8, 14, 8, 8, 8, 8, 8, - 15, 16, 18, 18, 47, 18, 19, 18, 22, 20, - 22, 23, 26, 23, 24, 26, 24, 27, 48, 46, - 45, 48, 18, 18, 18, 44, 18, 19, 18, 26, - 20, 35, 26, 50, 27, 50, 50, 43, 50, 29, - 30, 29, 51, 18, 35, 36, 51, 51, 51, 51, - 51, 37, 51, 51, 51, 38, 51, 51, 39, 40, - 41, 17, 17, 17, 17, 17, 17, 17, 17, 21, - 21, 21, 21, 21, 21, 21, 21, 25, 51, 51, - - 51, 51, 51, 25, 28, 28, 28, 28, 28, 28, - 28, 28, 31, 51, 51, 51, 51, 31, 51, 31, - 32, 32, 33, 33, 51, 33, 51, 33, 51, 33, - 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, - 51, 42, 42, 42, 42, 42, 49, 49, 49, 49, - 49, 51, 49, 49, 7, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51 + 8, 8, 14, 8, 8, 8, 8, 8, 15, 16, + 18, 18, 44, 18, 19, 18, 22, 20, 22, 23, + 45, 23, 47, 45, 47, 47, 43, 47, 18, 18, + 18, 42, 18, 19, 18, 41, 20, 34, 40, 28, + 26, 29, 28, 26, 48, 48, 48, 18, 34, 35, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 36, 37, 38, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 24, 48, 48, 48, 48, 48, 24, 25, 48, + + 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 30, 48, 48, 48, 48, 30, 48, 30, 31, 31, + 48, 48, 48, 31, 32, 32, 32, 32, 48, 32, + 48, 32, 32, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 39, 39, 48, 39, 39, 39, 39, 39, + 39, 46, 46, 46, 46, 46, 48, 46, 46, 46, + 7, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48 } ; -static yyconst flex_int16_t yy_chk[178] = +static yyconst flex_int16_t yy_chk[182] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 3, 46, 3, 3, 3, 5, 3, - 6, 5, 9, 6, 5, 9, 6, 9, 47, 45, - 44, 47, 3, 4, 4, 43, 4, 4, 4, 26, - 4, 36, 26, 48, 26, 50, 48, 30, 50, 28, - 14, 12, 7, 4, 24, 24, 0, 0, 0, 0, - 0, 24, 0, 0, 0, 24, 0, 0, 24, 24, - 24, 52, 52, 52, 52, 52, 52, 52, 52, 53, - 53, 53, 53, 53, 53, 53, 53, 54, 0, 0, - - 0, 0, 0, 54, 55, 55, 55, 55, 55, 55, - 55, 55, 56, 0, 0, 0, 0, 56, 0, 56, - 57, 57, 58, 58, 0, 58, 0, 58, 0, 58, - 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, - 0, 60, 60, 60, 60, 60, 61, 61, 61, 61, - 61, 0, 61, 61, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51 + 3, 3, 43, 3, 3, 3, 5, 3, 6, 5, + 44, 6, 45, 44, 47, 45, 42, 47, 3, 4, + 4, 41, 4, 4, 4, 40, 4, 35, 29, 27, + 25, 14, 12, 9, 7, 0, 0, 4, 23, 23, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 23, 23, 23, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 51, 0, 0, 0, 0, 0, 51, 52, 0, + + 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 54, 0, 0, 0, 0, 54, 0, 54, 55, 55, + 0, 0, 0, 55, 56, 56, 56, 56, 0, 56, + 0, 56, 56, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 58, 58, 0, 58, 58, 58, 58, 58, + 58, 59, 59, 59, 59, 59, 0, 59, 59, 59, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[27] = +static yyconst flex_int32_t yy_rule_can_match_eol[24] = { 0, -0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, 0, }; +0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, }; -static yyconst flex_int16_t yy_rule_linenum[26] = +static yyconst flex_int16_t yy_rule_linenum[23] = { 0, 59, 60, 61, 63, 64, 65, 67, 72, 77, 85, - 105, 108, 111, 114, 120, 122, 123, 146, 147, 148, - 149, 150, 151, 152, 153 + 105, 108, 111, 114, 120, 122, 141, 142, 143, 144, + 145, 146 } ; /* The intent behind this definition is that it'll catch @@ -640,7 +638,7 @@ static void include_files(parser_helper_t *ctx); /* state used to scan quoted strings */ -#line 644 "settings/settings_lexer.c" +#line 642 "settings/settings_lexer.c" #define INITIAL 0 #define inc 1 @@ -952,7 +950,7 @@ YY_DECL #line 57 "settings/settings_lexer.l" -#line 956 "settings/settings_lexer.c" +#line 954 "settings/settings_lexer.c" yylval = yylval_param; @@ -1017,13 +1015,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 52 ) + if ( yy_current_state >= 49 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 155 ); + while ( yy_base[yy_current_state] != 161 ); yy_find_action: /* %% [10.0] code to find the action number goes here */ @@ -1058,13 +1056,13 @@ do_action: /* This label is used only to access EOF actions. */ { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 26 ) + else if ( yy_act < 23 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 26 ) + else if ( yy_act == 23 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 27 ) + else if ( yy_act == 24 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -1197,21 +1195,13 @@ case 15: case YY_STATE_EOF(str): #line 121 "settings/settings_lexer.l" case 16: -/* rule 16 can match eol */ -#line 123 "settings/settings_lexer.l" -case 17: -/* rule 17 can match eol */ YY_RULE_SETUP -#line 123 "settings/settings_lexer.l" +#line 122 "settings/settings_lexer.l" { if (!streq(yytext, "\"")) { - if (streq(yytext, "\n")) - { /* put the newline back to fix the line numbers */ - unput('\n'); - yy_set_bol(0); - } PARSER_DBG1(yyextra, "unterminated string detected"); + return STRING_ERROR; } if (yy_top_state(yyscanner) == inc) { /* string include */ @@ -1227,52 +1217,43 @@ YY_RULE_SETUP } } YY_BREAK -case 18: +case 17: YY_RULE_SETUP -#line 146 "settings/settings_lexer.l" +#line 141 "settings/settings_lexer.l" yyextra->string_add(yyextra, "\n"); YY_BREAK -case 19: +case 18: YY_RULE_SETUP -#line 147 "settings/settings_lexer.l" +#line 142 "settings/settings_lexer.l" yyextra->string_add(yyextra, "\r"); YY_BREAK -case 20: +case 19: YY_RULE_SETUP -#line 148 "settings/settings_lexer.l" +#line 143 "settings/settings_lexer.l" yyextra->string_add(yyextra, "\t"); YY_BREAK -case 21: -YY_RULE_SETUP -#line 149 "settings/settings_lexer.l" -yyextra->string_add(yyextra, "\b"); - YY_BREAK -case 22: -YY_RULE_SETUP -#line 150 "settings/settings_lexer.l" -yyextra->string_add(yyextra, "\f"); - YY_BREAK -case 23: -/* rule 23 can match eol */ +case 20: +/* rule 20 can match eol */ YY_RULE_SETUP -#line 151 "settings/settings_lexer.l" +#line 144 "settings/settings_lexer.l" /* merge lines that end with EOL characters */ YY_BREAK -case 24: +case 21: YY_RULE_SETUP -#line 152 "settings/settings_lexer.l" +#line 145 "settings/settings_lexer.l" yyextra->string_add(yyextra, yytext+1); YY_BREAK -case 25: +case 22: +/* rule 22 can match eol */ YY_RULE_SETUP -#line 153 "settings/settings_lexer.l" +#line 146 "settings/settings_lexer.l" { yyextra->string_add(yyextra, yytext); } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 158 "settings/settings_lexer.l" +#line 151 "settings/settings_lexer.l" { settings_parser_pop_buffer_state(yyscanner); if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER) @@ -1281,12 +1262,12 @@ case YY_STATE_EOF(INITIAL): } } YY_BREAK -case 26: +case 23: YY_RULE_SETUP -#line 166 "settings/settings_lexer.l" +#line 159 "settings/settings_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1290 "settings/settings_lexer.c" +#line 1271 "settings/settings_lexer.c" case YY_END_OF_BUFFER: { @@ -1599,7 +1580,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 52 ) + if ( yy_current_state >= 49 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1633,11 +1614,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 52 ) + if ( yy_current_state >= 49 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 51); + yy_is_jam = (yy_current_state == 48); return yy_is_jam ? 0 : yy_current_state; } @@ -2654,7 +2635,7 @@ void settings_parser_free (void * ptr , yyscan_t yyscanner) /* %ok-for-header */ -#line 166 "settings/settings_lexer.l" +#line 159 "settings/settings_lexer.l" @@ -2692,3 +2673,11 @@ static void include_files(parser_helper_t *ctx) settings_parser_open_next_file(ctx); } +/** + * Load the given string to be parsed next + */ +void settings_parser_load_string(parser_helper_t *ctx, const char *content) +{ + settings_parser__scan_string(content, ctx->scanner); +} + diff --git a/src/libstrongswan/settings/settings_lexer.l b/src/libstrongswan/settings/settings_lexer.l index 176387f1f..ce9d4eedc 100644 --- a/src/libstrongswan/settings/settings_lexer.l +++ b/src/libstrongswan/settings/settings_lexer.l @@ -119,16 +119,11 @@ static void include_files(parser_helper_t *ctx); <str>{ "\"" | <<EOF>> | - \n | \\ { if (!streq(yytext, "\"")) { - if (streq(yytext, "\n")) - { /* put the newline back to fix the line numbers */ - unput('\n'); - yy_set_bol(0); - } PARSER_DBG1(yyextra, "unterminated string detected"); + return STRING_ERROR; } if (yy_top_state(yyscanner) == inc) { /* string include */ @@ -146,11 +141,9 @@ static void include_files(parser_helper_t *ctx); \\n yyextra->string_add(yyextra, "\n"); \\r yyextra->string_add(yyextra, "\r"); \\t yyextra->string_add(yyextra, "\t"); - \\b yyextra->string_add(yyextra, "\b"); - \\f yyextra->string_add(yyextra, "\f"); \\\r?\n /* merge lines that end with EOL characters */ \\. yyextra->string_add(yyextra, yytext+1); - [^\\\n"]+ { + [^\\"]+ { yyextra->string_add(yyextra, yytext); } } @@ -198,3 +191,11 @@ static void include_files(parser_helper_t *ctx) settings_parser_open_next_file(ctx); } + +/** + * Load the given string to be parsed next + */ +void settings_parser_load_string(parser_helper_t *ctx, const char *content) +{ + settings_parser__scan_string(content, ctx->scanner); +} diff --git a/src/libstrongswan/settings/settings_parser.c b/src/libstrongswan/settings/settings_parser.c index be805efc9..6cd3b177a 100644 --- a/src/libstrongswan/settings/settings_parser.c +++ b/src/libstrongswan/settings/settings_parser.c @@ -110,6 +110,7 @@ int settings_parser_get_leng(void *scanner); int settings_parser_get_lineno(void *scanner); /* Custom functions in lexer */ bool settings_parser_open_next_file(parser_helper_t *ctx); +bool settings_parser_load_string(parser_helper_t *ctx, const char *content); /** * Forward declarations @@ -130,7 +131,7 @@ static int yylex(YYSTYPE *lvalp, parser_helper_t *ctx) } -#line 134 "settings/settings_parser.c" /* yacc.c:339 */ +#line 135 "settings/settings_parser.c" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus @@ -167,26 +168,28 @@ extern int settings_parser_debug; { NAME = 258, STRING = 259, - NEWLINE = 260 + NEWLINE = 260, + STRING_ERROR = 261 }; #endif /* Tokens. */ #define NAME 258 #define STRING 259 #define NEWLINE 260 +#define STRING_ERROR 261 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 76 "settings/settings_parser.y" /* yacc.c:355 */ +#line 77 "settings/settings_parser.y" /* yacc.c:355 */ char *s; struct section_t *sec; struct kv_t *kv; -#line 190 "settings/settings_parser.c" /* yacc.c:355 */ +#line 193 "settings/settings_parser.c" /* yacc.c:355 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 @@ -200,7 +203,7 @@ int settings_parser_parse (parser_helper_t *ctx); /* Copy the second part of user declarations. */ -#line 204 "settings/settings_parser.c" /* yacc.c:358 */ +#line 207 "settings/settings_parser.c" /* yacc.c:358 */ #ifdef short # undef short @@ -445,7 +448,7 @@ union yyalloc #define YYLAST 13 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 9 +#define YYNTOKENS 10 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 8 /* YYNRULES -- Number of rules. */ @@ -456,7 +459,7 @@ union yyalloc /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 260 +#define YYMAXUTOK 261 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -471,13 +474,13 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 7, 2, 6, 2, 2, 2, 2, + 2, 2, 2, 8, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -491,15 +494,15 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5 + 5, 6 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 104, 104, 106, 107, 111, 115, 122, 130, 135, - 142, 147, 154, 155, 169, 170 + 0, 105, 105, 107, 108, 112, 116, 123, 131, 136, + 143, 148, 155, 156, 170, 171 }; #endif @@ -508,9 +511,9 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "NAME", "STRING", "NEWLINE", "'}'", - "'{'", "'='", "$accept", "statements", "statement", "section", - "section_start", "setting", "value", "valuepart", YY_NULLPTR + "$end", "error", "$undefined", "NAME", "STRING", "NEWLINE", + "STRING_ERROR", "'}'", "'{'", "'='", "$accept", "statements", + "statement", "section", "section_start", "setting", "value", "valuepart", YY_NULLPTR }; #endif @@ -519,14 +522,14 @@ static const char *const yytname[] = (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { - 0, 256, 257, 258, 259, 260, 125, 123, 61 + 0, 256, 257, 258, 259, 260, 261, 125, 123, 61 }; # endif -#define YYPACT_NINF -5 +#define YYPACT_NINF -11 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-5))) + (!!((Yystate) == (-11))) #define YYTABLE_NINF -1 @@ -537,8 +540,8 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - -5, 0, -5, -1, -5, -5, -5, -5, -5, 2, - -5, -2, 5, -5, -5, -5, -2, -5, -5, -5 + -11, 0, -11, -1, -11, -11, -11, -11, -11, 2, + -11, -2, 6, -11, -11, -11, -2, -11, -11, -11 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -553,7 +556,7 @@ static const yytype_uint8 yydefact[] = /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -5, 6, -5, -5, -5, -5, -5, -4 + -11, 5, -11, -11, -11, -11, -11, -10 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -567,29 +570,29 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { - 2, 14, 15, 3, 9, 4, 10, 11, 3, 13, - 4, 18, 19, 12 + 2, 14, 15, 3, 9, 4, 19, 10, 11, 3, + 13, 4, 12, 18 }; static const yytype_uint8 yycheck[] = { - 0, 3, 4, 3, 5, 5, 7, 8, 3, 7, - 5, 6, 16, 7 + 0, 3, 4, 3, 5, 5, 16, 8, 9, 3, + 8, 5, 7, 7 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 10, 0, 3, 5, 11, 12, 13, 14, 5, - 7, 8, 10, 7, 3, 4, 15, 16, 6, 16 + 0, 11, 0, 3, 5, 12, 13, 14, 15, 5, + 8, 9, 11, 8, 3, 4, 16, 17, 7, 17 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 9, 10, 10, 10, 11, 11, 12, 13, 13, - 14, 14, 15, 15, 16, 16 + 0, 10, 11, 11, 11, 12, 12, 13, 14, 14, + 15, 15, 16, 16, 17, 17 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1022,45 +1025,45 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_helper_t *c switch (yytype) { case 3: /* NAME */ -#line 90 "settings/settings_parser.y" /* yacc.c:1257 */ +#line 91 "settings/settings_parser.y" /* yacc.c:1257 */ { free(((*yyvaluep).s)); } -#line 1028 "settings/settings_parser.c" /* yacc.c:1257 */ +#line 1031 "settings/settings_parser.c" /* yacc.c:1257 */ break; case 4: /* STRING */ -#line 90 "settings/settings_parser.y" /* yacc.c:1257 */ +#line 91 "settings/settings_parser.y" /* yacc.c:1257 */ { free(((*yyvaluep).s)); } -#line 1034 "settings/settings_parser.c" /* yacc.c:1257 */ +#line 1037 "settings/settings_parser.c" /* yacc.c:1257 */ break; - case 12: /* section */ -#line 92 "settings/settings_parser.y" /* yacc.c:1257 */ + case 13: /* section */ +#line 93 "settings/settings_parser.y" /* yacc.c:1257 */ { pop_section(ctx); settings_section_destroy(((*yyvaluep).sec), NULL); } -#line 1040 "settings/settings_parser.c" /* yacc.c:1257 */ +#line 1043 "settings/settings_parser.c" /* yacc.c:1257 */ break; - case 13: /* section_start */ -#line 92 "settings/settings_parser.y" /* yacc.c:1257 */ + case 14: /* section_start */ +#line 93 "settings/settings_parser.y" /* yacc.c:1257 */ { pop_section(ctx); settings_section_destroy(((*yyvaluep).sec), NULL); } -#line 1046 "settings/settings_parser.c" /* yacc.c:1257 */ +#line 1049 "settings/settings_parser.c" /* yacc.c:1257 */ break; - case 14: /* setting */ -#line 93 "settings/settings_parser.y" /* yacc.c:1257 */ + case 15: /* setting */ +#line 94 "settings/settings_parser.y" /* yacc.c:1257 */ { settings_kv_destroy(((*yyvaluep).kv), NULL); } -#line 1052 "settings/settings_parser.c" /* yacc.c:1257 */ +#line 1055 "settings/settings_parser.c" /* yacc.c:1257 */ break; - case 15: /* value */ -#line 90 "settings/settings_parser.y" /* yacc.c:1257 */ + case 16: /* value */ +#line 91 "settings/settings_parser.y" /* yacc.c:1257 */ { free(((*yyvaluep).s)); } -#line 1058 "settings/settings_parser.c" /* yacc.c:1257 */ +#line 1061 "settings/settings_parser.c" /* yacc.c:1257 */ break; - case 16: /* valuepart */ -#line 90 "settings/settings_parser.y" /* yacc.c:1257 */ + case 17: /* valuepart */ +#line 91 "settings/settings_parser.y" /* yacc.c:1257 */ { free(((*yyvaluep).s)); } -#line 1064 "settings/settings_parser.c" /* yacc.c:1257 */ +#line 1067 "settings/settings_parser.c" /* yacc.c:1257 */ break; @@ -1326,64 +1329,64 @@ yyreduce: switch (yyn) { case 5: -#line 112 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 113 "settings/settings_parser.y" /* yacc.c:1646 */ { add_section(ctx, (yyvsp[0].sec)); } -#line 1334 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1337 "settings/settings_parser.c" /* yacc.c:1646 */ break; case 6: -#line 116 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 117 "settings/settings_parser.y" /* yacc.c:1646 */ { add_setting(ctx, (yyvsp[0].kv)); } -#line 1342 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1345 "settings/settings_parser.c" /* yacc.c:1646 */ break; case 7: -#line 123 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 124 "settings/settings_parser.y" /* yacc.c:1646 */ { pop_section(ctx); (yyval.sec) = (yyvsp[-2].sec); } -#line 1351 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1354 "settings/settings_parser.c" /* yacc.c:1646 */ break; case 8: -#line 131 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 132 "settings/settings_parser.y" /* yacc.c:1646 */ { (yyval.sec) = push_section(ctx, (yyvsp[-1].s)); } -#line 1359 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1362 "settings/settings_parser.c" /* yacc.c:1646 */ break; case 9: -#line 136 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 137 "settings/settings_parser.y" /* yacc.c:1646 */ { (yyval.sec) = push_section(ctx, (yyvsp[-2].s)); } -#line 1367 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1370 "settings/settings_parser.c" /* yacc.c:1646 */ break; case 10: -#line 143 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 144 "settings/settings_parser.y" /* yacc.c:1646 */ { (yyval.kv) = settings_kv_create((yyvsp[-2].s), (yyvsp[0].s)); } -#line 1375 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1378 "settings/settings_parser.c" /* yacc.c:1646 */ break; case 11: -#line 148 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 149 "settings/settings_parser.y" /* yacc.c:1646 */ { (yyval.kv) = settings_kv_create((yyvsp[-1].s), NULL); } -#line 1383 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1386 "settings/settings_parser.c" /* yacc.c:1646 */ break; case 13: -#line 156 "settings/settings_parser.y" /* yacc.c:1646 */ +#line 157 "settings/settings_parser.y" /* yacc.c:1646 */ { /* just put a single space between them, use strings for more */ if (asprintf(&(yyval.s), "%s %s", (yyvsp[-1].s), (yyvsp[0].s)) < 0) { @@ -1394,11 +1397,11 @@ yyreduce: free((yyvsp[-1].s)); free((yyvsp[0].s)); } -#line 1398 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1401 "settings/settings_parser.c" /* yacc.c:1646 */ break; -#line 1402 "settings/settings_parser.c" /* yacc.c:1646 */ +#line 1405 "settings/settings_parser.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1626,7 +1629,7 @@ yyreturn: #endif return yyresult; } -#line 173 "settings/settings_parser.y" /* yacc.c:1906 */ +#line 174 "settings/settings_parser.y" /* yacc.c:1906 */ /** @@ -1743,3 +1746,39 @@ bool settings_parser_parse_file(section_t *root, char *name) helper->destroy(helper); return success; } + +/** + * Parse the given string and add all sections and key/value pairs to the + * given section. + */ +bool settings_parser_parse_string(section_t *root, char *settings) +{ + parser_helper_t *helper; + array_t *sections = NULL; + bool success = FALSE; + + array_insert_create(§ions, ARRAY_TAIL, root); + helper = parser_helper_create(sections); + helper->get_lineno = settings_parser_get_lineno; + if (settings_parser_lex_init_extra(helper, &helper->scanner) != 0) + { + helper->destroy(helper); + array_destroy(sections); + return FALSE; + } + settings_parser_load_string(helper, settings); + if (getenv("DEBUG_SETTINGS_PARSER")) + { + yydebug = 1; + settings_parser_set_debug(1, helper->scanner); + } + success = yyparse(helper) == 0; + if (!success) + { + DBG1(DBG_CFG, "failed to parse settings '%s'", settings); + } + array_destroy(sections); + settings_parser_lex_destroy(helper->scanner); + helper->destroy(helper); + return success; +} diff --git a/src/libstrongswan/settings/settings_parser.h b/src/libstrongswan/settings/settings_parser.h index 9d56465ef..d887777a2 100644 --- a/src/libstrongswan/settings/settings_parser.h +++ b/src/libstrongswan/settings/settings_parser.h @@ -47,26 +47,28 @@ extern int settings_parser_debug; { NAME = 258, STRING = 259, - NEWLINE = 260 + NEWLINE = 260, + STRING_ERROR = 261 }; #endif /* Tokens. */ #define NAME 258 #define STRING 259 #define NEWLINE 260 +#define STRING_ERROR 261 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 76 "settings/settings_parser.y" /* yacc.c:1909 */ +#line 77 "settings/settings_parser.y" /* yacc.c:1909 */ char *s; struct section_t *sec; struct kv_t *kv; -#line 70 "settings/settings_parser.h" /* yacc.c:1909 */ +#line 72 "settings/settings_parser.h" /* yacc.c:1909 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 diff --git a/src/libstrongswan/settings/settings_parser.y b/src/libstrongswan/settings/settings_parser.y index d95a24b2a..96ab36faf 100644 --- a/src/libstrongswan/settings/settings_parser.y +++ b/src/libstrongswan/settings/settings_parser.y @@ -39,6 +39,7 @@ int settings_parser_get_leng(void *scanner); int settings_parser_get_lineno(void *scanner); /* Custom functions in lexer */ bool settings_parser_open_next_file(parser_helper_t *ctx); +bool settings_parser_load_string(parser_helper_t *ctx, const char *content); /** * Forward declarations @@ -79,7 +80,7 @@ static int yylex(YYSTYPE *lvalp, parser_helper_t *ctx) struct kv_t *kv; } %token <s> NAME STRING -%token NEWLINE +%token NEWLINE STRING_ERROR /* ...and other symbols */ %type <s> value valuepart @@ -286,3 +287,39 @@ bool settings_parser_parse_file(section_t *root, char *name) helper->destroy(helper); return success; } + +/** + * Parse the given string and add all sections and key/value pairs to the + * given section. + */ +bool settings_parser_parse_string(section_t *root, char *settings) +{ + parser_helper_t *helper; + array_t *sections = NULL; + bool success = FALSE; + + array_insert_create(§ions, ARRAY_TAIL, root); + helper = parser_helper_create(sections); + helper->get_lineno = settings_parser_get_lineno; + if (settings_parser_lex_init_extra(helper, &helper->scanner) != 0) + { + helper->destroy(helper); + array_destroy(sections); + return FALSE; + } + settings_parser_load_string(helper, settings); + if (getenv("DEBUG_SETTINGS_PARSER")) + { + yydebug = 1; + settings_parser_set_debug(1, helper->scanner); + } + success = yyparse(helper) == 0; + if (!success) + { + DBG1(DBG_CFG, "failed to parse settings '%s'", settings); + } + array_destroy(sections); + settings_parser_lex_destroy(helper->scanner); + helper->destroy(helper); + return success; +} |