Ver código fonte

ncd: add a length value to token values to allow implementation of strings with null bytes

ambrop7 14 anos atrás
pai
commit
152458b43f

+ 1 - 1
examples/ncd_tokenizer_test.c

@@ -37,7 +37,7 @@
 
 int error;
 
-static int tokenizer_output (void *user, int token, char *value, size_t line, size_t line_char)
+static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char)
 {
     if (token == NCD_ERROR) {
         printf("line %zu, character %zu: tokenizer error\n", line, line_char);

+ 83 - 78
generated/NCDConfigParser_parse.c

@@ -13,13 +13,18 @@
 #include <misc/debug.h>
 #include <ncd/NCDConfig.h>
 
+struct parser_minor {
+    char *str;
+    size_t len;
+};
+
 struct parser_out {
     int out_of_memory;
     int syntax_error;
     struct NCDConfig_processes *ast;
 };
 
-#line 23 "NCDConfigParser_parse.c"
+#line 28 "NCDConfigParser_parse.c"
 /* Next is all token values, in a form suitable for use by makeheaders.
 ** This section will be null unless lemon is run with the -m switch.
 */
@@ -72,7 +77,7 @@ struct parser_out {
 #define YYCODETYPE unsigned char
 #define YYNOCODE 30
 #define YYACTIONTYPE unsigned char
-#define ParseTOKENTYPE void *
+#define ParseTOKENTYPE struct parser_minor
 typedef union {
   int yyinit;
   ParseTOKENTYPE yy0;
@@ -434,30 +439,30 @@ static void yy_destructor(
     case 14: /* PROCESS */
     case 15: /* TEMPLATE */
 {
-#line 50 "NCDConfigParser_parse.y"
- free((yypminor->yy0)); 
-#line 440 "NCDConfigParser_parse.c"
+#line 55 "NCDConfigParser_parse.y"
+ free((yypminor->yy0).str); 
+#line 445 "NCDConfigParser_parse.c"
 }
       break;
     case 17: /* processes */
 {
-#line 64 "NCDConfigParser_parse.y"
+#line 69 "NCDConfigParser_parse.y"
  NCDConfig_free_processes((yypminor->yy45)); 
-#line 447 "NCDConfigParser_parse.c"
+#line 452 "NCDConfigParser_parse.c"
 }
       break;
     case 18: /* statements */
 {
-#line 65 "NCDConfigParser_parse.y"
+#line 70 "NCDConfigParser_parse.y"
  NCDConfig_free_statements((yypminor->yy16)); 
-#line 454 "NCDConfigParser_parse.c"
+#line 459 "NCDConfigParser_parse.c"
 }
       break;
     case 19: /* statement_names */
 {
-#line 66 "NCDConfigParser_parse.y"
+#line 71 "NCDConfigParser_parse.y"
  NCDConfig_free_strings((yypminor->yy24)); 
-#line 461 "NCDConfigParser_parse.c"
+#line 466 "NCDConfigParser_parse.c"
 }
       break;
     case 20: /* statement_args_maybe */
@@ -467,16 +472,16 @@ static void yy_destructor(
     case 24: /* map */
     case 25: /* value */
 {
-#line 67 "NCDConfigParser_parse.y"
+#line 72 "NCDConfigParser_parse.y"
  NCDConfig_free_list((yypminor->yy12)); 
-#line 473 "NCDConfigParser_parse.c"
+#line 478 "NCDConfigParser_parse.c"
 }
       break;
     case 26: /* name_maybe */
 {
-#line 73 "NCDConfigParser_parse.y"
+#line 78 "NCDConfigParser_parse.y"
  free((yypminor->yy5)); 
-#line 480 "NCDConfigParser_parse.c"
+#line 485 "NCDConfigParser_parse.c"
 }
       break;
     default:  break;   /* If no destructor action specified: do nothing */
@@ -649,12 +654,12 @@ static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
    while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
    /* Here code is inserted which will execute if the parser
    ** stack every overflows */
-#line 82 "NCDConfigParser_parse.y"
+#line 87 "NCDConfigParser_parse.y"
 
     if (yypMinor) {
-        free(yypMinor->yy0);
+        free(yypMinor->yy0.str);
     }
-#line 658 "NCDConfigParser_parse.c"
+#line 663 "NCDConfigParser_parse.c"
    ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
 }
 
@@ -793,7 +798,7 @@ static void yy_reduce(
   **     break;
   */
       case 0: /* input ::= processes */
-#line 88 "NCDConfigParser_parse.y"
+#line 93 "NCDConfigParser_parse.y"
 {
     parser_out->ast = yymsp[0].minor.yy45;
 
@@ -801,34 +806,34 @@ static void yy_reduce(
         parser_out->out_of_memory = 1;
     }
 }
-#line 805 "NCDConfigParser_parse.c"
+#line 810 "NCDConfigParser_parse.c"
         break;
       case 1: /* processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE */
-#line 96 "NCDConfigParser_parse.y"
+#line 101 "NCDConfigParser_parse.y"
 {
-    yygotominor.yy45 = NCDConfig_make_processes(yymsp[-4].minor.yy46, yymsp[-3].minor.yy0, yymsp[-1].minor.yy16, 0, NULL);
+    yygotominor.yy45 = NCDConfig_make_processes(yymsp[-4].minor.yy46, yymsp[-3].minor.yy0.str, yymsp[-1].minor.yy16, 0, NULL);
     if (!yygotominor.yy45) {
         parser_out->out_of_memory = 1;
     }
   yy_destructor(yypParser,2,&yymsp[-2].minor);
   yy_destructor(yypParser,3,&yymsp[0].minor);
 }
-#line 817 "NCDConfigParser_parse.c"
+#line 822 "NCDConfigParser_parse.c"
         break;
       case 2: /* processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes */
-#line 103 "NCDConfigParser_parse.y"
+#line 108 "NCDConfigParser_parse.y"
 {
-    yygotominor.yy45 = NCDConfig_make_processes(yymsp[-5].minor.yy46, yymsp[-4].minor.yy0, yymsp[-2].minor.yy16, 1, yymsp[0].minor.yy45);
+    yygotominor.yy45 = NCDConfig_make_processes(yymsp[-5].minor.yy46, yymsp[-4].minor.yy0.str, yymsp[-2].minor.yy16, 1, yymsp[0].minor.yy45);
     if (!yygotominor.yy45) {
         parser_out->out_of_memory = 1;
     }
   yy_destructor(yypParser,2,&yymsp[-3].minor);
   yy_destructor(yypParser,3,&yymsp[-1].minor);
 }
-#line 829 "NCDConfigParser_parse.c"
+#line 834 "NCDConfigParser_parse.c"
         break;
       case 3: /* statements ::= statement_names ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON */
-#line 110 "NCDConfigParser_parse.y"
+#line 115 "NCDConfigParser_parse.y"
 {
     yygotominor.yy16 = NCDConfig_make_statements(NULL, yymsp[-5].minor.yy24, yymsp[-3].minor.yy12, yymsp[-1].minor.yy5, NULL);
     if (!yygotominor.yy16) {
@@ -838,10 +843,10 @@ static void yy_reduce(
   yy_destructor(yypParser,5,&yymsp[-2].minor);
   yy_destructor(yypParser,6,&yymsp[0].minor);
 }
-#line 842 "NCDConfigParser_parse.c"
+#line 847 "NCDConfigParser_parse.c"
         break;
       case 4: /* statements ::= statement_names ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON statements */
-#line 117 "NCDConfigParser_parse.y"
+#line 122 "NCDConfigParser_parse.y"
 {
     yygotominor.yy16 = NCDConfig_make_statements(NULL, yymsp[-6].minor.yy24, yymsp[-4].minor.yy12, yymsp[-2].minor.yy5, yymsp[0].minor.yy16);
     if (!yygotominor.yy16) {
@@ -851,10 +856,10 @@ static void yy_reduce(
   yy_destructor(yypParser,5,&yymsp[-3].minor);
   yy_destructor(yypParser,6,&yymsp[-1].minor);
 }
-#line 855 "NCDConfigParser_parse.c"
+#line 860 "NCDConfigParser_parse.c"
         break;
       case 5: /* statements ::= statement_names ARROW statement_names ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON */
-#line 124 "NCDConfigParser_parse.y"
+#line 129 "NCDConfigParser_parse.y"
 {
     yygotominor.yy16 = NCDConfig_make_statements(yymsp[-7].minor.yy24, yymsp[-5].minor.yy24, yymsp[-3].minor.yy12, yymsp[-1].minor.yy5, NULL);
     if (!yygotominor.yy16) {
@@ -865,10 +870,10 @@ static void yy_reduce(
   yy_destructor(yypParser,5,&yymsp[-2].minor);
   yy_destructor(yypParser,6,&yymsp[0].minor);
 }
-#line 869 "NCDConfigParser_parse.c"
+#line 874 "NCDConfigParser_parse.c"
         break;
       case 6: /* statements ::= statement_names ARROW statement_names ROUND_OPEN statement_args_maybe ROUND_CLOSE name_maybe SEMICOLON statements */
-#line 131 "NCDConfigParser_parse.y"
+#line 136 "NCDConfigParser_parse.y"
 {
     yygotominor.yy16 = NCDConfig_make_statements(yymsp[-8].minor.yy24, yymsp[-6].minor.yy24, yymsp[-4].minor.yy12, yymsp[-2].minor.yy5, yymsp[0].minor.yy16);
     if (!yygotominor.yy16) {
@@ -879,46 +884,46 @@ static void yy_reduce(
   yy_destructor(yypParser,5,&yymsp[-3].minor);
   yy_destructor(yypParser,6,&yymsp[-1].minor);
 }
-#line 883 "NCDConfigParser_parse.c"
+#line 888 "NCDConfigParser_parse.c"
         break;
       case 7: /* statement_names ::= NAME */
-#line 138 "NCDConfigParser_parse.y"
+#line 143 "NCDConfigParser_parse.y"
 {
-    yygotominor.yy24 = NCDConfig_make_strings(yymsp[0].minor.yy0, 0, NULL);
+    yygotominor.yy24 = NCDConfig_make_strings(yymsp[0].minor.yy0.str, 0, NULL);
     if (!yygotominor.yy24) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 893 "NCDConfigParser_parse.c"
+#line 898 "NCDConfigParser_parse.c"
         break;
       case 8: /* statement_names ::= NAME DOT statement_names */
-#line 145 "NCDConfigParser_parse.y"
+#line 150 "NCDConfigParser_parse.y"
 {
-    yygotominor.yy24 = NCDConfig_make_strings(yymsp[-2].minor.yy0, 1, yymsp[0].minor.yy24);
+    yygotominor.yy24 = NCDConfig_make_strings(yymsp[-2].minor.yy0.str, 1, yymsp[0].minor.yy24);
     if (!yygotominor.yy24) {
         parser_out->out_of_memory = 1;
     }
   yy_destructor(yypParser,8,&yymsp[-1].minor);
 }
-#line 904 "NCDConfigParser_parse.c"
+#line 909 "NCDConfigParser_parse.c"
         break;
       case 9: /* statement_args_maybe ::= */
-#line 152 "NCDConfigParser_parse.y"
+#line 157 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = NULL;
 }
-#line 911 "NCDConfigParser_parse.c"
+#line 916 "NCDConfigParser_parse.c"
         break;
       case 10: /* statement_args_maybe ::= list_contents */
       case 11: /* list_contents ::= value */ yytestcase(yyruleno==11);
-#line 156 "NCDConfigParser_parse.y"
+#line 161 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = yymsp[0].minor.yy12;
 }
-#line 919 "NCDConfigParser_parse.c"
+#line 924 "NCDConfigParser_parse.c"
         break;
       case 12: /* list_contents ::= value COMMA list_contents */
-#line 164 "NCDConfigParser_parse.y"
+#line 169 "NCDConfigParser_parse.y"
 {
     if (!yymsp[-2].minor.yy12) {
         NCDConfig_free_list(yymsp[0].minor.yy12);
@@ -929,28 +934,28 @@ static void yy_reduce(
     yygotominor.yy12 = yymsp[-2].minor.yy12;
   yy_destructor(yypParser,9,&yymsp[-1].minor);
 }
-#line 933 "NCDConfigParser_parse.c"
+#line 938 "NCDConfigParser_parse.c"
         break;
       case 13: /* list ::= CURLY_OPEN CURLY_CLOSE */
-#line 174 "NCDConfigParser_parse.y"
+#line 179 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = NULL;
   yy_destructor(yypParser,2,&yymsp[-1].minor);
   yy_destructor(yypParser,3,&yymsp[0].minor);
 }
-#line 942 "NCDConfigParser_parse.c"
+#line 947 "NCDConfigParser_parse.c"
         break;
       case 14: /* list ::= CURLY_OPEN list_contents CURLY_CLOSE */
-#line 178 "NCDConfigParser_parse.y"
+#line 183 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = yymsp[-1].minor.yy12;
   yy_destructor(yypParser,2,&yymsp[-2].minor);
   yy_destructor(yypParser,3,&yymsp[0].minor);
 }
-#line 951 "NCDConfigParser_parse.c"
+#line 956 "NCDConfigParser_parse.c"
         break;
       case 15: /* map_contents ::= value COLON value */
-#line 182 "NCDConfigParser_parse.y"
+#line 187 "NCDConfigParser_parse.y"
 {
     if (!yymsp[-2].minor.yy12 || !yymsp[0].minor.yy12) {
         NCDConfig_free_list(yymsp[-2].minor.yy12);
@@ -964,10 +969,10 @@ static void yy_reduce(
     }
   yy_destructor(yypParser,10,&yymsp[-1].minor);
 }
-#line 968 "NCDConfigParser_parse.c"
+#line 973 "NCDConfigParser_parse.c"
         break;
       case 16: /* map_contents ::= value COLON value COMMA map_contents */
-#line 195 "NCDConfigParser_parse.y"
+#line 200 "NCDConfigParser_parse.y"
 {
     if (!yymsp[-4].minor.yy12 || !yymsp[-2].minor.yy12) {
         NCDConfig_free_list(yymsp[-4].minor.yy12);
@@ -984,95 +989,95 @@ static void yy_reduce(
   yy_destructor(yypParser,10,&yymsp[-3].minor);
   yy_destructor(yypParser,9,&yymsp[-1].minor);
 }
-#line 988 "NCDConfigParser_parse.c"
+#line 993 "NCDConfigParser_parse.c"
         break;
       case 17: /* map ::= BRACKET_OPEN BRACKET_CLOSE */
-#line 210 "NCDConfigParser_parse.y"
+#line 215 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = NULL;
   yy_destructor(yypParser,11,&yymsp[-1].minor);
   yy_destructor(yypParser,12,&yymsp[0].minor);
 }
-#line 997 "NCDConfigParser_parse.c"
+#line 1002 "NCDConfigParser_parse.c"
         break;
       case 18: /* map ::= BRACKET_OPEN map_contents BRACKET_CLOSE */
-#line 214 "NCDConfigParser_parse.y"
+#line 219 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = yymsp[-1].minor.yy12;
   yy_destructor(yypParser,11,&yymsp[-2].minor);
   yy_destructor(yypParser,12,&yymsp[0].minor);
 }
-#line 1006 "NCDConfigParser_parse.c"
+#line 1011 "NCDConfigParser_parse.c"
         break;
       case 19: /* value ::= STRING */
-#line 218 "NCDConfigParser_parse.y"
+#line 223 "NCDConfigParser_parse.y"
 {
-    yygotominor.yy12 = NCDConfig_make_list_string(yymsp[0].minor.yy0, NULL);
+    yygotominor.yy12 = NCDConfig_make_list_string(yymsp[0].minor.yy0.str, yymsp[0].minor.yy0.len, NULL);
     if (!yygotominor.yy12) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 1016 "NCDConfigParser_parse.c"
+#line 1021 "NCDConfigParser_parse.c"
         break;
       case 20: /* value ::= statement_names */
-#line 225 "NCDConfigParser_parse.y"
+#line 230 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = NCDConfig_make_list_var(yymsp[0].minor.yy24, NULL);
     if (!yygotominor.yy12) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 1026 "NCDConfigParser_parse.c"
+#line 1031 "NCDConfigParser_parse.c"
         break;
       case 21: /* value ::= list */
-#line 232 "NCDConfigParser_parse.y"
+#line 237 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = NCDConfig_make_list_list(yymsp[0].minor.yy12, NULL);
     if (!yygotominor.yy12) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 1036 "NCDConfigParser_parse.c"
+#line 1041 "NCDConfigParser_parse.c"
         break;
       case 22: /* value ::= map */
-#line 239 "NCDConfigParser_parse.y"
+#line 244 "NCDConfigParser_parse.y"
 {
     yygotominor.yy12 = NCDConfig_make_list_maplist(yymsp[0].minor.yy12, NULL);
     if (!yygotominor.yy12) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 1046 "NCDConfigParser_parse.c"
+#line 1051 "NCDConfigParser_parse.c"
         break;
       case 23: /* name_maybe ::= */
-#line 246 "NCDConfigParser_parse.y"
+#line 251 "NCDConfigParser_parse.y"
 {
     yygotominor.yy5 = NULL;
 }
-#line 1053 "NCDConfigParser_parse.c"
+#line 1058 "NCDConfigParser_parse.c"
         break;
       case 24: /* name_maybe ::= NAME */
-#line 250 "NCDConfigParser_parse.y"
+#line 255 "NCDConfigParser_parse.y"
 {
-    yygotominor.yy5 = yymsp[0].minor.yy0;
+    yygotominor.yy5 = yymsp[0].minor.yy0.str;
 }
-#line 1060 "NCDConfigParser_parse.c"
+#line 1065 "NCDConfigParser_parse.c"
         break;
       case 25: /* process_or_template ::= PROCESS */
-#line 254 "NCDConfigParser_parse.y"
+#line 259 "NCDConfigParser_parse.y"
 {
     yygotominor.yy46 = 0;
   yy_destructor(yypParser,14,&yymsp[0].minor);
 }
-#line 1068 "NCDConfigParser_parse.c"
+#line 1073 "NCDConfigParser_parse.c"
         break;
       case 26: /* process_or_template ::= TEMPLATE */
-#line 258 "NCDConfigParser_parse.y"
+#line 263 "NCDConfigParser_parse.y"
 {
     yygotominor.yy46 = 1;
   yy_destructor(yypParser,15,&yymsp[0].minor);
 }
-#line 1076 "NCDConfigParser_parse.c"
+#line 1081 "NCDConfigParser_parse.c"
         break;
       default:
         break;
@@ -1134,10 +1139,10 @@ static void yy_syntax_error(
 ){
   ParseARG_FETCH;
 #define TOKEN (yyminor.yy0)
-#line 77 "NCDConfigParser_parse.y"
+#line 82 "NCDConfigParser_parse.y"
 
     parser_out->syntax_error = 1;
-#line 1141 "NCDConfigParser_parse.c"
+#line 1146 "NCDConfigParser_parse.c"
   ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
 }
 

+ 14 - 9
generated/NCDConfigParser_parse.y

@@ -35,6 +35,11 @@
 #include <misc/debug.h>
 #include <ncd/NCDConfig.h>
 
+struct parser_minor {
+    char *str;
+    size_t len;
+};
+
 struct parser_out {
     int out_of_memory;
     int syntax_error;
@@ -45,9 +50,9 @@ struct parser_out {
 
 %extra_argument {struct parser_out *parser_out}
 
-%token_type {void *}
+%token_type {struct parser_minor}
 
-%token_destructor { free($$); }
+%token_destructor { free($$.str); }
 
 %type processes {struct NCDConfig_processes *}
 %type statements {struct NCDConfig_statements *}
@@ -81,7 +86,7 @@ struct parser_out {
 // workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked
 %stack_overflow {
     if (yypMinor) {
-        free(yypMinor->yy0);
+        free(yypMinor->yy0.str);
     }
 }
 
@@ -94,14 +99,14 @@ input ::= processes(A). {
 }
 
 processes(R) ::= process_or_template(T) NAME(A) CURLY_OPEN statements(B) CURLY_CLOSE. {
-    R = NCDConfig_make_processes(T, A, B, 0, NULL);
+    R = NCDConfig_make_processes(T, A.str, B, 0, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
 }
 
 processes(R) ::= process_or_template(T) NAME(A) CURLY_OPEN statements(B) CURLY_CLOSE processes(N). {
-    R = NCDConfig_make_processes(T, A, B, 1, N);
+    R = NCDConfig_make_processes(T, A.str, B, 1, N);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
@@ -136,14 +141,14 @@ statements(R) ::= statement_names(M) ARROW statement_names(A) ROUND_OPEN stateme
 }
 
 statement_names(R) ::= NAME(A). {
-    R = NCDConfig_make_strings(A, 0, NULL);
+    R = NCDConfig_make_strings(A.str, 0, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
 }
 
 statement_names(R) ::= NAME(A) DOT statement_names(N). {
-    R = NCDConfig_make_strings(A, 1, N);
+    R = NCDConfig_make_strings(A.str, 1, N);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
@@ -216,7 +221,7 @@ map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. {
 }
 
 value(R) ::= STRING(A). {
-    R = NCDConfig_make_list_string(A, NULL);
+    R = NCDConfig_make_list_string(A.str, A.len, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
@@ -248,7 +253,7 @@ name_maybe(R) ::= . {
 }
 
 name_maybe(R) ::= NAME(A). {
-    R = A;
+    R = A.str;
 }
 
 process_or_template(R) ::= PROCESS. {

+ 47 - 42
generated/NCDValueParser_parse.c

@@ -18,15 +18,20 @@
 #define AST_TYPE_LIST 2
 #define AST_TYPE_MAP 3
 
+struct parser_minor {
+    char *str;
+    size_t len;
+};
+
 struct parser_out {
     int out_of_memory;
     int syntax_error;
     int ast_type;
-    char *ast_string;
+    struct parser_minor ast_string;
     struct NCDConfig_list *ast_list;
 };
 
-#line 30 "NCDValueParser_parse.c"
+#line 35 "NCDValueParser_parse.c"
 /* Next is all token values, in a form suitable for use by makeheaders.
 ** This section will be null unless lemon is run with the -m switch.
 */
@@ -79,7 +84,7 @@ struct parser_out {
 #define YYCODETYPE unsigned char
 #define YYNOCODE 16
 #define YYACTIONTYPE unsigned char
-#define ParseTOKENTYPE void *
+#define ParseTOKENTYPE struct parser_minor
 typedef union {
   int yyinit;
   ParseTOKENTYPE yy0;
@@ -396,9 +401,9 @@ static void yy_destructor(
     case 6: /* BRACKET_OPEN */
     case 7: /* BRACKET_CLOSE */
 {
-#line 57 "NCDValueParser_parse.y"
- free((yypminor->yy0)); 
-#line 402 "NCDValueParser_parse.c"
+#line 62 "NCDValueParser_parse.y"
+ free((yypminor->yy0).str); 
+#line 407 "NCDValueParser_parse.c"
 }
       break;
     case 9: /* list_contents */
@@ -407,9 +412,9 @@ static void yy_destructor(
     case 12: /* map */
     case 13: /* value */
 {
-#line 65 "NCDValueParser_parse.y"
+#line 70 "NCDValueParser_parse.y"
  NCDConfig_free_list((yypminor->yy14)); 
-#line 413 "NCDValueParser_parse.c"
+#line 418 "NCDValueParser_parse.c"
 }
       break;
     default:  break;   /* If no destructor action specified: do nothing */
@@ -582,12 +587,12 @@ static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
    while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
    /* Here code is inserted which will execute if the parser
    ** stack every overflows */
-#line 78 "NCDValueParser_parse.y"
+#line 83 "NCDValueParser_parse.y"
 
     if (yypMinor) {
-        free(yypMinor->yy0);
+        free(yypMinor->yy0.str);
     }
-#line 591 "NCDValueParser_parse.c"
+#line 596 "NCDValueParser_parse.c"
    ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
 }
 
@@ -713,44 +718,44 @@ static void yy_reduce(
   **     break;
   */
       case 0: /* input ::= STRING */
-#line 84 "NCDValueParser_parse.y"
+#line 89 "NCDValueParser_parse.y"
 {
     ASSERT(parser_out->ast_type == AST_TYPE_NONE)
 
     parser_out->ast_string = yymsp[0].minor.yy0;
     parser_out->ast_type = AST_TYPE_STRING;
 }
-#line 724 "NCDValueParser_parse.c"
+#line 729 "NCDValueParser_parse.c"
         break;
       case 1: /* input ::= list */
-#line 91 "NCDValueParser_parse.y"
+#line 96 "NCDValueParser_parse.y"
 {
     ASSERT(parser_out->ast_type == AST_TYPE_NONE)
 
     parser_out->ast_list = yymsp[0].minor.yy14;
     parser_out->ast_type = AST_TYPE_LIST;
 }
-#line 734 "NCDValueParser_parse.c"
+#line 739 "NCDValueParser_parse.c"
         break;
       case 2: /* input ::= map */
-#line 98 "NCDValueParser_parse.y"
+#line 103 "NCDValueParser_parse.y"
 {
     ASSERT(parser_out->ast_type == AST_TYPE_NONE)
 
     parser_out->ast_list = yymsp[0].minor.yy14;
     parser_out->ast_type = AST_TYPE_MAP;
 }
-#line 744 "NCDValueParser_parse.c"
+#line 749 "NCDValueParser_parse.c"
         break;
       case 3: /* list_contents ::= value */
-#line 105 "NCDValueParser_parse.y"
+#line 110 "NCDValueParser_parse.y"
 {
     yygotominor.yy14 = yymsp[0].minor.yy14;
 }
-#line 751 "NCDValueParser_parse.c"
+#line 756 "NCDValueParser_parse.c"
         break;
       case 4: /* list_contents ::= value COMMA list_contents */
-#line 109 "NCDValueParser_parse.y"
+#line 114 "NCDValueParser_parse.y"
 {
     if (!yymsp[-2].minor.yy14) {
         NCDConfig_free_list(yymsp[0].minor.yy14);
@@ -761,10 +766,10 @@ static void yy_reduce(
     yygotominor.yy14 = yymsp[-2].minor.yy14;
   yy_destructor(yypParser,2,&yymsp[-1].minor);
 }
-#line 765 "NCDValueParser_parse.c"
+#line 770 "NCDValueParser_parse.c"
         break;
       case 5: /* map_contents ::= value COLON value */
-#line 119 "NCDValueParser_parse.y"
+#line 124 "NCDValueParser_parse.y"
 {
     if (!yymsp[-2].minor.yy14 || !yymsp[0].minor.yy14) {
         NCDConfig_free_list(yymsp[-2].minor.yy14);
@@ -778,10 +783,10 @@ static void yy_reduce(
     }
   yy_destructor(yypParser,3,&yymsp[-1].minor);
 }
-#line 782 "NCDValueParser_parse.c"
+#line 787 "NCDValueParser_parse.c"
         break;
       case 6: /* map_contents ::= value COLON value COMMA map_contents */
-#line 132 "NCDValueParser_parse.y"
+#line 137 "NCDValueParser_parse.y"
 {
     if (!yymsp[-4].minor.yy14 || !yymsp[-2].minor.yy14) {
         NCDConfig_free_list(yymsp[-4].minor.yy14);
@@ -798,73 +803,73 @@ static void yy_reduce(
   yy_destructor(yypParser,3,&yymsp[-3].minor);
   yy_destructor(yypParser,2,&yymsp[-1].minor);
 }
-#line 802 "NCDValueParser_parse.c"
+#line 807 "NCDValueParser_parse.c"
         break;
       case 7: /* list ::= CURLY_OPEN CURLY_CLOSE */
-#line 147 "NCDValueParser_parse.y"
+#line 152 "NCDValueParser_parse.y"
 {
     yygotominor.yy14 = NULL;
   yy_destructor(yypParser,4,&yymsp[-1].minor);
   yy_destructor(yypParser,5,&yymsp[0].minor);
 }
-#line 811 "NCDValueParser_parse.c"
+#line 816 "NCDValueParser_parse.c"
         break;
       case 8: /* list ::= CURLY_OPEN list_contents CURLY_CLOSE */
-#line 151 "NCDValueParser_parse.y"
+#line 156 "NCDValueParser_parse.y"
 {
     yygotominor.yy14 = yymsp[-1].minor.yy14;
   yy_destructor(yypParser,4,&yymsp[-2].minor);
   yy_destructor(yypParser,5,&yymsp[0].minor);
 }
-#line 820 "NCDValueParser_parse.c"
+#line 825 "NCDValueParser_parse.c"
         break;
       case 9: /* map ::= BRACKET_OPEN BRACKET_CLOSE */
-#line 155 "NCDValueParser_parse.y"
+#line 160 "NCDValueParser_parse.y"
 {
     yygotominor.yy14 = NULL;
   yy_destructor(yypParser,6,&yymsp[-1].minor);
   yy_destructor(yypParser,7,&yymsp[0].minor);
 }
-#line 829 "NCDValueParser_parse.c"
+#line 834 "NCDValueParser_parse.c"
         break;
       case 10: /* map ::= BRACKET_OPEN map_contents BRACKET_CLOSE */
-#line 159 "NCDValueParser_parse.y"
+#line 164 "NCDValueParser_parse.y"
 {
     yygotominor.yy14 = yymsp[-1].minor.yy14;
   yy_destructor(yypParser,6,&yymsp[-2].minor);
   yy_destructor(yypParser,7,&yymsp[0].minor);
 }
-#line 838 "NCDValueParser_parse.c"
+#line 843 "NCDValueParser_parse.c"
         break;
       case 11: /* value ::= STRING */
-#line 163 "NCDValueParser_parse.y"
+#line 168 "NCDValueParser_parse.y"
 {
-    yygotominor.yy14 = NCDConfig_make_list_string(yymsp[0].minor.yy0, NULL);
+    yygotominor.yy14 = NCDConfig_make_list_string(yymsp[0].minor.yy0.str, yymsp[0].minor.yy0.len, NULL);
     if (!yygotominor.yy14) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 848 "NCDValueParser_parse.c"
+#line 853 "NCDValueParser_parse.c"
         break;
       case 12: /* value ::= list */
-#line 170 "NCDValueParser_parse.y"
+#line 175 "NCDValueParser_parse.y"
 {
     yygotominor.yy14 = NCDConfig_make_list_list(yymsp[0].minor.yy14, NULL);
     if (!yygotominor.yy14) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 858 "NCDValueParser_parse.c"
+#line 863 "NCDValueParser_parse.c"
         break;
       case 13: /* value ::= map */
-#line 177 "NCDValueParser_parse.y"
+#line 182 "NCDValueParser_parse.y"
 {
     yygotominor.yy14 = NCDConfig_make_list_maplist(yymsp[0].minor.yy14, NULL);
     if (!yygotominor.yy14) {
         parser_out->out_of_memory = 1;
     }
 }
-#line 868 "NCDValueParser_parse.c"
+#line 873 "NCDValueParser_parse.c"
         break;
       default:
         break;
@@ -926,10 +931,10 @@ static void yy_syntax_error(
 ){
   ParseARG_FETCH;
 #define TOKEN (yyminor.yy0)
-#line 73 "NCDValueParser_parse.y"
+#line 78 "NCDValueParser_parse.y"
 
     parser_out->syntax_error = 1;
-#line 933 "NCDValueParser_parse.c"
+#line 938 "NCDValueParser_parse.c"
   ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
 }
 

+ 10 - 5
generated/NCDValueParser_parse.y

@@ -40,11 +40,16 @@
 #define AST_TYPE_LIST 2
 #define AST_TYPE_MAP 3
 
+struct parser_minor {
+    char *str;
+    size_t len;
+};
+
 struct parser_out {
     int out_of_memory;
     int syntax_error;
     int ast_type;
-    char *ast_string;
+    struct parser_minor ast_string;
     struct NCDConfig_list *ast_list;
 };
 
@@ -52,9 +57,9 @@ struct parser_out {
 
 %extra_argument {struct parser_out *parser_out}
 
-%token_type {void *}
+%token_type {struct parser_minor}
 
-%token_destructor { free($$); }
+%token_destructor { free($$.str); }
 
 %type list_contents {struct NCDConfig_list *}
 %type list {struct NCDConfig_list *}
@@ -77,7 +82,7 @@ struct parser_out {
 // workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked
 %stack_overflow {
     if (yypMinor) {
-        free(yypMinor->yy0);
+        free(yypMinor->yy0.str);
     }
 }
 
@@ -161,7 +166,7 @@ map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. {
 }
 
 value(R) ::= STRING(A). {
-    R = NCDConfig_make_list_string(A, NULL);
+    R = NCDConfig_make_list_string(A.str, A.len, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }

+ 5 - 1
ncd/NCDConfig.c

@@ -32,6 +32,7 @@
 
 #include <misc/string_begins_with.h>
 #include <misc/expstring.h>
+#include <misc/debug.h>
 
 #include <ncd/NCDConfig.h>
 
@@ -149,8 +150,10 @@ fail:
     return NULL;
 }
 
-struct NCDConfig_list * NCDConfig_make_list_string (char *str, struct NCDConfig_list *next)
+struct NCDConfig_list * NCDConfig_make_list_string (char *str, size_t len, struct NCDConfig_list *next)
 {
+    ASSERT(str[len] == '\0')
+    
     struct NCDConfig_list *v = malloc(sizeof(*v));
     if (!v) {
         goto fail;
@@ -158,6 +161,7 @@ struct NCDConfig_list * NCDConfig_make_list_string (char *str, struct NCDConfig_
     
     v->type = NCDCONFIG_ARG_STRING;
     v->string = str;
+    v->string_len = len;
     v->next = next;
     
     return v;

+ 7 - 2
ncd/NCDConfig.h

@@ -30,6 +30,8 @@
 #ifndef BADVPN_NCDCONFIG_NCDCONFIG_H
 #define BADVPN_NCDCONFIG_NCDCONFIG_H
 
+#include <stddef.h>
+
 struct NCDConfig_processes;
 struct NCDConfig_statements;
 struct NCDConfig_list;
@@ -58,7 +60,10 @@ struct NCDConfig_statements {
 struct NCDConfig_list {
     int type;
     union {
-        char *string;
+        struct {
+            char *string;
+            size_t string_len;
+        };
         struct NCDConfig_strings *var;
         struct NCDConfig_list *list;
     };
@@ -76,7 +81,7 @@ void NCDConfig_free_list (struct NCDConfig_list *v);
 void NCDConfig_free_strings (struct NCDConfig_strings *v);
 struct NCDConfig_processes * NCDConfig_make_processes (int is_template, char *name, struct NCDConfig_statements *statements, int have_next, struct NCDConfig_processes *next);
 struct NCDConfig_statements * NCDConfig_make_statements (struct NCDConfig_strings *objname, struct NCDConfig_strings *names, struct NCDConfig_list *args, char *name, struct NCDConfig_statements *next);
-struct NCDConfig_list * NCDConfig_make_list_string (char *str, struct NCDConfig_list *next);
+struct NCDConfig_list * NCDConfig_make_list_string (char *str, size_t len, struct NCDConfig_list *next);
 struct NCDConfig_list * NCDConfig_make_list_var (struct NCDConfig_strings *var, struct NCDConfig_list *next);
 struct NCDConfig_list * NCDConfig_make_list_list (struct NCDConfig_list *list, struct NCDConfig_list *next);
 struct NCDConfig_list * NCDConfig_make_list_maplist (struct NCDConfig_list *list, struct NCDConfig_list *next);

+ 22 - 18
ncd/NCDConfigParser.c

@@ -48,9 +48,9 @@ struct parser_state {
     void *parser;
 };
 
-static int tokenizer_output (void *user, int token, char *value, size_t line, size_t line_char)
+static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char)
 {
-    struct parser_state *state = (struct parser_state *)user;
+    struct parser_state *state = user;
     ASSERT(!state->out.out_of_memory)
     ASSERT(!state->out.syntax_error)
     ASSERT(!state->error)
@@ -61,69 +61,73 @@ static int tokenizer_output (void *user, int token, char *value, size_t line, si
         return 0;
     }
     
+    struct parser_minor minor;
+    minor.str = value;
+    minor.len = value_len;
+    
     switch (token) {
         case NCD_EOF: {
-            Parse(state->parser, 0, NULL, &state->out);
+            Parse(state->parser, 0, minor, &state->out);
         } break;
         
         case NCD_TOKEN_CURLY_OPEN: {
-            Parse(state->parser, CURLY_OPEN, NULL, &state->out);
+            Parse(state->parser, CURLY_OPEN, minor, &state->out);
         } break;
         
         case NCD_TOKEN_CURLY_CLOSE: {
-            Parse(state->parser, CURLY_CLOSE, NULL, &state->out);
+            Parse(state->parser, CURLY_CLOSE, minor, &state->out);
         } break;
         
         case NCD_TOKEN_ROUND_OPEN: {
-            Parse(state->parser, ROUND_OPEN, NULL, &state->out);
+            Parse(state->parser, ROUND_OPEN, minor, &state->out);
         } break;
         
         case NCD_TOKEN_ROUND_CLOSE: {
-            Parse(state->parser, ROUND_CLOSE, NULL, &state->out);
+            Parse(state->parser, ROUND_CLOSE, minor, &state->out);
         } break;
         
         case NCD_TOKEN_SEMICOLON: {
-            Parse(state->parser, SEMICOLON, NULL, &state->out);
+            Parse(state->parser, SEMICOLON, minor, &state->out);
         } break;
         
         case NCD_TOKEN_DOT: {
-            Parse(state->parser, DOT, NULL, &state->out);
+            Parse(state->parser, DOT, minor, &state->out);
         } break;
         
         case NCD_TOKEN_COMMA: {
-            Parse(state->parser, COMMA, NULL, &state->out);
+            Parse(state->parser, COMMA, minor, &state->out);
         } break;
         
         case NCD_TOKEN_ARROW: {
-            Parse(state->parser, ARROW, NULL, &state->out);
+            Parse(state->parser, ARROW, minor, &state->out);
         } break;
         
         case NCD_TOKEN_PROCESS: {
-            Parse(state->parser, PROCESS, NULL, &state->out);
+            Parse(state->parser, PROCESS, minor, &state->out);
         } break;
         
         case NCD_TOKEN_TEMPLATE: {
-            Parse(state->parser, TEMPLATE, NULL, &state->out);
+            Parse(state->parser, TEMPLATE, minor, &state->out);
         } break;
         
         case NCD_TOKEN_NAME: {
-            Parse(state->parser, NAME, value, &state->out);
+            Parse(state->parser, NAME, minor, &state->out);
         } break;
         
         case NCD_TOKEN_STRING: {
-            Parse(state->parser, STRING, value, &state->out);
+            Parse(state->parser, STRING, minor, &state->out);
         } break;
         
         case NCD_TOKEN_COLON: {
-            Parse(state->parser, COLON, NULL, &state->out);
+            Parse(state->parser, COLON, minor, &state->out);
         } break;
         
         case NCD_TOKEN_BRACKET_OPEN: {
-            Parse(state->parser, BRACKET_OPEN, NULL, &state->out);
+            Parse(state->parser, BRACKET_OPEN, minor, &state->out);
         } break;
         
         case NCD_TOKEN_BRACKET_CLOSE: {
-            Parse(state->parser, BRACKET_CLOSE, NULL, &state->out);
+            Parse(state->parser, BRACKET_CLOSE, minor, &state->out);
         } break;
         
         default:

+ 14 - 9
ncd/NCDConfigParser_parse.y

@@ -35,6 +35,11 @@
 #include <misc/debug.h>
 #include <ncd/NCDConfig.h>
 
+struct parser_minor {
+    char *str;
+    size_t len;
+};
+
 struct parser_out {
     int out_of_memory;
     int syntax_error;
@@ -45,9 +50,9 @@ struct parser_out {
 
 %extra_argument {struct parser_out *parser_out}
 
-%token_type {void *}
+%token_type {struct parser_minor}
 
-%token_destructor { free($$); }
+%token_destructor { free($$.str); }
 
 %type processes {struct NCDConfig_processes *}
 %type statements {struct NCDConfig_statements *}
@@ -81,7 +86,7 @@ struct parser_out {
 // workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked
 %stack_overflow {
     if (yypMinor) {
-        free(yypMinor->yy0);
+        free(yypMinor->yy0.str);
     }
 }
 
@@ -94,14 +99,14 @@ input ::= processes(A). {
 }
 
 processes(R) ::= process_or_template(T) NAME(A) CURLY_OPEN statements(B) CURLY_CLOSE. {
-    R = NCDConfig_make_processes(T, A, B, 0, NULL);
+    R = NCDConfig_make_processes(T, A.str, B, 0, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
 }
 
 processes(R) ::= process_or_template(T) NAME(A) CURLY_OPEN statements(B) CURLY_CLOSE processes(N). {
-    R = NCDConfig_make_processes(T, A, B, 1, N);
+    R = NCDConfig_make_processes(T, A.str, B, 1, N);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
@@ -136,14 +141,14 @@ statements(R) ::= statement_names(M) ARROW statement_names(A) ROUND_OPEN stateme
 }
 
 statement_names(R) ::= NAME(A). {
-    R = NCDConfig_make_strings(A, 0, NULL);
+    R = NCDConfig_make_strings(A.str, 0, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
 }
 
 statement_names(R) ::= NAME(A) DOT statement_names(N). {
-    R = NCDConfig_make_strings(A, 1, N);
+    R = NCDConfig_make_strings(A.str, 1, N);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
@@ -216,7 +221,7 @@ map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. {
 }
 
 value(R) ::= STRING(A). {
-    R = NCDConfig_make_list_string(A, NULL);
+    R = NCDConfig_make_list_string(A.str, A.len, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }
@@ -248,7 +253,7 @@ name_maybe(R) ::= . {
 }
 
 name_maybe(R) ::= NAME(A). {
-    R = A;
+    R = A.str;
 }
 
 process_or_template(R) ::= PROCESS. {

+ 8 - 5
ncd/NCDConfigTokenizer.c

@@ -71,6 +71,7 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
         int error = 0;
         int token;
         void *token_val = NULL;
+        size_t token_len = 0;
         
         if (*str == '#') {
             l = 1;
@@ -142,6 +143,7 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
             else {
                 token = NCD_TOKEN_NAME;
                 token_val = buf;
+                token_len = l;
             }
         }
         else if (*str == '"') do {
@@ -157,7 +159,7 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
             
             // decode string
             while (l < left) {
-                char dec_ch;
+                uint8_t dec_ch;
                 
                 // get character
                 if (str[l] == '\\') {
@@ -184,7 +186,7 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
                 }
                 
                 // append character to string
-                if (!ExpString_AppendChar(&estr, dec_ch)) {
+                if (!ExpString_AppendByte(&estr, dec_ch)) {
                     BLog(BLOG_ERROR, "ExpString_AppendChar failed");
                     goto string_fail1;
                 }
@@ -201,6 +203,7 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
             
             token = NCD_TOKEN_STRING;
             token_val = ExpString_Get(&estr);
+            token_len = ExpString_Length(&estr);
             break;
             
         string_fail1:
@@ -220,13 +223,13 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
     out:
         // report error
         if (error) {
-            output(user, NCD_ERROR, NULL, line, line_char);
+            output(user, NCD_ERROR, NULL, 0, line, line_char);
             return;
         }
         
         // output token
         if (token) {
-            if (!output(user, token, token_val, line, line_char)) {
+            if (!output(user, token, token_val, token_len, line, line_char)) {
                 return;
             }
         }
@@ -245,5 +248,5 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
         left -= l;
     }
     
-    output(user, NCD_EOF, NULL, line, line_char);
+    output(user, NCD_EOF, NULL, 0, line, line_char);
 }

+ 1 - 1
ncd/NCDConfigTokenizer.h

@@ -50,7 +50,7 @@
 #define NCD_TOKEN_BRACKET_OPEN 14
 #define NCD_TOKEN_BRACKET_CLOSE 15
 
-typedef int (*NCDConfigTokenizer_output) (void *user, int token, char *value, size_t line, size_t line_char);
+typedef int (*NCDConfigTokenizer_output) (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char);
 
 void NCDConfigTokenizer_Tokenize (char *str, size_t str_len, NCDConfigTokenizer_output output, void *user);
 

+ 18 - 14
ncd/NCDValueParser.c

@@ -56,12 +56,12 @@ struct parser_state {
     void *parser;
 };
 
-static int tokenizer_output (void *user, int token, char *value, size_t line, size_t line_char);
+static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char);
 static int build_value (struct NCDConfig_list *ast, NCDValue *out);
 static int build_list_value (struct NCDConfig_list *list, NCDValue *out);
 static int build_map_value (struct NCDConfig_list *list, NCDValue *out);
 
-static int tokenizer_output (void *user, int token, char *value, size_t line, size_t line_char)
+static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char)
 {
     struct parser_state *state = (struct parser_state *)user;
     ASSERT(!state->out.out_of_memory)
@@ -87,37 +87,41 @@ static int tokenizer_output (void *user, int token, char *value, size_t line, si
         goto fail;
     }
     
+    struct parser_minor minor;
+    minor.str = value;
+    minor.len = value_len;
+    
     switch (token) {
         case NCD_EOF: {
-            Parse(state->parser, 0, NULL, &state->out);
+            Parse(state->parser, 0, minor, &state->out);
         } break;
         
         case NCD_TOKEN_CURLY_OPEN: {
-            Parse(state->parser, CURLY_OPEN, NULL, &state->out);
+            Parse(state->parser, CURLY_OPEN, minor, &state->out);
         } break;
         
         case NCD_TOKEN_CURLY_CLOSE: {
-            Parse(state->parser, CURLY_CLOSE, NULL, &state->out);
+            Parse(state->parser, CURLY_CLOSE, minor, &state->out);
         } break;
         
         case NCD_TOKEN_COMMA: {
-            Parse(state->parser, COMMA, NULL, &state->out);
+            Parse(state->parser, COMMA, minor, &state->out);
         } break;
         
         case NCD_TOKEN_STRING: {
-            Parse(state->parser, STRING, value, &state->out);
+            Parse(state->parser, STRING, minor, &state->out);
         } break;
         
         case NCD_TOKEN_COLON: {
-            Parse(state->parser, COLON, NULL, &state->out);
+            Parse(state->parser, COLON, minor, &state->out);
         } break;
         
         case NCD_TOKEN_BRACKET_OPEN: {
-            Parse(state->parser, BRACKET_OPEN, NULL, &state->out);
+            Parse(state->parser, BRACKET_OPEN, minor, &state->out);
         } break;
         
         case NCD_TOKEN_BRACKET_CLOSE: {
-            Parse(state->parser, BRACKET_CLOSE, NULL, &state->out);
+            Parse(state->parser, BRACKET_CLOSE, minor, &state->out);
         } break;
         
         default:
@@ -145,7 +149,7 @@ static int build_value (struct NCDConfig_list *ast, NCDValue *out)
 {
     switch (ast->type) {
         case NCDCONFIG_ARG_STRING: {
-            if (!NCDValue_InitString(out, ast->string)) {
+            if (!NCDValue_InitStringBin(out, ast->string, ast->string_len)) {
                 BLog(BLOG_ERROR, "NCDValue_InitString failed");
                 return 0;
             }
@@ -248,7 +252,7 @@ int NCDValueParser_Parse (const char *str, size_t str_len, NCDValue *out_value)
     state.out.out_of_memory = 0;
     state.out.syntax_error = 0;
     state.out.ast_type = AST_TYPE_NONE;
-    state.out.ast_string = NULL;
+    state.out.ast_string.str = NULL;
     state.out.ast_list = NULL;
     state.error = 0;
     
@@ -273,7 +277,7 @@ int NCDValueParser_Parse (const char *str, size_t str_len, NCDValue *out_value)
     NCDValue val;
     switch (state.out.ast_type) {
         case AST_TYPE_STRING: {
-            if (!NCDValue_InitString(&val, state.out.ast_string)) {
+            if (!NCDValue_InitStringBin(&val, state.out.ast_string.str, state.out.ast_string.len)) {
                 BLog(BLOG_ERROR, "NCDValue_InitString failed");
                 goto out;
             }
@@ -299,7 +303,7 @@ out:
     if (state.parser) {
         ParseFree(state.parser, free);
     }
-    free(state.out.ast_string);
+    free(state.out.ast_string.str);
     NCDConfig_free_list(state.out.ast_list);
     return res;
 }

+ 10 - 5
ncd/NCDValueParser_parse.y

@@ -40,11 +40,16 @@
 #define AST_TYPE_LIST 2
 #define AST_TYPE_MAP 3
 
+struct parser_minor {
+    char *str;
+    size_t len;
+};
+
 struct parser_out {
     int out_of_memory;
     int syntax_error;
     int ast_type;
-    char *ast_string;
+    struct parser_minor ast_string;
     struct NCDConfig_list *ast_list;
 };
 
@@ -52,9 +57,9 @@ struct parser_out {
 
 %extra_argument {struct parser_out *parser_out}
 
-%token_type {void *}
+%token_type {struct parser_minor}
 
-%token_destructor { free($$); }
+%token_destructor { free($$.str); }
 
 %type list_contents {struct NCDConfig_list *}
 %type list {struct NCDConfig_list *}
@@ -77,7 +82,7 @@ struct parser_out {
 // workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked
 %stack_overflow {
     if (yypMinor) {
-        free(yypMinor->yy0);
+        free(yypMinor->yy0.str);
     }
 }
 
@@ -161,7 +166,7 @@ map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. {
 }
 
 value(R) ::= STRING(A). {
-    R = NCDConfig_make_list_string(A, NULL);
+    R = NCDConfig_make_list_string(A.str, A.len, NULL);
     if (!R) {
         parser_out->out_of_memory = 1;
     }