home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / DevTools / ClassBuilder / Source / ClassManager.m < prev    next >
Encoding:
Text File  |  1993-01-25  |  5.7 KB  |  200 lines

  1. /* Generated by Interface Builder */
  2.  
  3. #import "ClassManager.h"
  4. #import "MenuManager.h"
  5. #import <appkit/Application.h>
  6. #import <appkit/Text.h>
  7. #import <appkit/Panel.h>
  8. #import <appkit/NXBrowser.h>
  9. #import <objc/objc-load.h>
  10. #import <objc/Storage.h>
  11. #import <libc.h>
  12. #import <strings.h>
  13.  
  14.  
  15. id loadList ; // this global var points to a "Storage" list of
  16.                 // 2-element malloced arrays of chars, where element
  17.         // 0 contains the classname and element 1 contains
  18.         // the pathname of every loaded class
  19.  
  20. struct loadClass
  21. { char *className ;
  22.   char *dotOFileName ;
  23. } ;
  24.  
  25. @implementation ClassManager: WindowManager
  26.  
  27. + initialize ;
  28. // initialize the loadList
  29. { loadList = [[Storage new] initCount:0
  30.                  elementSize: sizeof(struct loadClass)
  31.                  description:"{**}"] ;
  32.   return [super initialize] ;
  33. }
  34.  
  35. +(int) loadIndex: (char *) nameOfClass ;
  36. // if nameOfClass is in the load list, return its index,
  37. // else return -1
  38. { int i, knt ;
  39.   struct loadClass *lc ;
  40.   knt = [loadList count] ;
  41.   for(i = 0 ; i < knt ; i++)
  42.   { lc = (struct loadClass *) [loadList elementAt: i] ;
  43.     if(!strcmp(lc->className, nameOfClass))
  44.       return i ;
  45.   }
  46.   return -1 ;
  47. }
  48.  
  49. + loadList ;
  50. { return loadList ;
  51. }
  52.  
  53. + unload: (const char *) aClass;
  54. // unload the class with name aClass
  55. { char *moduleNames[2], *textBuf ;
  56.   int i, loadNumber, loadKnt, textLen, maxLen ;
  57.   struct loadClass *lcPtr ;    
  58.   NXStream *aStream ;
  59.  
  60.   aStream = NXOpenMemory(NULL, 0, NX_READWRITE) ;
  61.   loadKnt = [loadList count] ;
  62.   moduleNames[1] = NULL ;
  63.   loadNumber = [ClassManager loadIndex: (char *) aClass] ;
  64.   if(loadNumber != -1) // module is loaded...
  65.   { for(i = loadKnt ; i > loadNumber ; i--)
  66.       objc_unloadModules(aStream, NULL) ; // unload all classes
  67.     lcPtr = [loadList elementAt: i] ;
  68.     free(lcPtr->className) ;
  69.     free(lcPtr->dotOFileName) ;
  70.     [loadList removeAt: i] ; // remove this class from loadList
  71.     loadKnt-- ;
  72.     for( ; i < loadKnt ; i++) // reload unloaded classes
  73.     { lcPtr = (struct loadClass *) [loadList elementAt: i] ;
  74.       moduleNames[0] = lcPtr->dotOFileName ;
  75.       objc_loadModules(moduleNames, aStream, NULL, NULL, NULL) ;
  76.     }
  77.   }
  78.   NXGetMemoryBuffer(aStream, &textBuf, &textLen, &maxLen);
  79.   [NXApp printf: textBuf];
  80.   NXCloseMemory(aStream,NX_TRUNCATEBUFFER) ;
  81.   [[NXApp loadedClassesBrowser] loadColumnZero] ;
  82.   return self ;
  83. }
  84.  
  85. + unloadAll ;
  86. // unload all incrementally loaded classes
  87. { char *textBuf ;
  88.   NXStream *aStream ;
  89.   int i, loadKnt, textLen, maxLen ;
  90.   struct loadClass *lcPtr ;    
  91.   loadKnt = [loadList count] ;
  92.   aStream = NXOpenMemory(NULL, 0, NX_READWRITE) ;
  93.   for(i = 0 ; i < loadKnt ; i++)
  94.   { objc_unloadModules(aStream, NULL) ;
  95.     lcPtr = [loadList elementAt: 0] ;
  96.     free(lcPtr->className) ;
  97.     free(lcPtr->dotOFileName) ;
  98.     [loadList removeAt: 0] ;
  99.   }
  100.   NXGetMemoryBuffer(aStream, &textBuf, &textLen, &maxLen);
  101.   [NXApp printf: textBuf];
  102.   NXCloseMemory(aStream,NX_TRUNCATEBUFFER) ;
  103.   [[NXApp loadedClassesBrowser] loadColumnZero] ;
  104.   [[NXApp loadedClassesBrowser] loadColumnZero] ;
  105.   return self ;  
  106. }
  107.  
  108.  
  109. - className: (char *) name ;
  110. { // copy className into ivar
  111.   strncpy(className, name, 63) ;
  112.   return self ;
  113. }
  114.  
  115.  
  116. - classText: (char *) theText ;
  117. { // copy theText into text object
  118.   [textView setText: theText] ;
  119.   [self setDocEdited:YES];
  120.   return self ;
  121. }
  122.  
  123. - compile:sender
  124. { char buf[512] ;
  125.   char tmpFile[20] = "CBXXXXXX" ;
  126.   if([self isDocEdited]) // be sure file is saved first
  127.     [self save: self] ;
  128.   // use awk to create .h file.  We should probably refine
  129.   // this script.  it can't deal with @implementation a:b, there
  130.   // must be a blank after the colon, thus a: b
  131.   mktemp(tmpFile) ;
  132.   [self message: "Creating .h file..."] ;
  133.   sprintf(buf,
  134. "awk '\\\n\
  135. /#pragma .h/      { $1 = \"\";$2=\"\"; print}\\\n\
  136. /@implementation/ { $1 = \"@interface\"; print ;state++ }\\\n\
  137. /^{/               { if(state == 1) state++ }\\\n\
  138.                   { if(state == 2) print }\\\n\
  139. /^}/               { if(state == 2) state++ }\\\n\
  140. /^[+-]/           { if(state == 3) print }\\\n\
  141. END               { print \"@end\"}'\\\n\
  142. < %s.m > %s.h",className, className, className ) ;
  143.   system(buf) ;
  144.   // compile into .o file
  145.   sprintf(buf, "cc -c -I /usr/include/objc -Wall -o %s.o %s.m"
  146.      "  2> /tmp/%s", className, className, tmpFile) ;
  147.   [self message: "Compiling..."] ;
  148.   if(system(buf)) // non-zero exit status == errors
  149.   { sprintf(buf,"/tmp/%s",tmpFile) ;
  150.     [NXApp appendFileToTranscript: buf] ;
  151.     NXRunAlertPanel("CB","Compilation errors: see Transcript Window\n",
  152.          NULL,NULL,NULL) ;
  153.     sprintf(buf,"rm /tmp/%s.m /tmp/%s.o /tmp/%s 2> /dev/null",
  154.          tmpFile,tmpFile,tmpFile) ;
  155.     system(buf) ;
  156.   } 
  157.   [self message: ""] ;
  158.   return self ;
  159. }
  160.  
  161. - (char *) extension ;
  162. { // provide file extension
  163.   return "m" ;
  164. }
  165.  
  166.  
  167. - load:sender ;
  168. { char *moduleNames[2] ;
  169.   struct loadClass lc ;
  170.     
  171.   NXStream *aStream ;
  172.   aStream = NXOpenMemory(NULL, 0, NX_READWRITE) ;
  173.   moduleNames[1] = NULL ;
  174.   
  175.   // if class is already loaded, we'll have to unload
  176.   // all classes loaded after it, then reload all unloaded
  177.   // classes except it.
  178.   [self message: "Loading..."] ;
  179.   [ClassManager unload: className] ;
  180.   // load current module. Note that we have moved the module
  181.   // to the end of the loadlist, so subsequent reloads of
  182.   // it are quicker.
  183.   lc.className = malloc(strlen(className) + 1) ;
  184.   strcpy(lc.className,className) ;
  185.   lc.dotOFileName = malloc(strlen(fileName) + 1) ;
  186.   strcpy(lc.dotOFileName,fileName) ;
  187.   lc.dotOFileName[strlen(lc.dotOFileName) -1] = 'o' ;
  188.   moduleNames[0] = lc.dotOFileName ;
  189.   objc_loadModules(moduleNames, aStream, NULL, NULL, NULL) ;
  190.   [loadList addElement: (void *) &lc] ;
  191.   NXSeek(aStream, 0L, NX_FROMSTART) ;
  192.   NXCloseMemory(aStream,NX_TRUNCATEBUFFER) ;
  193.   [[NXApp loadedClassesBrowser] loadColumnZero] ;
  194.   [self message: ""] ;
  195.   return self ;
  196. }
  197.  
  198.  
  199. @end
  200.