/* ** ObjCBlockHandler.m ** ** Copyright (c) 2003 ** ** Author: Yen-Ju ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ObjCBlockHandler.h" #include @implementation ObjCBlockHandler + (BOOL) isDelimiter: (NSString *) de { if ( ([de isEqualToString: @"["]) || ([de isEqualToString: @"]"]) || ([de isEqualToString: @"{"]) || ([de isEqualToString: @"}"]) || ([de isEqualToString: @"("]) || ([de isEqualToString: @")"]) ) return YES; else return NO; } - (BOOL) searchBackward: (NSString *) de { if ([_delimiter isEqualToString: @"["]) return NO; else if ([_delimiter isEqualToString: @"]"]) return YES; else if ([_delimiter isEqualToString: @"{"]) return NO; else if ([_delimiter isEqualToString: @"}"]) return YES; else if ([_delimiter isEqualToString: @"("]) return NO; else if ([_delimiter isEqualToString: @")"]) return YES; else return NO; } - (void) setDelimiter: (NSString *) de { ASSIGN(_delimiter, de); if ([_delimiter isEqualToString: @"["]) _matcher = @"]"; else if ([_delimiter isEqualToString: @"]"]) _matcher = @"["; else if ([_delimiter isEqualToString: @"{"]) _matcher = @"}"; else if ([_delimiter isEqualToString: @"}"]) _matcher = @"{"; else if ([_delimiter isEqualToString: @"("]) _matcher = @")"; else if ([_delimiter isEqualToString: @")"]) _matcher = @"("; } - (void) setBackward: (BOOL) bool { _backward = bool; if (_backward) _balance = -1; else _balance = +1; } - (void) string: (NSString *) element { [super string: element]; _position += [element length]; _preChar = 0; } - (void) number: (NSString *) element { [super number: element]; _position += [element length]; _preChar = 0; } - (void) spaceAndNewLine: (unichar) element { [super spaceAndNewLine: element]; _position++; _preChar = element; } - (void) symbol: (unichar) element { NSString *eStr; [super symbol: element]; _position++; eStr = [NSString stringWithCharacters: &element length: 1]; _preChar = element; if ( (_commentType == NoComment) && (_stringBegin == NO) ) { if (_backward) { /* backward search */ if ([eStr isEqualToString: _delimiter]) { _balance--; [_backwardArray addObject: _delimiter]; [_positionArray addObject: [NSNumber numberWithUnsignedLongLong: _position]]; if (_balance == -1) { [_backwardArray removeAllObjects]; [_positionArray removeAllObjects]; } } else if ([eStr isEqualToString: _matcher]) { _balance++; [_backwardArray addObject: _matcher]; [_positionArray addObject: [NSNumber numberWithUnsignedLongLong: _position]]; } else return; } else { if (_balance == 0) return; /* forward search */ if ([eStr isEqualToString: _delimiter]) _balance++; else if ([eStr isEqualToString: _matcher]) _balance--; else return; if (_balance == 0) { _result = NSMakeRange(_position, [_matcher length]); } } } } - (void) invisible: (unichar) element { [super invisible: element]; _position ++; _preChar = element; } - (NSRange) result { unsigned long long position; int i; int len = [_delimiter length]; if (_backward) { int count, balance = -1; count = [_backwardArray count]; /* If the last glyph is in comment or string, it means the delimiter is in comment or string. Then it has no matched delimiter */ if ( (_commentType == NoComment) && (_stringBegin == NO) ) { for (i = count-1; i > -1; i--) { if ([_delimiter isEqualToString: [_backwardArray objectAtIndex: i]]) balance--; else { balance++; if (balance == 0) { position = [[_positionArray objectAtIndex: i] unsignedLongLongValue]; _result = NSMakeRange(position-len, len); break; } } } } } /* There is no way to tell whether the delimiter begins in comment or string because CodeHandler only receive string after the delimiter */ return _result; } - (id) init { self = [super init]; [self setBackward: NO]; _result = NSMakeRange(NSNotFound, 0); _backwardArray = [NSMutableArray new]; _positionArray = [NSMutableArray new]; return self; } - (void) dealloc { RELEASE(_backwardArray); RELEASE(_delimiter); RELEASE(_positionArray); [super dealloc]; } @end