diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2022-08-14 18:03:18 +0200 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2022-08-14 18:14:21 +0200 | 
| commit | f545be725df9195a5b5897ad95a0220acf10f148 (patch) | |
| tree | b30aab92bcf23e94ca2c74fca0c6f5573d5745c2 | |
| parent | 7e8e085c97311b52db4d6739b6ef2a1b26a2319f (diff) | |
| download | liberty-f545be725df9195a5b5897ad95a0220acf10f148.tar.gz liberty-f545be725df9195a5b5897ad95a0220acf10f148.tar.xz liberty-f545be725df9195a5b5897ad95a0220acf10f148.zip | |
Extend string syntax in config
And actually test the results of string parsing.
| -rw-r--r-- | LICENSE | 2 | ||||
| -rw-r--r-- | liberty.c | 52 | ||||
| -rw-r--r-- | tests/liberty.c | 7 | 
3 files changed, 52 insertions, 9 deletions
| @@ -1,4 +1,4 @@ -Copyright (c) 2014 - 2020, Přemysl Eric Janouch <p@janouch.name> +Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name>  Permission to use, copy, modify, and/or distribute this software for any  purpose with or without fee is hereby granted. @@ -1,7 +1,7 @@  /*   * liberty.c: the ultimate C unlibrary   * - * Copyright (c) 2014 - 2020, Přemysl Eric Janouch <p@janouch.name> + * Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name>   *   * Permission to use, copy, modify, and/or distribute this software for any   * purpose with or without fee is hereby granted. @@ -4412,7 +4412,9 @@ socket_io_try_write (int socket_fd, struct str *wb)  //   object  = lws '{' entries endobj  //   endobj  = lws '}'  // -//   string  = lws '"' ('\\' escape / ![\\"] char)* '"' +//   quoted  = lws '"' ('\\' escape / ![\\"] char)* '"' +//           / lws '`' ![`]* '`' +//   string  = (quoted)+  //   char    = [\0-\177]  # or any Unicode codepoint in the UTF-8 encoding  //   escape  = [\\"abfnrtv] / [xX][0-9A-Fa-f][0-9A-Fa-f]? / [0-7][0-7]?[0-7]?  // @@ -5039,10 +5041,10 @@ config_tokenizer_escape_sequence  }  static bool -config_tokenizer_string -	(struct config_tokenizer *self, struct str *output, struct error **e) +config_tokenizer_dq_string (struct config_tokenizer *self, struct str *output, +	struct error **e)  { -	unsigned char c; +	unsigned char c = config_tokenizer_advance (self);  	while (self->len)  	{  		if ((c = config_tokenizer_advance (self)) == '"') @@ -5056,6 +5058,44 @@ config_tokenizer_string  	return false;  } +static bool +config_tokenizer_bt_string (struct config_tokenizer *self, struct str *output, +	struct error **e) +{ +	unsigned char c = config_tokenizer_advance (self); +	while (self->len) +	{ +		if ((c = config_tokenizer_advance (self)) == '`') +			return true; +		str_append_c (output, c); +	} +	config_tokenizer_error (self, e, "premature end of string"); +	return false; +} + +static bool +config_tokenizer_string (struct config_tokenizer *self, struct str *output, +	struct error **e) +{ +	// Go-like strings, with C/AWK-like automatic concatenation +	while (self->len) +	{ +		bool ok = true; +		if (isspace_ascii (*self->p) && *self->p != '\n') +			config_tokenizer_advance (self); +		else if (*self->p == '"') +			ok = config_tokenizer_dq_string (self, output, e); +		else if (*self->p == '`') +			ok = config_tokenizer_bt_string (self, output, e); +		else +			break; + +		if (!ok) +			return false; +	} +	return true; +} +  static enum config_token  config_tokenizer_next (struct config_tokenizer *self, struct error **e)  { @@ -5080,7 +5120,7 @@ config_tokenizer_next (struct config_tokenizer *self, struct error **e)  		return CONFIG_T_ABORT;  	case '"': -		config_tokenizer_advance (self); +	case '`':  		str_reset (&self->string);  		if (!config_tokenizer_string (self, &self->string, e))  			return CONFIG_T_ABORT; diff --git a/tests/liberty.c b/tests/liberty.c index dc445d8..3d932d5 100644 --- a/tests/liberty.c +++ b/tests/liberty.c @@ -1,7 +1,7 @@  /*   * tests/liberty.c   * - * Copyright (c) 2015 - 2016, Přemysl Eric Janouch <p@janouch.name> + * Copyright (c) 2015 - 2022, Přemysl Eric Janouch <p@janouch.name>   *   * Permission to use, copy, modify, and/or distribute this software for any   * purpose with or without fee is hereby granted. @@ -649,7 +649,7 @@ static struct config_schema g_config_test[] =  	  .default_  = "1" },  	{ .name      = "foobar",  	  .type      = CONFIG_ITEM_STRING, -	  .default_  = "\"qux\\x01\"" }, +	  .default_  = "\"qux\\x01`\" \"\"`a`" },  	{}  }; @@ -675,6 +675,9 @@ test_config (void)  		"top.bar", NULL), invalid, NULL));  	config_item_destroy (invalid); +	hard_assert (!strcmp ("qux\001`a", +		config_item_get (config.root, "top.foobar", NULL)->value.string.str)); +  	struct str s = str_make ();  	config_item_write (config.root, true, &s);  	struct config_item *parsed = config_item_parse (s.str, s.len, false, NULL); | 
