LCOV - code coverage report
Current view: top level - libgfs2 - parser.y (source / functions) Coverage Total Hit
Test: gfs2-utils.info Lines: 41.5 % 94 39
Test Date: 2024-03-07 16:24:06 Functions: 60.0 % 5 3

            Line data    Source code
       1              : %code requires {
       2              : /* Required to break a circular dependency introduced with bison 2.6 */
       3              : typedef void* yyscan_t;
       4              : }
       5              : %code top {
       6              : #include <errno.h>
       7              : #include "lang.h"
       8              : #include "lexer.h"
       9              : 
      10            0 : static int yyerror(struct lgfs2_lang_state *state, yyscan_t lexer, const char *errorstr)
      11              : {
      12            0 :         fprintf(stderr, "%d:%d: %s\n", state->ls_linenum, state->ls_colnum, errorstr);
      13            0 :         return 1;
      14              : }
      15              : 
      16              : }
      17              : %defines
      18              : %debug
      19              : %define api.pure
      20              : %parse-param { struct lgfs2_lang_state *state }
      21              : %parse-param { yyscan_t lexer }
      22              : %lex-param { yyscan_t lexer }
      23              : %start script
      24              : %token TOK_COLON
      25              : %token TOK_COMMA
      26              : %token TOK_ID
      27              : %token TOK_LBRACE
      28              : %token TOK_LBRACKET
      29              : %token TOK_NUMBER
      30              : %token TOK_OFFSET
      31              : %token TOK_RBRACE
      32              : %token TOK_RBRACKET
      33              : %token TOK_SEMI
      34              : %token TOK_SET
      35              : %token TOK_GET
      36              : %token TOK_STATE
      37              : %token TOK_STRING
      38              : %token TOK_PATH
      39              : %%
      40              : script: statements {
      41            8 :                 state->ls_ast_root = $1;
      42            8 :                 state->ls_interp_curr = $1;
      43              :         }
      44              :         | statements TOK_SEMI {
      45            0 :                 state->ls_ast_root = $1;
      46            0 :                 state->ls_interp_curr = $1;
      47              :         }
      48              : ;
      49              : statements: statements TOK_SEMI statement {
      50            0 :                 state->ls_ast_tail->ast_left = $3;
      51            0 :                 state->ls_ast_tail = $3;
      52            0 :                 $$ = $1;
      53              :         }
      54              :         | statement {
      55            8 :                 if (state->ls_ast_tail == NULL)
      56            8 :                         state->ls_ast_tail = $1;
      57            8 :                 $$ = $1;
      58              :         }
      59              : ;
      60            8 : statement: set_stmt { $$ = $1;}
      61            0 :         | get_stmt { $$ = $1; }
      62              : ;
      63              : set_stmt: TOK_SET blockspec structspec {
      64            8 :                 $1->ast_right = $2;
      65            8 :                 $2->ast_right = $3;
      66            8 :                 $$ = $1;
      67              :         }
      68              :         | TOK_SET blockspec typespec structspec {
      69            0 :                 $1->ast_right = $2;
      70            0 :                 $2->ast_right = $3;
      71            0 :                 $3->ast_right = $4;
      72            0 :                 $$ = $1;
      73              :         }
      74              : ;
      75              : get_stmt: TOK_GET blockspec {
      76            0 :                 $1->ast_right = $2; $$ = $1;
      77              :         }
      78              :         | TOK_GET blockspec TOK_STATE {
      79            0 :                 $1->ast_right = $2;
      80            0 :                 $2->ast_right = $3;
      81            0 :                 $$ = $1;
      82              :         }
      83              : ;
      84            0 : blockspec: offset { $$ = $1; }
      85            0 :         | address { $$ = $1; }
      86            1 :         | path { $$ = $1; }
      87            7 :         | block_literal { $$ = $1; }
      88            0 :         | subscript { $$ = $1; }
      89              : ;
      90              : offset: blockspec TOK_OFFSET {
      91            0 :                 $2->ast_left = $1;
      92            0 :                 $$ = $2;
      93              :         }
      94              : ;
      95              : typespec: identifier {
      96            0 :                 $1->ast_type = AST_EX_TYPESPEC;
      97            0 :                 $$ = $1;
      98              :         }
      99              : ;
     100            7 : block_literal: identifier { $$ = $1; }
     101              : ;
     102              : subscript: block_literal TOK_LBRACKET index TOK_RBRACKET {
     103            0 :                 $4->ast_left = $1;
     104            0 :                 $1->ast_left = $3;
     105            0 :                 $$ = $4;
     106              :         }
     107              : ;
     108            0 : index: number { $$ = $1; }
     109            0 :         | identifier { $$ = $1; }
     110              : ;
     111              : address: number {
     112            0 :                 $1->ast_type = AST_EX_ADDRESS;
     113            0 :                 $$ = $1;
     114              :          }
     115              : ;
     116            8 : structspec: TOK_LBRACE fieldspecs TOK_RBRACE { $$ = $2; }
     117            0 :         | TOK_LBRACE TOK_RBRACE { $$ = NULL; }
     118              : ;
     119              : fieldspecs: fieldspecs TOK_COMMA fieldspec {
     120            0 :                 $1->ast_left = $3;
     121            0 :                 $$ = $1;
     122              :         }
     123            8 :         | fieldspec { $$ = $1; }
     124              : ;
     125              : fieldspec: identifier TOK_COLON fieldvalue {
     126            8 :                 $2->ast_right = $1;
     127            8 :                 $1->ast_right = $3;
     128            8 :                 $$ = $2;
     129              :         }
     130              : ;
     131            8 : fieldvalue: number { $$ = $1; }
     132            0 :         | string { $$ = $1; }
     133              : ;
     134            8 : number: TOK_NUMBER { $$ = $1; }
     135            0 : string: TOK_STRING { $$ = $1; }
     136           15 : identifier: TOK_ID { $$ = $1; }
     137            1 : path: TOK_PATH { $$ = $1; }
     138              : %%
     139              : 
     140              : /**
     141              :  * Allocate and initialize a new parse state structure. The caller must free the
     142              :  * memory returned by this function.
     143              :  */
     144            8 : struct lgfs2_lang_state *lgfs2_lang_init(void)
     145              : {
     146              :         struct lgfs2_lang_state *state;
     147            8 :         state = calloc(1, sizeof(struct lgfs2_lang_state));
     148            8 :         if (state == NULL) {
     149            0 :                 return NULL;
     150              :         }
     151            8 :         state->ls_linenum = 1;
     152            8 :         return state;
     153              : }
     154              : 
     155            8 : void lgfs2_lang_free(struct lgfs2_lang_state **state)
     156              : {
     157            8 :         ast_destroy(&(*state)->ls_ast_root);
     158            8 :         free(*state);
     159            8 :         *state = NULL;
     160            8 : }
     161              : 
     162            8 : int lgfs2_lang_parsef(struct lgfs2_lang_state *state, FILE *src)
     163              : {
     164            8 :         int ret = 0;
     165              :         yyscan_t lexer;
     166              : 
     167            8 :         ret = yylex_init_extra(state, &lexer);
     168            8 :         if (ret != 0) {
     169            0 :                 fprintf(stderr, "Failed to initialize lexer.\n");
     170            0 :                 return ret;
     171              :         }
     172              : 
     173            8 :         yyset_in(src, lexer);
     174            8 :         ret = yyparse(state, lexer);
     175            8 :         yylex_destroy(lexer);
     176            8 :         return ret;
     177              : }
     178              : 
     179            0 : int lgfs2_lang_parses(struct lgfs2_lang_state *state, const char *cstr)
     180              : {
     181              :         int ret;
     182              :         FILE *src;
     183            0 :         char *str = strdup(cstr);
     184              : 
     185            0 :         if (str == NULL) {
     186            0 :                 perror("Failed to duplicate source string");
     187            0 :                 return 1;
     188              :         }
     189              :         /* coverity[alloc_strlen:SUPPRESS] False positive */
     190            0 :         src = fmemopen(str, strlen(str), "r");
     191            0 :         if (src == NULL) {
     192            0 :                 perror("Failed to open string as source file");
     193            0 :                 free(str);
     194            0 :                 return 1;
     195              :         }
     196            0 :         ret = lgfs2_lang_parsef(state, src);
     197            0 :         fclose(src);
     198            0 :         free(str);
     199            0 :         if (ret != 0 || state->ls_errnum != 0) {
     200            0 :                 return 1;
     201              :         }
     202            0 :         return 0;
     203              : }
        

Generated by: LCOV version 2.0-1