home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (C) 1994 Sean Luke
-
- COWSIPCLibrary.m
- Version 10
- Sean Luke
-
- */
-
-
-
-
- #import "COWSIPCLibrary.h"
- #import <stdio.h>
-
- @implementation COWSIPCLibrary
-
-
- - init
- {
- char nm[COWSLARGESTPATHLENGTH];
- id returnval=[super init];
- sprintf (nm,"%s(COWS)",[NXApp appName]);
- connection = [NXConnection registerRoot: self withName:nm];
- [connection runFromAppKit];
- arguments=[[COWSArgumentList alloc] init];
- arguments_state=COWSIPCLIBRARY_ARGSTATE_READY;
- result=[[COWSStringNode alloc] init];
- return returnval;
- }
-
-
- - free
- {
- if (connection!=NULL) [connection free];
- [arguments free];
- [result free];
- [NXConnection removeObject:self];
- return [super free];
- }
-
-
- - loadLibrary:sender
- {
- id returnval=[super loadLibrary:sender];
-
- if (![sender conformsTo:@protocol(LibraryControl)])
- {
- printf ("StandardLibrary error: Interpreter cannot accept Library Control protocol!\n");
- return NULL;
- }
- [sender addLibraryFunction:"send-out"
- selector:@selector(ipc_sendout:)
- target:self];
- [sender addLibraryFunction:"send-out-remote"
- selector:@selector(ipc_sendout_machine:)
- target:self];
- [sender addLibraryFunction:"send"
- selector:@selector(ipc_send:)
- target:self];
- [sender addLibraryFunction:"send-remote"
- selector:@selector(ipc_send_machine:)
- target:self];
- [sender addLibraryFunction:"launch"
- selector:@selector(ipc_launch:)
- target:self];
- [sender addLibraryFunction:"launched?"
- selector:@selector(ipc_launched:)
- target:self];
- interpreter=sender;
- return returnval;
- }
-
-
- - ipc_send:arg_list
- {
- char nm[COWSLARGESTPATHLENGTH];
- id return_val=[[COWSStringNode alloc] init];
- id current;
- id name=[[COWSStringNode alloc] init];
- id function=[[COWSStringNode alloc] init];
- id server;
-
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"send error: nothing to connect to"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [name setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // only one arg
- {
- [return_val setString:"send error: no function to call"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [function setString:[current string]];
- [current free];
- }
- sprintf (nm,"%s(COWS)",[name string]);
- server = [NXConnection connectToName:nm];
- if (server==nil)
- {
- [return_val setString:"send error: cannot establish connection"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
-
- if (![server conformsTo:@protocol(InterpreterIPC)])
- {
- [return_val setString:"send error: remote object is not an interpreter"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
-
- if (![server isForeground])
- {
- [return_val setString:
- "send error: remote interpreter is in background mode"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
-
- while ([arg_list top]!=NULL)
- {
- id current=[arg_list pop];
- [server addArgument:(const char*)[current string]];
- [current free];
- }
-
- [server sendFunction:(const char*) [function string]:return_val];
-
- [function free];
- [name free];
-
- return return_val;
- }
-
-
-
-
- - ipc_send_machine:arg_list
- {
- char nm[COWSLARGESTPATHLENGTH];
- id return_val=[[COWSStringNode alloc] init];
- id current;
- id name=[[COWSStringNode alloc] init];
- id function=[[COWSStringNode alloc] init];
- id machine=[[COWSStringNode alloc] init];
- id server;
-
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"send-remote error: no machine to connect to"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [machine setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"send-remote error: nothing to connect to"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [name setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // only one arg
- {
- [return_val setString:"send-remote error: no function to call"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [function setString:[current string]];
- [current free];
- }
-
- sprintf (nm,"%s(COWS)",[name string]);
- server = [NXConnection connectToName:nm onHost:[machine string]];
- if (server==nil)
- {
- [return_val setString:"send-remote error: cannot establish connection"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
-
- if (![server conformsTo:@protocol(InterpreterIPC)])
- {
- [return_val setString:"send-remote error: remote object is not an interpreter"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
-
- if (![server isForeground])
- {
- [return_val setString:
- "send-remote error: remote interpreter is in background mode"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
-
- while ([arg_list top]!=NULL)
- {
- id current=[arg_list pop];
- [server addArgument:(const char*)[current string]];
- [current free];
- }
-
- [server sendFunction:(const char*) [function string]:return_val];
-
- [name free];
- [machine free];
- [function free];
-
- return return_val;
- }
-
-
-
-
- - ipc_sendout:arg_list // calls a remote function in another
- // interpreter and ignores answer.
-
- {
- char nm[COWSLARGESTPATHLENGTH];
- id return_val=[[COWSStringNode alloc] init];
- id current;
- id name=[[COWSStringNode alloc] init];
- id function=[[COWSStringNode alloc] init];
- id server;
-
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"send-out error: nothing to connect to"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [name setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // only one arg
- {
- [return_val setString:"send-out error: no function to call"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [function setString:[current string]];
- [current free];
- }
- sprintf (nm,"%s(COWS)",[name string]);
- server = [NXConnection connectToName:nm];
- if (server==nil)
- {
- [return_val setString:"send-out error: cannot establish connection"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
-
- if (![server conformsTo:@protocol(InterpreterIPC)])
- {
- [return_val setString:"send-out error: remote object is not an interpreter"];
- [return_val setError:YES];
- [name free];
- [function free];
- return return_val;
- }
-
- while ([arg_list top]!=NULL)
- {
- id current=[arg_list pop];
- [server addArgument:(const char*)[current string]];
- [current free];
- }
-
- [server sendOutFunction:(const char*) [function string]];
- [function free];
- [name free];
-
- return return_val;
- }
-
-
- - ipc_sendout_machine:arg_list
- {
- char nm[COWSLARGESTPATHLENGTH];
- id return_val=[[COWSStringNode alloc] init];
- id current;
- id name=[[COWSStringNode alloc] init];
- id function=[[COWSStringNode alloc] init];
- id machine=[[COWSStringNode alloc] init];
- id server;
-
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"send-out-remote error: no machine to connect to"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [machine setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"send-out-remote error: nothing to connect to"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [name setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // only one arg
- {
- [return_val setString:"send-out-remote error: no function to call"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [function setString:[current string]];
- [current free];
- }
-
- sprintf (nm,"%s(COWS)",[name string]);
- server = [NXConnection connectToName:nm onHost:[machine string]];
- if (server==nil)
- {
- [return_val setString:"send-out-remote error: cannot establish connection"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
-
- if (![server conformsTo:@protocol(InterpreterIPC)])
- {
- [return_val setString:"send-out-remote error: remote object is not an interpreter"];
- [return_val setError:YES];
- [name free];
- [machine free];
- [function free];
- return return_val;
- }
-
- while ([arg_list top]!=NULL)
- {
- id current=[arg_list pop];
- [server addArgument:(const char*)[current string]];
- [current free];
- }
-
- [server sendOutFunction:(const char*) [function string]];
- [name free];
- [machine free];
- [function free];
-
- return return_val;
- }
-
-
-
-
-
- // IPC MESSAGES
-
-
- - finishedInterpreting:(const char*)returnValue:(int)thisMessage:sender
- // this message is sent to the delegate, if it can receive it, after
- // the interpreter has finished interpreting a function request.
- // it is defined here for IPC purposes (an interpreter can be its
- // own delegate in an IPC process.
- {
- [result setString:returnValue];
- [result setError:NO];
- return self;
- }
-
- - errorInterpreting:(int) thisError:(const char*)thisFunction:
- (int)thisPosition:(const char*)thisString:sender
- // this message is sent to the delegate, if it can receive it, after
- // the interpreter has encountered an error while interpreting.
- {
- [result setString:thisString];
- [result setError:YES];
- return self;
- }
-
-
-
-
- - addArgument:(const char*)this_argument
- {
- id new_string;
- printf ("Adding Argument: %s\n",this_argument);
- if (arguments_state==COWSIPCLIBRARY_ARGSTATE_WORKING)
- {
- printf ("COWS IPC Error: trying to begin new function before old one has finished\n");
- return NULL;
- }
-
- new_string=[[COWSStringNode alloc] init];
- [new_string setString:this_argument];
- [arguments push:new_string];
- printf ("Added Argument: %s\n",[new_string string]);
- return NULL;
- }
-
-
-
- - (oneway void) sendOutFunction:(const char*) this_name
- {
- id arg_list=[[COWSArgumentList alloc] init];
-
- if (arguments_state==COWSIPCLIBRARY_ARGSTATE_WORKING)
- {
- printf ("COWS IPC Error: calling new function before old one has finished\n");
- }
- else
- {
- arguments_state=COWSIPCLIBRARY_ARGSTATE_WORKING;
-
- // reverse the argument list
-
- while([arguments top]!=NULL)
- {
- [arg_list push:[arguments pop]];
- }
-
- if (![interpreter locked]&&![interpreter working])
- // i.e., interpreter is able to respond to messages
- {
- // note no delegate is assigned.
- [interpreter setDelegate:NULL];
- [interpreter interpretFunction:this_name arguments:arg_list];
- }
-
- [arguments clear];
- arguments_state=COWSIPCLIBRARY_ARGSTATE_READY;
- }
- [arg_list free];
- }
-
-
-
-
-
- - sendFunction:(const char*) this_name:reply
- {
- id arg_list=[[COWSArgumentList alloc] init];
-
- if (arguments_state==COWSIPCLIBRARY_ARGSTATE_WORKING)
- {
- char junk[COWSLARGESTPATHLENGTH+40];
- sprintf (junk,"remote send error (%s): calling new function before old one has finished.", [NXApp appName]);
- [reply setString:junk];
- [reply setError:YES];
- }
- else
- {
- arguments_state=COWSIPCLIBRARY_ARGSTATE_WORKING;
-
- // clean out response
-
- [result setString:""];
- [result setError:NO];
-
- // reverse the argument list
-
- while([arguments top]!=NULL)
- {
- [arg_list push:[arguments pop]];
- }
-
- if (![interpreter locked]&&![interpreter working])
- {
- [interpreter setDelegate:self];
- [interpreter interpretFunction:this_name arguments:arg_list];
- [reply setString:(const char*)[result string]];
- [reply setError:[result error]];
- }
- else
- {
- char junk[COWSLARGESTPATHLENGTH+40];
- sprintf (junk,"remote send error (%s): interpreter is unavailable.", [NXApp appName]);
- [reply setString: junk];
- [reply setError:YES];
- }
- arguments_state=COWSIPCLIBRARY_ARGSTATE_READY;
- }
- [arg_list free];
- return NULL;
- }
-
-
- - (BOOL) isForeground
- {
- if (interpreter==NULL)
- {
- printf ("Yikes! No Interpreter\n");
- return NO;
- }
- return [interpreter foreground];
- }
-
- - pauseCancelled:sender
- {
- return NULL;
- }
-
- - pauseInterpreter:remote_process
- {
- [interpreter pauseInterpreting:remote_process];
- return NULL;
- }
-
-
-
- - ipc_launch:arg_list
- {
- id return_val=[[COWSStringNode alloc] init];
- id current;
- id name=[[COWSStringNode alloc] init];
- id machine=[[COWSStringNode alloc] init];
- port_t response;
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"launch error: nothing to launch"];
- [return_val setError:YES];
- [name free];
- [machine free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [name setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // only one arg
- {
- char host[MAXHOSTNAMELEN];
- gethostname(host,MAXHOSTNAMELEN);
- [machine setString:(const char*) host];
- }
- else
- {
- current=[arg_list pop];
- [machine setString:[current string]];
- [current free];
- }
-
- response=NXPortFromName([name string],[machine string]);
-
- if (response==PORT_NULL)
- {
- [return_val setString:"f"];
- [name free];
- [machine free];
- return return_val;
- }
-
- [return_val setString:"t"];
- [name free];
- [machine free];
-
- return return_val;
- }
-
-
-
- - ipc_launched:arg_list
- {
- id return_val=[[COWSStringNode alloc] init];
- id current;
- id name=[[COWSStringNode alloc] init];
- id machine=[[COWSStringNode alloc] init];
- port_t response;
-
- if ([arg_list top]==NULL) // no args
- {
- [return_val setString:"launched? error: nothing to check for"];
- [return_val setError:YES];
- [name free];
- [machine free];
- return return_val;
- }
- else
- {
- current=[arg_list pop];
- [name setString:[current string]];
- [current free];
- }
-
- if ([arg_list top]==NULL) // only one arg
- {
- char host[MAXHOSTNAMELEN];
- gethostname(host,MAXHOSTNAMELEN);
- [machine setString:(const char*) host];
- }
- else
- {
- current=[arg_list pop];
- [machine setString:[current string]];
- [current free];
- }
-
- response=NXPortNameLookup([name string],[machine string]);
-
- if (response==PORT_NULL)
- {
- [return_val setString:"f"];
- [name free];
- [machine free];
- return return_val;
- }
-
- [return_val setString:"t"];
-
- [name free];
- [machine free];
- return return_val;
- }
-
-
- @end
-