LCOV - code coverage report
Current view: top level - src - passgen.c (source / functions) Hit Total Coverage
Test: passgen-test.info Lines: 54 54 100.0 %
Date: 2024-05-03 06:05:14 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include "passgen/parser/parser.h"
       2             : #include "passgen/parser/token.h"
       3             : #include "passgen/pattern/pattern.h"
       4             : #include "passgen/util/random.h"
       5             : #include "passgen/util/utf8.h"
       6             : #include <assert.h>
       7             : #include <passgen/passgen.h>
       8             : #include <string.h>
       9             : 
      10       20104 : int passgen_parse(
      11             :     passgen_pattern *output,
      12             :     passgen_error *error,
      13       20104 :     const char *string) {
      14             :     passgen_parser parser;
      15       20104 :     passgen_token_parser token_parser = {0};
      16       20104 :     passgen_token token = {0};
      17       20104 :     passgen_parser_init(&parser, output);
      18             : 
      19       20104 :     const uint8_t *pattern_raw = (const uint8_t *) string;
      20       20104 :     size_t pattern_len = 256;
      21       20104 :     uint32_t pattern[pattern_len];
      22       20104 :     uint8_t pattern_widths[pattern_len];
      23       20104 :     size_t pattern_pos = 0;
      24       20104 :     size_t pattern_pos_total = 0;
      25       20104 :     size_t pattern_raw_pos = 0;
      26       20104 :     size_t pattern_raw_len = strlen(string);
      27             : 
      28       20104 :     int decode_ret = 0;
      29             : 
      30             :     do {
      31       20105 :         uint32_t *pattern_cur = &pattern[0];
      32       20105 :         const uint8_t *pattern_raw_cur = &pattern_raw[pattern_raw_pos];
      33             : 
      34             :         // decode input utf8 into unicode codepoints
      35       20105 :         decode_ret = passgen_utf8_decode(
      36             :             &pattern_cur,
      37             :             pattern_len,
      38             :             pattern_widths,
      39             :             &pattern_raw_cur,
      40             :             pattern_raw_len - pattern_raw_pos);
      41             : 
      42       20105 :         pattern_raw_pos += pattern_raw_cur - &pattern_raw[pattern_raw_pos];
      43       20105 :         pattern_pos = pattern_cur - &pattern[0];
      44       20105 :         pattern_pos_total += pattern_pos;
      45             : 
      46             :         // make sure utf8 decoding was successful
      47       20105 :         if(decode_ret < PASSGEN_UTF8_SUCCESS) {
      48           8 :             passgen_error_init(error, passgen_utf8_error(decode_ret));
      49           8 :             passgen_error_offset_set(error, pattern_pos_total, pattern_raw_pos);
      50           8 :             passgen_parser_free(&parser);
      51        6350 :             return -1;
      52             :         }
      53             : 
      54             :         // parse tokens and pattern
      55      206977 :         for(size_t i = 0; i < pattern_pos; i++) {
      56      193222 :             int ret = passgen_token_parse(
      57             :                 &token_parser,
      58             :                 &token,
      59      193222 :                 pattern_widths[i],
      60             :                 pattern[i]);
      61             : 
      62             :             // make sure parsing the token was successful
      63      193222 :             if(ret < 0) {
      64          38 :                 passgen_error_init(error, passgen_token_parse_error_str(ret));
      65          38 :                 passgen_error_offset_set(error, token.offset, token.byte_offset);
      66          38 :                 passgen_parser_free(&parser);
      67          38 :                 return -1;
      68             :             }
      69             : 
      70             :             // if we have a token, feed it to the parser
      71      193184 :             if(ret == PASSGEN_TOKEN_INIT) {
      72      190315 :                 ret = passgen_parse_token(&parser, &token);
      73             :                 // make sure that the parser accepts the token
      74      190315 :                 if(ret != 0) {
      75        6304 :                     passgen_error_init(error, "invalid token");
      76        6304 :                     passgen_error_offset_set(error, token.offset, token.byte_offset);
      77        6304 :                     passgen_parser_free(&parser);
      78        6304 :                     return -1;
      79             :                 }
      80      184011 :                 assert(ret == 0);
      81             :             }
      82             :         }
      83       13755 :     } while(decode_ret > PASSGEN_UTF8_SUCCESS);
      84             : 
      85             :     // make sure we aren't still parsing tokens
      86       13754 :     if(token_parser.state != PASSGEN_TOKEN_INIT) {
      87         240 :         passgen_error_init(error, passgen_token_parse_error_str(token_parser.state));
      88         240 :         passgen_error_offset_set(error, pattern_pos_total, pattern_raw_pos);
      89         240 :         passgen_parser_free(&parser);
      90         240 :         return -1;
      91             :     }
      92             : 
      93             :     // make sure we are done parsing
      94       13514 :     if(0 != passgen_parse_finish(&parser)) {
      95        4029 :         passgen_error_init(error, "parsing not finished");
      96        4029 :         passgen_error_offset_set(error, pattern_pos_total, pattern_raw_pos);
      97        4029 :         passgen_parser_free(&parser);
      98        4029 :         return -1;
      99             :     }
     100             : 
     101        9485 :     passgen_parser_free(&parser);
     102             : 
     103        9485 :     return 0;
     104             : }

Generated by: LCOV version 1.14