LCOV - code coverage report
Current view: top level - Core/OXPVerifier - OOAIStateMachineVerifierStage.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 7 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOAIStateMachineVerifierStage.m
       4             : 
       5             : 
       6             : Oolite
       7             : Copyright (C) 2004-2013 Giles C Williams and contributors
       8             : 
       9             : This program is free software; you can redistribute it and/or
      10             : modify it under the terms of the GNU General Public License
      11             : as published by the Free Software Foundation; either version 2
      12             : of the License, or (at your option) any later version.
      13             : 
      14             : This program is distributed in the hope that it will be useful,
      15             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             : GNU General Public License for more details.
      18             : 
      19             : You should have received a copy of the GNU General Public License
      20             : along with this program; if not, write to the Free Software
      21             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      22             : MA 02110-1301, USA.
      23             : 
      24             : */
      25             : 
      26             : #import "OOAIStateMachineVerifierStage.h"
      27             : #import "OOCollectionExtractors.h"
      28             : #import "OOPListParsing.h"
      29             : 
      30             : #if OO_OXP_VERIFIER_ENABLED
      31             : 
      32             : #import "ResourceManager.h"
      33             : 
      34           0 : static NSString * const kStageName      = @"Validating AIs";
      35             : 
      36             : 
      37             : @interface OOAIStateMachineVerifierStage (Private)
      38             : 
      39           0 : - (void) validateAI:(NSString *)aiName;
      40             : 
      41             : @end
      42             : 
      43             : 
      44             : @implementation OOAIStateMachineVerifierStage
      45             : 
      46           0 : - (void) dealloc
      47             : {
      48             :         [_whitelist release];
      49             :         [_usedAIs release];
      50             :         
      51             :         [super dealloc];
      52             : }
      53             : 
      54             : 
      55           0 : - (NSString *) name
      56             : {
      57             :         return kStageName;
      58             : }
      59             : 
      60             : 
      61           0 : - (BOOL) shouldRun
      62             : {
      63             :         return [_usedAIs count] != 0;
      64             : }
      65             : 
      66             : 
      67           0 : - (void) run
      68             : {
      69             :         NSArray                                         *aiNames = nil;
      70             :         NSEnumerator                            *aiEnum = nil;
      71             :         NSString                                        *aiName = nil;
      72             :         NSMutableSet                            *whitelist = nil;
      73             :         
      74             :         // Build whitelist. Note that we merge in aliases since the distinction doesn't matter when just validating.
      75             :         whitelist = [[NSMutableSet alloc] init];
      76             :         [whitelist addObjectsFromArray:[[ResourceManager whitelistDictionary] oo_arrayForKey:@"ai_methods"]];
      77             :         [whitelist addObjectsFromArray:[[ResourceManager whitelistDictionary] oo_arrayForKey:@"ai_and_action_methods"]];
      78             :         [whitelist addObjectsFromArray:[[[ResourceManager whitelistDictionary] oo_dictionaryForKey:@"ai_method_aliases"] allKeys]];
      79             :         _whitelist = [whitelist copy];
      80             :         [whitelist release];
      81             :         
      82             :         aiNames = [[_usedAIs allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
      83             :         for (aiEnum = [aiNames objectEnumerator]; (aiName = [aiEnum nextObject]); )
      84             :         {
      85             :                 [self validateAI:aiName];
      86             :         }
      87             :         
      88             :         [_whitelist release];
      89             :         _whitelist = nil;
      90             : }
      91             : 
      92             : 
      93             : + (NSString *) nameForReverseDependencyForVerifier:(OOOXPVerifier *)verifier
      94             : {
      95             :         return kStageName;
      96             : }
      97             : 
      98             : 
      99             : - (void) stateMachineNamed:(NSString *)name usedByShip:(NSString *)shipName
     100             : {
     101             :         OOFileScannerVerifierStage      *fileScanner = nil;
     102             :         
     103             :         if (name == nil)  return;
     104             :         if ([_usedAIs containsObject:name])  return;
     105             :         if (_usedAIs == nil)  _usedAIs = [[NSMutableSet alloc] init];
     106             :         [_usedAIs addObject:name];
     107             :         
     108             :         fileScanner = [[self verifier] fileScannerStage];
     109             :         if (![fileScanner fileExists:name
     110             :                                                 inFolder:@"AIs"
     111             :                                   referencedFrom:[NSString stringWithFormat:@"shipdata.plist entry \"%@\"", shipName]
     112             :                                         checkBuiltIn:YES])
     113             :         {
     114             :                 OOLog(@"verifyOXP.validateAI.notFound", @"----- WARNING: AI state machine \"%@\" referenced in shipdata.plist entry \"%@\" could not be found in %@ or in Oolite.", name, shipName, [[self verifier] oxpDisplayName]);
     115             :         }
     116             : }
     117             : 
     118             : @end
     119             : 
     120             : 
     121             : @implementation OOAIStateMachineVerifierStage (Private)
     122             : 
     123             : - (void) validateAI:(NSString *)aiName
     124             : {
     125             :         NSString                                *path = nil;
     126             :         NSDictionary                    *aiStateMachine = nil;
     127             :         NSEnumerator                    *stateEnum = nil;
     128             :         NSString                                *stateKey = nil;
     129             :         NSDictionary                    *stateHandlers = nil;
     130             :         NSEnumerator                    *handlerEnum = nil;
     131             :         NSString                                *handlerKey = nil;
     132             :         NSArray                                 *handlerActions = nil;
     133             :         NSEnumerator                    *actionEnum = nil;
     134             :         NSString                                *action = nil;
     135             :         NSRange                                 spaceRange;
     136             :         NSString                                *selector = nil;
     137             :         NSMutableSet                    *badSelectors = nil;
     138             :         NSString                                *badSelectorDesc = nil;
     139             :         NSUInteger                              index = 0;
     140             :         
     141             :         OOLog(@"verifyOXP.verbose.validateAI", @"- Validating AI \"%@\".", aiName);
     142             :         OOLogIndentIf(@"verifyOXP.verbose.validateAI");
     143             :         
     144             :         // Attempt to load AI.
     145             :         path = [[[self verifier] fileScannerStage] pathForFile:aiName inFolder:@"AIs" referencedFrom:@"AI list" checkBuiltIn:NO];
     146             :         if (path == nil)  return;
     147             :         
     148             :         badSelectors = [NSMutableSet set];
     149             :         
     150             :         aiStateMachine = OODictionaryFromFile(path);
     151             :         if (aiStateMachine == nil)
     152             :         {
     153             :                 OOLog(@"verifyOXP.validateAI.failed.notDictPlist", @"***** ERROR: could not interpret \"%@\" as a dictionary.", path);
     154             :                 return;
     155             :         }
     156             :         
     157             :         // Validate each state.
     158             :         for (stateEnum = [aiStateMachine keyEnumerator]; (stateKey = [stateEnum nextObject]); )
     159             :         {
     160             :                 stateHandlers = [aiStateMachine objectForKey:stateKey];
     161             :                 if (![stateHandlers isKindOfClass:[NSDictionary class]])
     162             :                 {
     163             :                         OOLog(@"verifyOXP.validateAI.failed.invalidFormat.state", @"***** ERROR: state \"%@\" in AI \"%@\" is not a dictionary.", stateKey, aiName);
     164             :                         continue;
     165             :                 }
     166             :                 
     167             :                 // Verify handlers for this state.
     168             :                 for (handlerEnum = [stateHandlers keyEnumerator]; (handlerKey = [handlerEnum nextObject]); )
     169             :                 {
     170             :                         handlerActions = [stateHandlers objectForKey:handlerKey];
     171             :                         if (![handlerActions isKindOfClass:[NSArray class]])
     172             :                         {
     173             :                                 OOLog(@"verifyOXP.validateAI.failed.invalidFormat.handler", @"***** ERROR: handler \"%@\" for state \"%@\" in AI \"%@\" is not an array, ignoring.", handlerKey, stateKey, aiName);
     174             :                                 continue;
     175             :                         }
     176             :                         
     177             :                         // Verify commands for this handler.
     178             :                         index = 0;
     179             :                         for (actionEnum = [handlerActions objectEnumerator]; (action = [actionEnum nextObject]); )
     180             :                         {
     181             :                                 index++;
     182             :                                 if (![action isKindOfClass:[NSString class]])
     183             :                                 {
     184             :                                         OOLog(@"verifyOXP.validateAI.failed.invalidFormat.action", @"***** ERROR: action %lu in handler \"%@\" for state \"%@\" in AI \"%@\" is not a string, ignoring.", index - 1, handlerKey, stateKey, aiName);
     185             :                                         continue;
     186             :                                 }
     187             :                                 
     188             :                                 // Trim spaces from beginning and end.
     189             :                                 action = [action stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
     190             :                                 
     191             :                                 // Cut off parameters.
     192             :                                 spaceRange = [action rangeOfString:@" "];
     193             :                                 if (spaceRange.location == NSNotFound)  selector = action;
     194             :                                 else  selector = [action substringToIndex:spaceRange.location];
     195             :                                 
     196             :                                 // Check against whitelist.
     197             :                                 if (![_whitelist containsObject:selector])
     198             :                                 {
     199             :                                         [badSelectors addObject:selector];
     200             :                                 }
     201             :                         }
     202             :                 }
     203             :         }
     204             :         
     205             :         if ([badSelectors count] != 0)
     206             :         {
     207             :                 badSelectorDesc = [[[badSelectors allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@", "];
     208             :                 OOLog(@"verifyOXP.validateAI.failed.badSelector", @"***** ERROR: the AI \"%@\" uses %lu unpermitted method%s: %@", aiName, [badSelectors count], ([badSelectors count] == 1) ? "" : "s", badSelectorDesc);
     209             :         }
     210             :         
     211             :         OOLogOutdentIf(@"verifyOXP.verbose.validateAI");
     212             : }
     213             : 
     214             : @end
     215             : 
     216             : #endif

Generated by: LCOV version 1.14