LCOV - code coverage report
Current view: top level - src/detail - ppg_note_detail.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 85 99 85.9 %
Date: 2018-01-08 Functions: 9 10 90.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_note_detail.h"
      18             : #include "ppg_debug.h"
      19             : #include "detail/ppg_context_detail.h"
      20             : #include "detail/ppg_input_detail.h"
      21             : #include "detail/ppg_token_detail.h"
      22             : #include "detail/ppg_token_precedence_detail.h"
      23             : #include "detail/ppg_malloc_detail.h"
      24             : 
      25             : #include <stdlib.h>
      26             : 
      27         614 : static bool ppg_note_match_event(   
      28             :                                  PPG_Note *note,
      29             :                                  PPG_Event *event,
      30             :                                  bool modify_only_if_consuming
      31             :                                 ) 
      32             : {  
      33         614 :    PPG_LOG("Nt 0x%" PRIXPTR ", input 0x%d, ppg_note_match_event\n", (uintptr_t)note, note->input);
      34             :    
      35         614 :    PPG_Count note_flags 
      36         614 :       = note->super.misc.flags;
      37             :    
      38             :    // Assert that the note requires either activation or deactivation
      39             :    //
      40         614 :    PPG_ASSERT(note_flags != 0);
      41             :    
      42         614 :    switch(note_flags & (   PPG_Note_Flag_Match_Activation
      43             :                         | PPG_Note_Flag_Match_Deactivation)) {
      44             :      
      45             :       case     (PPG_Note_Flag_Match_Activation
      46             :             | PPG_Note_Flag_Match_Deactivation):
      47             :             
      48         580 :             if(note->input != event->input) {
      49         166 :                if(   (note_flags & PPG_Token_Flags_Pedantic) 
      50         166 :                   || (event->flags & PPG_Event_Active)) {
      51             :                   
      52          42 :                   if(!modify_only_if_consuming) {
      53          42 :                      note->super.misc.state = PPG_Token_Invalid;
      54             :                   }
      55             :                }
      56             : 
      57         166 :                return false;
      58             :             }
      59             :                
      60         414 :             if(event->flags & PPG_Event_Active) {
      61             :                
      62         196 :                PPG_LOG("I act\n");
      63             :                
      64             :                // Mark the note as active
      65             :                //
      66         196 :                note->super.misc.flags |= PPG_Note_Type_Active;
      67             :                
      68         196 :                PPG_LOG("Nt 0x%" PRIXPTR " fin\n", (uintptr_t)note);
      69             :                
      70         196 :                if(note_flags & PPG_Token_Flags_Pedantic) {
      71           0 :                   note->super.misc.state = PPG_Token_Activation_In_Progress;
      72             :                }
      73             :                else {
      74         196 :                   note->super.misc.state = PPG_Token_Matches;
      75             :                }
      76             :             }
      77             :             else {
      78             :                
      79         218 :                if(note_flags & PPG_Note_Type_Active) {
      80         186 :                   PPG_LOG("I deact\n");
      81             :                
      82         186 :                   if(note_flags & PPG_Token_Flags_Pedantic) {
      83           0 :                      PPG_LOG("Nt fin\n");
      84             :          //             PPG_LOG("N");
      85           0 :                      note->super.misc.state = PPG_Token_Matches;
      86             :                   }
      87             :                   else {
      88         186 :                      note->super.misc.state = PPG_Token_Finalized;
      89             :                   }
      90             :                }
      91             :                else {
      92             :                
      93             :                   // The input is not active but this is a deactivation 
      94             :                   // event. Thus, we ignore it as it belongs 
      95             :                   // to the activation of another token.
      96             :                   
      97             :                   // Note: Even the deactivation of the associated input must
      98             :                   //       be ignored here.
      99             :                   //
     100          32 :                   return false;
     101             :                }
     102             :             }
     103         382 :             break;
     104             :             
     105             :       case PPG_Note_Flag_Match_Activation:
     106             :          
     107          24 :          PPG_LOG("Only act\n");
     108          24 :          if(   (note->input == event->input)
     109          14 :             && (event->flags & PPG_Event_Active)) {
     110          12 :             PPG_LOG("I mtch\n");
     111          12 :             note->super.misc.state = PPG_Token_Matches;
     112          12 :             note->super.misc.flags |= PPG_Token_Flags_Done;
     113          12 :             return true;
     114             :          }
     115             :          
     116          12 :          PPG_LOG("I inact\n");
     117          12 :          if(!modify_only_if_consuming) {
     118          12 :             note->super.misc.state = PPG_Token_Invalid;
     119             :          }
     120             :          
     121          12 :          return false;
     122             :          
     123             :       case PPG_Note_Flag_Match_Deactivation:
     124             :       
     125          10 :          if(   (note->input == event->input)
     126           8 :             && ((event->flags & PPG_Event_Active) == 0)) {
     127           8 :             note->super.misc.state = PPG_Token_Finalized;
     128             :             
     129           8 :             note->super.misc.flags |= PPG_Token_Flags_Done;
     130           8 :             return true;
     131             :          }
     132             :          
     133           2 :          if(!modify_only_if_consuming) {
     134           2 :             note->super.misc.state = PPG_Token_Invalid;
     135             :          }
     136             :          
     137           2 :          return false;
     138             :    }
     139             :    
     140         382 :    return true;
     141             : }
     142             : 
     143         283 : static void ppg_note_reset(PPG_Note *note) 
     144             : {
     145         283 :    ppg_token_reset_control_state((PPG_Token__*)note);
     146             :    
     147             :    // Notes that only match deactivation start in matching state
     148             :    //
     149         566 :    if((note->super.misc.flags 
     150         283 :                      & PPG_Note_Flag_Match_Activation) == 0) {
     151          10 :       note->super.misc.state = PPG_Token_Matches;
     152             :    }
     153             :    
     154             :    // Clear the activation state
     155             :    //
     156             :    note->super.misc.flags 
     157         283 :          &= (PPG_Count)~PPG_Note_Type_Active;
     158         283 : }
     159             : 
     160        6744 : static bool ppg_note_equals(PPG_Note *n1, PPG_Note *n2) 
     161             : {
     162        6744 :    return n1->input == n2->input;
     163             : }
     164             : 
     165         280 : static PPG_Count ppg_note_token_precedence(PPG_Token__ *token)
     166             : {
     167         280 :    PPG_Note *note = (PPG_Note *)token;
     168             :    
     169         280 :    PPG_Count note_flags = note->super.misc.flags;
     170             :    
     171         280 :    if(   (note_flags & PPG_Note_Flag_Match_Activation)
     172         280 :       && (note_flags & PPG_Note_Flag_Match_Deactivation)) {
     173         280 :       return PPG_Token_Precedence_Note;
     174             :    }
     175             :    
     176           0 :    return PPG_Token_Precedence_Explicit_Note;
     177             : }
     178             : 
     179         826 : static size_t ppg_note_dynamic_size(PPG_Token__ *token)
     180             : {
     181         826 :    return   sizeof(PPG_Note)
     182         826 :          +  ppg_token_dynamic_member_size(token);
     183             : }
     184             : 
     185         826 : static char *ppg_note_placement_clone(PPG_Token__ *token, char *buffer)
     186             : {
     187         826 :    PPG_Note *note = (PPG_Note *)token;
     188             :    
     189         826 :    *((PPG_Note *)buffer) = *note;
     190             :    
     191         826 :    PPG_Token__ *clone = (PPG_Token__ *)buffer;
     192             :    
     193             : //    printf("Replacing children pointer %p with %p\n", clone->children, (PPG_Token__ **)(buffer + sizeof(PPG_Note)));
     194             :    
     195         826 :    clone->children = (PPG_Token__ **)(buffer + sizeof(PPG_Note));
     196             :    
     197         826 :    return ppg_token_copy_dynamic_members(token, buffer + sizeof(PPG_Note));
     198             : }
     199             : 
     200             : #if PPG_PRINT_SELF_ENABLED
     201        1668 : static void ppg_note_print_self(PPG_Note *p, PPG_Count indent, bool recurse)
     202             : {
     203        1668 :    PPG_I PPG_LOG("<*** nt (0x%" PRIXPTR ") ***>\n", (uintptr_t)p);
     204        1668 :    ppg_token_print_self_start((PPG_Token__*)p, indent);
     205        1668 :    PPG_I PPG_LOG("\tI: 0x%" PRIXPTR "\n", (uintptr_t)p->input);
     206        1668 :    PPG_I PPG_LOG("\tA: %d\n", (p->super.misc.flags & PPG_Note_Type_Active));
     207        1668 :    PPG_I PPG_LOG("\tm a: %d\n", (bool)(p->super.misc.flags & PPG_Note_Flag_Match_Activation));
     208        1668 :    PPG_I PPG_LOG("\tm d: %d\n", (bool)(p->super.misc.flags & PPG_Note_Flag_Match_Deactivation));
     209        1668 :    ppg_token_print_self_end((PPG_Token__*)p, indent, recurse);
     210        1668 : }
     211             : #endif
     212             : 
     213             : #if PPG_HAVE_DEBUGGING
     214           0 : static bool ppg_note_check_initialized(PPG_Token__ *token)
     215             : {
     216           0 :    PPG_Note *note = (PPG_Note *)token;
     217             :   
     218           0 :    bool assertion_failed = false;
     219             :    
     220             :    // Skip the parent call as we need a specialized check
     221             : //    assertion_failed |= ppg_token_check_initialized(token);
     222             :    
     223           0 :    if((note->super.misc.flags 
     224           0 :                      & PPG_Note_Flag_Match_Activation) == 0) {
     225           0 :       PPG_ASSERT_WARN(note->super.misc.state == PPG_Token_Matches);
     226             :    }
     227             :    else {
     228           0 :       PPG_ASSERT_WARN(note->super.misc.state == PPG_Token_Initialized);
     229             :    }
     230             :    
     231           0 :    PPG_ASSERT_WARN(token->misc.action_state == PPG_Action_Disabled);
     232             :    
     233           0 :    PPG_ASSERT_WARN(
     234             :       (note->super.misc.flags 
     235             :          & PPG_Note_Type_Active) == 0);
     236             :    
     237           0 :    return assertion_failed;
     238             : }
     239             : #endif
     240             : 
     241             : PPG_Token_Vtable ppg_note_vtable =
     242             : {
     243             :    .match_event 
     244             :       = (PPG_Token_Match_Event_Fun) ppg_note_match_event,
     245             :    .reset 
     246             :       = (PPG_Token_Reset_Fun) ppg_note_reset,
     247             :    .destroy 
     248             :       = (PPG_Token_Destroy_Fun) ppg_token_destroy,
     249             :    .equals
     250             :       = (PPG_Token_Equals_Fun) ppg_note_equals,
     251             :    .token_precedence
     252             :       = (PPG_Token_Precedence_Fun)ppg_note_token_precedence,
     253             :    .dynamic_size 
     254             :       = (PPG_Token_Dynamic_Size_Requirement_Fun)ppg_note_dynamic_size,
     255             :    .placement_clone
     256             :       = (PPG_Token_Placement_Clone_Fun)ppg_note_placement_clone,
     257             :    .register_ptrs_for_compression
     258             :       = (PPG_Token_Register_Pointers_For_Compression)ppg_token_register_pointers_for_compression,
     259             :    .addresses_to_relative
     260             :       = (PPG_Token_Addresses_To_Relative)ppg_token_addresses_to_relative,
     261             :    .addresses_to_absolute
     262             :       = (PPG_Token_Addresses_To_Absolute)ppg_token_addresses_to_absolute
     263             :    #if PPG_PRINT_SELF_ENABLED
     264             :    ,
     265             :    .print_self
     266             :       = (PPG_Token_Print_Self_Fun) ppg_note_print_self
     267             :    #endif
     268             :    
     269             :    #if PPG_HAVE_DEBUGGING
     270             :    ,
     271             :    .check_initialized
     272             :       = (PPG_Token_Check_Initialized_Fun)ppg_note_check_initialized
     273             :    #endif
     274             : };
     275             : 
     276        1284 : PPG_Note *ppg_note_new(PPG_Note *note)
     277             : {
     278             :     /* Explict call to parent constructor 
     279             :      */
     280        1284 :     ppg_token_new((PPG_Token__*)note);
     281             : 
     282        1284 :     note->super.vtable = &ppg_note_vtable;
     283             :     
     284        1284 :     note->super.misc.flags = PPG_Token_Flags_Empty;
     285             :     
     286        1284 :     ppg_global_init_input(&note->input);
     287             :     
     288        1284 :     return note;
     289             : }
     290             : 
     291        1284 : PPG_Note *ppg_note_alloc(void) {
     292        1284 :     return (PPG_Note*)PPG_MALLOC(sizeof(PPG_Note));
     293             : }

Generated by: LCOV version 1.10