LCOV - code coverage report
Current view: top level - src/detail - ppg_pattern_detail.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 47 55 85.5 %
Date: 2018-01-08 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* Copyright 2017 noseglasses <shinynoseglasses@gmail.com>
       2             :  *
       3             :  * This program is free software: you can redistribute it and/or modify
       4             :  * it under the terms of the GNU Lesser General Public License as published by
       5             :  * the Free Software Foundation, either version 3 of the License, or
       6             :  * (at your option) any later version.
       7             :  *
       8             :  * This program is distributed in the hope that it will be useful,
       9             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      10             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      11             :  * GNU Lesser General Public License for more details.
      12             :  *
      13             :  * You should have received a copy of the GNU Lesser General Public License
      14             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      15             :  */
      16             : 
      17             : #include "detail/ppg_pattern_detail.h"
      18             : #include "detail/ppg_token_detail.h"
      19             : #include "detail/ppg_context_detail.h"
      20             : #include "ppg_debug.h"
      21             : #include "ppg_action.h"
      22             : 
      23         869 : PPG_Token ppg_pattern_from_list( 
      24             :                                     PPG_Token__ *parent_token,
      25             :                                     PPG_Layer layer,
      26             :                                     PPG_Count n_tokens,
      27             :                                     PPG_Token__ *tokens[])
      28             : {  
      29         869 :    if(!parent_token) {
      30         860 :       parent_token = ppg_context->pattern_root;
      31             :    }
      32             :    
      33         869 :    PPG_LOG("\troot: %p\n", parent_token);
      34             :    
      35         869 :    PPG_LOG("\t%d memb\n", n_tokens);
      36             :    
      37        4243 :    for (PPG_Count i = 0; i < n_tokens; i++) { 
      38             :       
      39        3374 :       if(tokens[i] == NULL) { 
      40             :          // Ignore empty members. This is helpful
      41             :          // when an additional NULL ptr needs to be added 
      42             :          // in generation macros.
      43             :       }
      44             :       
      45        3374 :       PPG_Token__ *cur_token = tokens[i];
      46             :       
      47        3374 :       PPG_Token__ *equivalent_child 
      48             :          = ppg_token_get_equivalent_child(parent_token, cur_token);
      49             :          
      50        3374 :       PPG_LOG("\tmemb %d: ", i);
      51             :       
      52        3374 :       if(equivalent_child == cur_token) {
      53             :          
      54        2052 :          PPG_LOG("identical t: 0x%" PRIXPTR "\n", (uintptr_t)equivalent_child);
      55             :          
      56        2052 :          parent_token = equivalent_child;
      57             :       }
      58        1322 :       else if(  equivalent_child
      59             :                
      60             :                /* Only share interior nodes and ...
      61             :                */
      62          42 :                && equivalent_child->children
      63             :                
      64             :                /* ... only if the 
      65             :                * newly registered node on the respective level is 
      66             :                * not a leaf node.
      67             :                */ 
      68          36 :                && (i < (n_tokens - 1))
      69             :                
      70             :                // And only if the actions associated with both nodes are equal
      71             :                //
      72          72 :                && (cur_token->action.callback.func 
      73          36 :                         == equivalent_child->action.callback.func)
      74             :                
      75          72 :                && (cur_token->action.callback.user_data 
      76          36 :                         == equivalent_child->action.callback.user_data)
      77             :       ) {
      78             :          
      79          36 :          PPG_LOG("alrd prsntt: 0x%" PRIXPTR "\n", (uintptr_t)equivalent_child);
      80             :          
      81          36 :          parent_token = equivalent_child;
      82             :          
      83          36 :          if(layer < equivalent_child->layer) {
      84             :             
      85           0 :             equivalent_child->layer = layer;
      86             :          }
      87             :          
      88             :          /* The child is already registered in the search tree. Delete the newly created version.
      89             :           */         
      90          36 :          ppg_token_free(cur_token);
      91             :       }
      92             :       else {
      93             :          
      94        1286 :          PPG_LOG("new def: 0x%" PRIXPTR "\n", (uintptr_t)cur_token);
      95             :          
      96        1286 :          PPG_LOG("   act. clbk. 0x%" PRIXPTR "\n", (uintptr_t)cur_token->action.callback.func);
      97        1286 :          PPG_LOG("   act. u.d. 0x%" PRIXPTR "\n", (uintptr_t)cur_token->action.callback.user_data);
      98             :          
      99             :          #if PPG_HAVE_ASSERTIONS
     100             :          
     101             :          /* Detect pattern ambiguities
     102             :           */
     103        1286 :          if(equivalent_child) {
     104           6 :             if(   
     105             :                /* Melodies are ambiguous if ...
     106             :                 * the conflicting nodes/tokens are both leaf tokens
     107             :                 */
     108           6 :                   (i == (n_tokens - 1))
     109           6 :                && !equivalent_child->children
     110             :                
     111             :                /* And defined for the same layer
     112             :                 */
     113           6 :                && (equivalent_child->layer == layer)
     114             :             ) {
     115             :                // Conflicting melodies detected
     116             :                //
     117           0 :                PPG_ERROR("Conf mel det.\n")
     118             :                
     119             :                #if PPG_PRINT_SELF_ENABLED
     120           0 :                PPG_ERROR(
     121             :                   "Tk of conf. patt:\n");
     122             :                
     123           0 :                PPG_ERROR("Prev def:\n");
     124             :                
     125           0 :                PPG_PRINT_TOKEN(equivalent_child)
     126             :                
     127           0 :                PPG_ERROR("Confl:\n");
     128           0 :                for (PPG_Count i = 0; i < n_tokens; i++) {
     129           0 :                   PPG_PRINT_TOKEN(tokens[i])
     130             :                }
     131             :                #endif
     132             :             }
     133             :          }
     134             :          #endif /* if PPG_HAVE_LOGGING */
     135             :                
     136        1286 :          cur_token->layer = layer;
     137             :          
     138             : //          printf("Adding %p to %p\n", cur_token, parent_token);
     139        1286 :          ppg_token_add_child(parent_token, cur_token);
     140             :          
     141        1286 :          parent_token = cur_token;
     142             :       }
     143             :    }
     144             :    
     145             :    /* Return the leaf token 
     146             :     */
     147         869 :    return parent_token;
     148             : }
     149             : 
     150        1318 : PPG_Count ppg_branch_depth(PPG_Token__ *token)
     151             : {
     152        1318 :    if(!token) { return 0; }
     153             :    
     154        1318 :    PPG_Count max_depth = 0;
     155             :    
     156        2604 :    for(PPG_Count i = 0; i < token->n_children; ++i) {
     157             :       
     158        1286 :       PPG_Count cur_depth = 
     159        1286 :          ppg_branch_depth(token->children[i]);
     160             :          
     161        1286 :       if(cur_depth > max_depth) {
     162         461 :          max_depth = cur_depth;
     163             :       }
     164             :    }
     165             :    
     166        1318 :    return 1 + max_depth;
     167             : }
     168             : 
     169          32 : PPG_Count ppg_pattern_tree_depth(void)
     170             : {
     171          32 :    return ppg_branch_depth(ppg_context->pattern_root);
     172             : }

Generated by: LCOV version 1.10