//// BXDataModelCompiler.m// BaseTen//// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.//// Before using this software, please review the available licensing options// by visiting http://basetenframework.org/licensing/ or by contacting// us at sales@karppinen.fi. Without an additional license, this software// may be distributed only in compliance with the GNU General Public License.////// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License, version 2.0,// as published by the Free Software Foundation.//// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA//// $Id$//#import "BXDataModelCompiler.h"#import "BXLogger.h"#import "BXEnumerate.h"@implementationBXDataModelCompiler+(NSString*)momcPath{__strongstaticNSString*momcPath=nil;if(!momcPath){NSFileManager*manager=[NSFileManagerdefaultManager];//Paths inside the system developer directory which may lead to momc.NSArray*developerSubpaths=[NSArrayarrayWithObjects:@"/usr/bin/momc",@"/Library/Xcode/Plug-ins/XDCoreDataModel.xdplugin/Contents/Resources/momc",nil];//Try using xcode-select's setting.{intfd=open("/usr/share/xcode-select/xcode_dir_path",O_RDONLY|O_SHLOCK);FILE*file=fdopen(fd,"r");if(file){charbuffer[1024]={};if(fgets(buffer,1024,file)){//Remove the newline character if one exists.size_tlength=strlen(buffer);if('\n'==buffer[length-1])buffer[length-1]='\0';BXEnumerate(currentSubpath,e,[developerSubpathsobjectEnumerator]){NSString*path=[NSStringstringWithFormat:@"%s%@",buffer,currentSubpath];if([managerfileExistsAtPath:path]){momcPath=[pathretain];fclose(file);gotoend;}}}}fclose(file);}//Try using paths from NSSearchPathForDirectoriesInDomains //(which returns always /Developer and not xcode-select's setting).{NSArray*paths=NSSearchPathForDirectoriesInDomains(NSDeveloperDirectory,NSAllDomainsMask,YES);BXEnumerate(currentPath,e,[pathsobjectEnumerator]){BXEnumerate(currentSubpath,e,[developerSubpathsobjectEnumerator]){NSString*path=[currentPathstringByAppendingString:currentSubpath];if([managerfileExistsAtPath:path]){momcPath=[pathretain];gotoend;}}}}//Finally try something rather old.{NSString*path=@"/Library/Application Support/Apple/Developer Tools/Plug-ins/XDCoreDataModel.xdplugin/Contents/Resources/momc";if([managerfileExistsAtPath:path]){momcPath=[pathretain];gotoend;}}}end:returnmomcPath;}-(void)dealloc{[mModelURLrelease];[mCompiledModelURLrelease];[mMomcTaskrelease];[mErrorPiperelease];[superdealloc];}-(void)setDelegate:(id<BXDataModelCompilerDelegate>)anObject{mDelegate=anObject;}-(void)setModelURL:(NSURL*)aFileURL{if(mModelURL!=aFileURL){[mModelURLrelease];mModelURL=[aFileURLretain];}}-(void)setCompiledModelURL:(NSURL*)aFileURL{if(mCompiledModelURL!=aFileURL){[mCompiledModelURLrelease];mCompiledModelURL=[aFileURLretain];}}-(NSURL*)compiledModelURL{returnmCompiledModelURL;}-(void)compileDataModel{NSString*sourcePath=[mModelURLpath];char*pathFormat=NULL;if([sourcePathhasSuffix:@".xcdatamodeld"]){asprintf(&pathFormat,"%s/BaseTen.datamodel.%u.XXXXX",[NSTemporaryDirectory()UTF8String],getpid());if(!pathFormat){BXLogError(@"asprintf returned NULL. errno was %d.",errno);gotobail;}if(!mkdtemp(pathFormat)){BXLogError(@"mkdtemp returned NULL. errno was %d.",errno);gotobail;}}else{asprintf(&pathFormat,"%s/BaseTen.datamodel.%u.XXXXX.mom",[NSTemporaryDirectory()UTF8String],getpid());if(!pathFormat){BXLogError(@"asprintf returned NULL.");gotobail;}if(-1==mkstemps(pathFormat,5)){BXLogError(@"mkstemps returned -1. errno was %d.",errno);gotobail;}}NSString*targetPath=[NSStringstringWithCString:pathFormatencoding:NSUTF8StringEncoding];NSString*momcPath=[[selfclass]momcPath];NSArray*arguments=[NSArrayarrayWithObjects:sourcePath,targetPath,nil];[selfsetCompiledModelURL:[NSURLfileURLWithPath:targetPath]];mErrorPipe=[[NSPipepipe]retain];mMomcTask=[[NSTaskalloc]init];[mMomcTasksetLaunchPath:momcPath];[mMomcTasksetArguments:arguments];[mMomcTasksetStandardError:[mErrorPipefileHandleForWriting]];[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(momcTaskFinished:)name:NSTaskDidTerminateNotificationobject:mMomcTask];[mMomcTasklaunch];bail:if(pathFormat)free(pathFormat);}-(void)momcTaskFinished:(NSNotification*)notification{[mDelegatedataModelCompiler:selffinished:[mMomcTaskterminationStatus]errorOutput:[mErrorPipefileHandleForReading]];[[NSNotificationCenterdefaultCenter]removeObserver:self];[mMomcTaskrelease];mMomcTask=nil;[mErrorPiperelease];mErrorPipe=nil;}@end