apps-gorm/GormObjCHeaderParser/OCClass.m

244 lines
6.5 KiB
Objective-C

/* OCClass.m
*
* Copyright (C) 1999 Free Software Foundation, Inc.
*
* Author: Gregory John Casamento <greg_casamento@yahoo.com>
* Date: 1999, 2002
*
* This file is part of GNUstep.
*
* 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <Foundation/Foundation.h>
#include <GormObjCHeaderParser/OCClass.h>
#include <GormObjCHeaderParser/OCMethod.h>
#include <GormObjCHeaderParser/OCIVar.h>
#include <GormObjCHeaderParser/OCIVarDecl.h>
#include <GormObjCHeaderParser/NSScanner+OCHeaderParser.h>
#include <GormObjCHeaderParser/ParserFunctions.h>
@implementation OCClass
- (id) initWithString: (NSString *)string
{
if((self = [super init]) != nil)
{
methods = [[NSMutableArray alloc] init];
ivars = [[NSMutableArray alloc] init];
ASSIGN(classString, string);
}
return self;
}
- (void) dealloc
{
RELEASE(methods);
RELEASE(ivars);
RELEASE(classString);
RELEASE(className);
RELEASE(superClassName);
[super dealloc];
}
- (NSArray *) methods
{
return methods;
}
- (void) addMethod: (NSString *)name isAction: (BOOL) flag
{
OCMethod *method = AUTORELEASE([[OCMethod alloc] init]);
[method setName: name];
[method setIsAction: flag];
[methods addObject: method];
}
- (NSArray *) ivars
{
return ivars;
}
- (void) addIVar: (NSString *)name isOutlet: (BOOL) flag
{
OCIVar *ivar = AUTORELEASE([[OCIVar alloc] init]);
[ivar setName: name];
[ivar setIsOutlet: flag];
[ivars addObject: ivar];
}
- (NSString *) className
{
return className;
}
- (void) setClassName: (NSString *)name
{
ASSIGN(className, name);
}
- (NSString *) superClassName
{
return superClassName;
}
- (void) setSuperClassName: (NSString *)name
{
ASSIGN(superClassName,name);
}
- (BOOL) isCategory
{
return isCategory;
}
- (void) setIsCategory: (BOOL)flag
{
isCategory = flag;
}
- (void) _strip
{
NSScanner *stripScanner = [NSScanner scannerWithString: classString];
NSString *resultString = @"";
NSCharacterSet *wsnl = [NSCharacterSet whitespaceAndNewlineCharacterSet];
while(![stripScanner isAtEnd])
{
NSString *string = nil;
[stripScanner scanUpToCharactersFromSet: wsnl intoString: &string];
resultString = [resultString stringByAppendingString: string];
if(![stripScanner isAtEnd])
{
resultString = [resultString stringByAppendingString: @" "];
}
}
ASSIGN(classString, resultString);
}
- (void) parse
{
NSScanner *scanner = nil;
NSScanner *iscan = nil;
NSString *interfaceLine = nil;
NSString *methodsString = nil;
NSString *ivarsString = nil;
NSCharacterSet *wsnl = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSCharacterSet *pmcs = [NSCharacterSet characterSetWithCharactersInString: @"+-"];
// get the interface line... look ahead...
[self _strip];
scanner = [NSScanner scannerWithString: classString];
if(lookAhead(classString, @"{"))
{
[scanner scanUpToString: @"@interface" intoString: NULL];
[scanner scanUpToString: @"{" intoString: &interfaceLine];
iscan = [NSScanner scannerWithString: interfaceLine]; // reset scanner...
}
else // if there is no "{", then there are no ivars...
{
[scanner scanUpToString: @"@interface" intoString: NULL];
[scanner scanUpToCharactersFromSet: pmcs intoString: &interfaceLine];
iscan = [NSScanner scannerWithString: interfaceLine]; // reset scanner...
}
// look ahead...
if(lookAhead(interfaceLine, @":"))
{
NSString *cn = nil, *scn = nil;
[iscan scanUpToAndIncludingString: @"@interface" intoString: NULL];
[iscan scanUpToString: @":" intoString: &cn];
className = [cn stringByTrimmingCharactersInSet: wsnl];
RETAIN(className);
[iscan scanString: @":" intoString: NULL];
[iscan scanUpToCharactersFromSet: wsnl intoString: &scn];
superClassName = [scn stringByTrimmingCharactersInSet: wsnl];
RETAIN(superClassName);
}
else // category...
{
NSString *cn = nil;
[iscan scanUpToAndIncludingString: @"@interface" intoString: NULL];
[iscan scanUpToCharactersFromSet: wsnl intoString: &cn];
className = [cn stringByTrimmingCharactersInSet: wsnl];
RETAIN(className);
// check to see if it's a category on an existing interface...
if(lookAhead(interfaceLine,@"("))
{
isCategory = YES;
}
}
if(isCategory == NO)
{
NSScanner *ivarScan = nil;
// put the ivars into a a string...
[scanner scanUpToAndIncludingString: @"{" intoString: NULL];
[scanner scanUpToString: @"}" intoString: &ivarsString];
[scanner scanString: @"}" intoString: NULL];
if(ivarsString != nil)
{
// scan each ivar...
ivarScan = [NSScanner scannerWithString: ivarsString];
while(![ivarScan isAtEnd])
{
NSString *ivarLine = nil;
OCIVarDecl *ivarDecl = nil;
[ivarScan scanUpToString: @";" intoString: &ivarLine];
[ivarScan scanString: @";" intoString: NULL];
ivarDecl = AUTORELEASE([[OCIVarDecl alloc] initWithString: ivarLine]);
[ivarDecl parse];
[ivars addObjectsFromArray: [ivarDecl ivars]];
}
}
}
// put the methods into a string...
if(ivarsString != nil)
{
[scanner scanUpToString: @"@end" intoString: &methodsString];
}
else //
{
scanner = [NSScanner scannerWithString: classString];
[scanner scanUpToAndIncludingString: interfaceLine intoString: NULL];
[scanner scanUpToString: @"@end" intoString: &methodsString];
}
// scan each method...
if(methodsString != nil)
{
NSScanner *methodScan = [NSScanner scannerWithString: methodsString];
while(![methodScan isAtEnd])
{
NSString *methodLine = nil;
OCMethod *method = nil;
[methodScan scanUpToString: @";" intoString: &methodLine];
[methodScan scanString: @";" intoString: NULL];
method = AUTORELEASE([[OCMethod alloc] initWithString: methodLine]);
[method parse];
[methods addObject: method];
}
}
}
@end