LCOV - code coverage report
Current view: top level - src - ppg_chord.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 68 72 94.4 %
Date: 2018-01-08 Functions: 7 7 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 "ppg_chord.h"
      18             : #include "ppg_debug.h"
      19             : #include "detail/ppg_context_detail.h"
      20             : #include "detail/ppg_aggregate_detail.h"
      21             : #include "detail/ppg_pattern_detail.h"
      22             : #include "detail/ppg_token_detail.h"
      23             : #include "detail/ppg_token_precedence_detail.h"
      24             : 
      25             : typedef PPG_Aggregate PPG_Chord;
      26             : 
      27         336 : static bool ppg_chord_match_event(  
      28             :                                  PPG_Chord *chord,
      29             :                                  PPG_Event *event,
      30             :                                  bool modify_only_if_consuming) 
      31             : {
      32         336 :    PPG_LOG("Ch. chord\n");
      33             :    
      34         336 :    bool input_part_of_chord = false;
      35             :    
      36         336 :    PPG_ASSERT(chord->n_members != 0);
      37             :    
      38             :    /* Check if the input is part of the current chord 
      39             :     */
      40         750 :    for(PPG_Count i = 0; i < chord->n_members; ++i) {
      41             :       
      42         700 :       if(chord->inputs[i] == event->input) {
      43             :          
      44         286 :          input_part_of_chord = true;
      45             :          
      46         286 :          if(event->flags & PPG_Event_Active) {
      47         145 :             if(!ppg_bitfield_get_bit(&chord->member_active, i)) {
      48         145 :                ppg_bitfield_set_bit(&chord->member_active, i, true);
      49         145 :                ++chord->n_inputs_active;
      50             :             }
      51             :          }
      52             :          else {
      53             :             
      54         141 :             if(   ((chord->super.misc.flags & PPG_Aggregate_All_Active) == 0)
      55          66 :                && (chord->super.misc.flags &          
      56             :                         PPG_Chord_Flags_Disallow_Input_Deactivation)) {
      57             :                
      58           0 :                if(!modify_only_if_consuming) {
      59           0 :                   chord->super.misc.state = PPG_Token_Invalid;
      60             :                }
      61             :                
      62           0 :                return false;
      63             :             }
      64             :             
      65         141 :             if(ppg_bitfield_get_bit(&chord->member_active, i)) {
      66         115 :                ppg_bitfield_set_bit(&chord->member_active, i, false);
      67         115 :                --chord->n_inputs_active;
      68             :             }
      69             :             else {
      70             :                
      71             :                // The event deactivates an input that
      72             :                // was not previously registered as active.
      73             :                // Thus, we conclude that the event must be related
      74             :                // to a previous match. Ignore the event.
      75             :                //
      76          26 :                return false;
      77             :             }
      78             :          }
      79         260 :          break;
      80             :       }
      81             :    }
      82             :    
      83             : #if PPG_HAVE_LOGGING
      84        1240 :    for(PPG_Count i = 0; i < chord->n_members; ++i) {
      85         930 :       PPG_LOG("%d: 0x%d = %d\n", 
      86             :               i, 
      87             :               chord->inputs[i],
      88             :               ppg_bitfield_get_bit(&chord->member_active, i)
      89             :       );
      90             :    }
      91             : #endif
      92             :    
      93         310 :    if(!input_part_of_chord) {
      94          50 :       if(event->flags & PPG_Event_Active) {
      95             :          
      96          44 :          if(!modify_only_if_consuming) {
      97          44 :             chord->super.misc.state = PPG_Token_Invalid;
      98             :          }
      99             :       }
     100             :       
     101             :       // Chords ignore unmatching deactivation events
     102             :       
     103          50 :       return false;
     104             :    }
     105             :    
     106         260 :    chord->super.misc.state = PPG_Token_Activation_In_Progress;
     107             :    
     108         260 :    if(chord->n_inputs_active == chord->n_members) {
     109             :       
     110          25 :       chord->super.misc.flags |= PPG_Aggregate_All_Active;
     111             :       
     112             :       /* Chord matches
     113             :        */
     114          25 :       chord->super.misc.state = PPG_Token_Matches;
     115             : //       PPG_LOG("C");
     116             :    }
     117         235 :    else if(chord->n_inputs_active == 0) {
     118             :       
     119          47 :       if(chord->super.misc.flags & PPG_Aggregate_All_Active) {
     120             :       
     121          25 :          if(chord->super.misc.flags & PPG_Token_Flags_Pedantic) {
     122             :             /* Chord matches
     123             :             */
     124           0 :             chord->super.misc.state = PPG_Token_Matches;
     125             :          }
     126             :          else {
     127          25 :             chord->super.misc.state = PPG_Token_Finalized;
     128             :          }
     129             :       }
     130             :    }
     131             :    else {
     132         188 :       if(chord->super.misc.flags & PPG_Aggregate_All_Active) {
     133          50 :          chord->super.misc.state = PPG_Token_Deactivation_In_Progress;
     134             :       }
     135             :    }
     136             :    
     137         260 :    return true;
     138             : }
     139             : 
     140         142 : static PPG_Count ppg_chord_token_precedence(PPG_Token__ *token)
     141             : {
     142             :    PPG_UNUSED(token);
     143         142 :    return PPG_Token_Precedence_Chord;
     144             : }
     145             : 
     146          12 : static size_t ppg_chord_dynamic_member_size(PPG_Token *token)
     147             : {
     148          12 :    return   sizeof(PPG_Chord)
     149          12 :          +  ppg_aggregate_dynamic_member_size((PPG_Aggregate *)token);
     150             : }
     151             : 
     152          12 : static char *ppg_chord_placement_clone(PPG_Token__ *token, char *buffer)
     153             : {
     154          12 :    PPG_Chord *chord = (PPG_Chord *)token;
     155             :    
     156          12 :    *((PPG_Chord *)buffer) = *chord;
     157             :    
     158          12 :    PPG_Token__ *clone = (PPG_Token__ *)buffer;
     159             :    
     160             : //    printf("Replacing children pointer %p with %p\n", clone->children, (PPG_Token__ **)(buffer + sizeof(PPG_Chord)));
     161             :    
     162          12 :    clone->children = (PPG_Token__ **)(buffer + sizeof(PPG_Chord));
     163             :    
     164          12 :    return ppg_aggregate_copy_dynamic_members(token, clone, buffer + sizeof(PPG_Chord));
     165             : }
     166             : 
     167             : #if PPG_PRINT_SELF_ENABLED
     168         250 : static void ppg_chord_print_self(PPG_Chord *c, PPG_Count indent, bool recurse)
     169             : {
     170         250 :    PPG_I PPG_LOG("<*** chrd (0x%" PRIXPTR ") ***>\n", (uintptr_t)c);
     171         250 :    ppg_token_print_self_start((PPG_Token__*)c, indent);
     172         250 :    PPG_I PPG_LOG("\tn mem: %d\n", c->n_members);
     173         250 :    PPG_I PPG_LOG("\tn I actv: %d\n", c->n_inputs_active);
     174             :    
     175        1000 :    for(PPG_Count i = 0; i < c->n_members; ++i) {
     176         750 :       PPG_I PPG_LOG("\t\tI: 0x%d, actv: %d\n", 
     177             :               c->inputs[i],
     178             :                ppg_bitfield_get_bit(&c->member_active, i));
     179             :    }
     180         250 :    ppg_token_print_self_end((PPG_Token__*)c, indent, recurse);
     181         250 : }
     182             : #endif
     183             : 
     184             : PPG_Token_Vtable ppg_chord_vtable =
     185             : {
     186             :    .match_event
     187             :       = (PPG_Token_Match_Event_Fun) ppg_chord_match_event,
     188             :    .reset 
     189             :       = (PPG_Token_Reset_Fun) ppg_aggregate_reset,
     190             :    .destroy 
     191             :       = (PPG_Token_Destroy_Fun) ppg_aggregate_destroy,
     192             :    .equals
     193             :       = (PPG_Token_Equals_Fun) ppg_aggregates_equal,
     194             :    .token_precedence
     195             :       = (PPG_Token_Precedence_Fun)ppg_chord_token_precedence,
     196             :    .dynamic_size
     197             :       = (PPG_Token_Dynamic_Size_Requirement_Fun)ppg_chord_dynamic_member_size,
     198             :    .placement_clone
     199             :       = (PPG_Token_Placement_Clone_Fun)ppg_chord_placement_clone,
     200             :    .register_ptrs_for_compression
     201             :       = (PPG_Token_Register_Pointers_For_Compression)ppg_token_register_pointers_for_compression,
     202             :    .addresses_to_relative
     203             :       = (PPG_Token_Addresses_To_Relative)ppg_aggregate_addresses_to_relative,
     204             :    .addresses_to_absolute
     205             :       = (PPG_Token_Addresses_To_Absolute)ppg_aggregate_addresses_to_absolute
     206             :       
     207             :    #if PPG_PRINT_SELF_ENABLED
     208             :    ,
     209             :    .print_self
     210             :       = (PPG_Token_Print_Self_Fun) ppg_chord_print_self
     211             :    #endif
     212             :    
     213             :    #if PPG_HAVE_DEBUGGING
     214             :    ,
     215             :    .check_initialized
     216             :       = (PPG_Token_Check_Initialized_Fun)ppg_aggregate_check_initialized
     217             :    #endif
     218             : };
     219             : 
     220          20 : PPG_Token ppg_chord_create(   
     221             :                         PPG_Count n_inputs,
     222             :                         PPG_Input_Id inputs[])
     223             : {
     224          20 :    PPG_Chord *chord = (PPG_Chord*)ppg_aggregate_new(ppg_aggregate_alloc());
     225             :    
     226          20 :    chord->super.vtable = &ppg_chord_vtable;
     227             :    
     228             : //    PPG_LOG("in def: 0x%" PRIXPTR "\n", (uintptr_t)ppg_chord_match_event);
     229             :    
     230          20 :    return ppg_global_initialize_aggregate(chord, n_inputs, inputs);
     231             : }
     232             : 
     233          20 : PPG_Token ppg_chord(    
     234             :                      PPG_Layer layer, 
     235             :                      PPG_Action action, 
     236             :                      PPG_Count n_inputs,
     237             :                      PPG_Input_Id inputs[])
     238             : {     
     239             : //    PPG_LOG("Adding chord\n");
     240             :    
     241          20 :    PPG_Token__ *token = 
     242          20 :       (PPG_Token__ *)ppg_chord_create(n_inputs, inputs);
     243             :       
     244          20 :    token->action = action;
     245             :       
     246          20 :    PPG_Token__ *tokens[1] = { token };
     247             :    
     248          20 :    PPG_Token__ *leaf_token 
     249          20 :       = ppg_pattern_from_list(NULL, layer, 1, tokens);
     250             :       
     251          20 :    return leaf_token;
     252             : }

Generated by: LCOV version 1.10