/* ** ObjCHandler.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 "ObjCHandler.h" #include #include @implementation ObjCHandler + (NSString *) language { return @"Objective-C"; } + (Class) blockHandlerClass { return NSClassFromString(@"ObjCBlockHandler"); } + (Class) indentationHandlerClass { return NSClassFromString(@"ObjCIndentHandler"); } + (Class) methodHandlerClass { return NSClassFromString(@"ObjCMethodHandler"); } #define STRCMP(str) (!strcmp(cstr, str)) - (void) string: (NSString *) element { const char *cstr = [element cString]; unsigned int len = [element length]; NSRange attributeRange = NSMakeRange(position, len); BOOL changeAttribute = NO; NSDictionary *attr = normalAttr; [super string: element]; /* Comments */ if (_commentType != NoComment) { changeAttribute = YES; attr = commentsAttr; } else if (_stringBegin == YES) { changeAttribute = YES; attr = stringsAttr; } else if ( (*cstr > 0x40) && (*cstr < 0x58) ) /* Capital */ { /* KnownType */ if ( STRCMP("SEL") || STRCMP("BOOL") || STRCMP("Class") || STRCMP("Nil") || STRCMP("IBAction") || STRCMP("IBOutlet") ) { changeAttribute = YES; attr = knowntypesAttr; } /* Strings */ else if ( STRCMP("FALSE") || STRCMP("NO") || STRCMP("TRUE") || STRCMP("YES") ) { changeAttribute = YES; attr = stringsAttr; } else if ( (*cstr == 'N') && (*(cstr+1) == 'S') ) { changeAttribute = YES; attr = knowntypesAttr; } } else if (len < 10) { /* Preprocessor */ if (_preChar == '#') { if ( STRCMP("import") || STRCMP("include") || STRCMP("ifdef") || STRCMP("ifndef") || /*STRCMP("if defined") ||*/ STRCMP("else") || STRCMP("endif") || STRCMP("pragma") || STRCMP("define") || STRCMP("warning") || STRCMP("error") ) { attributeRange = NSMakeRange(position-1, len+1); changeAttribute = YES; attr = preprocessorAttr; } } else if (_preChar == '@') { if ( STRCMP("class") || STRCMP("selector") || STRCMP("interface") || STRCMP("end") || STRCMP("encode") || STRCMP("private") || STRCMP("protected") ) { changeAttribute = YES; attr = keywordsAttr; } } /* Keyword */ else if ( STRCMP("break") || STRCMP("extern") || STRCMP("continue") || STRCMP("_cmd") || STRCMP("self") || STRCMP("super") || STRCMP("return") || STRCMP("sizeof") || STRCMP("break") || STRCMP("case") || STRCMP("default") || STRCMP("goto") || STRCMP("switch") || STRCMP("if") || STRCMP("else") || STRCMP("do") || STRCMP("shile") || STRCMP("for") || STRCMP("while") ) { changeAttribute = YES; attr = keywordsAttr; } /* KnownType */ else if ( STRCMP("int") || STRCMP("long") || STRCMP("short") || STRCMP("char") || STRCMP("float") || STRCMP("double") || STRCMP("void") || STRCMP("union") || STRCMP("unichar") || STRCMP("const") || STRCMP("signed") || STRCMP("unsigned") || STRCMP("static") || STRCMP("volatile") || STRCMP("enum") || STRCMP("id") ) { changeAttribute = YES; attr = knowntypesAttr; } /* Strings */ else if ( STRCMP("nil") ) { changeAttribute = YES; attr = stringsAttr; } } else if ((len == 14) && (_preChar == '@')) { if ( STRCMP("implementation") ) { changeAttribute = YES; attr = keywordsAttr; } } position += len; _preChar = 0; if (changeAttribute) { attributeRange.location += _startRange.location; #if 1 [_origin addAttributes: attr range: attributeRange]; #else [_origin setAttributes: attr range: attributeRange]; #endif } } - (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 { NSRange attributeRange; NSDictionary *attr; [super symbol: element]; if ( ((_preChar == '/') && ((element == '*') || (element == '/'))) || ((_preChar == '*') && (element == '/')) ) { attr = commentsAttr; attributeRange = NSMakeRange(position-1, 2); attributeRange.location += _startRange.location; [_origin addAttributes: attr range: attributeRange]; } else { if (_commentType != NoComment) { attr = commentsAttr; attributeRange = NSMakeRange(position, 1); attributeRange.location += _startRange.location; [_origin addAttributes: attr range: attributeRange]; } } position++; _preChar = element; } - (void) invisible: (unichar) element { [super invisible: element]; position ++; _preChar = element; } - (void) setString: (NSMutableAttributedString *) string { ASSIGN(_origin, string); _startRange = NSMakeRange(0, [_origin length]); } - (void) setRange: (NSRange) range { _startRange = range; } - (id) init { NSFont *preprocessorFont, *keywordsFont, *commentsFont; NSFont *stringsFont, *knowntypesFont, *normalFont; NSColor *preprocessorColor, *keywordsColor, *commentsColor; NSColor *stringsColor, *knowntypesColor, *normalColor; self = [super init]; _rulesetManager = [RulesetManager sharedRulesetManager]; _startRange = NSMakeRange(0, 0); position = 0; /* cache */ preprocessorColor = [_rulesetManager colorForType: @"Preprocessor"]; keywordsColor = [_rulesetManager colorForType: @"Keywords"]; commentsColor = [_rulesetManager colorForType: @"Comments"]; stringsColor = [_rulesetManager colorForType: @"Strings"]; knowntypesColor = [_rulesetManager colorForType: @"KnownTypes"]; normalColor = [_rulesetManager colorForType: @"Normal"]; normalFont = [_rulesetManager normalFont]; preprocessorFont = [_rulesetManager fontForType: @"Preprocessor"]; keywordsFont = [_rulesetManager fontForType: @"Keywords"]; commentsFont = [_rulesetManager fontForType: @"Comments"]; stringsFont = [_rulesetManager fontForType: @"Strings"]; knowntypesFont = [_rulesetManager fontForType: @"KnownTypes"]; #define MAKE_ATTRIBUTES(color, font) \ [[NSDictionary alloc] initWithObjectsAndKeys: \ color, NSForegroundColorAttributeName, \ font, NSFontAttributeName, nil]; normalAttr = MAKE_ATTRIBUTES(normalColor, normalFont); preprocessorAttr = MAKE_ATTRIBUTES(preprocessorColor, preprocessorFont); keywordsAttr = MAKE_ATTRIBUTES(keywordsColor, keywordsFont); commentsAttr = MAKE_ATTRIBUTES(commentsColor, commentsFont); stringsAttr = MAKE_ATTRIBUTES(stringsColor, stringsFont); knowntypesAttr = MAKE_ATTRIBUTES(knowntypesColor, knowntypesFont); return self; } - (void) dealloc { RELEASE(_origin); RELEASE(preprocessorAttr); RELEASE(keywordsAttr); RELEASE(commentsAttr); RELEASE(stringsAttr); RELEASE(knowntypesAttr); RELEASE(normalAttr); [super dealloc]; } @end