ceptr
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
shell.c
Go to the documentation of this file.
1 
11 #include "shell.h"
12 #include "semtrex.h"
13 #include "protocol.h"
14 
15 
16 void addCommand(Receptor *r,ReceptorAddress ox,char *command,char *desc,T *code,T *bindings_handler) {
17  T *expect = _t_new_root(PATTERN);
18  T *s = _t_news(expect,SEMTREX_GROUP,SHELL_COMMAND);
19 
20  T *cm = _sl(s,SHELL_COMMAND);
21  T *vl = _t_newr(cm,SEMTREX_VALUE_LITERAL);
22  T *vls = _t_newr(vl,SEMTREX_VALUE_SET);
23  _t_new_str(vls,VERB,command);
24 
25  T *p = _t_new_root(SAY);
26  __r_make_addr(p,TO_ADDRESS,ox);
27 
28  _t_news(p,ASPECT_IDENT,DEFAULT_ASPECT);
29  _t_news(p,CARRIER,NULL_SYMBOL);
30 
31  // if code is actually an INITIATE then we will have a bindings handler
32  // to which we want to add the SAY command as the ACTUAL_PROCESS
33  // and we will replace the p with code which does the proper protocol
34  // initiation. Kinda weird, I know...
35  if (bindings_handler) {
36  char proc_name[255] = "handle ";
37  strcpy(&proc_name[7],command);
38  int pt1[] = {2,1,TREE_PATH_TERMINATOR};
39  _t_new(p,PARAM_REF,pt1,sizeof(int)*3);
40  Process proc = _r_define_process(r,p,proc_name,"long desc...",NULL,NULL);
41  _t_news(bindings_handler,ACTUAL_PROCESS,proc);
42  p = code;
43  }
44  else {
45  _t_add(p,code);
46  }
47 
48  Process proc = _r_define_process(r,p,desc,"long desc...",NULL,NULL);
49  T *act = _t_newp(0,ACTION,proc);
50 
51  _r_add_expectation(r,DEFAULT_ASPECT,SHELL_COMMAND,expect,act,0,0,NULL,NULL);
52 }
53 
54 void makeShell(VMHost *v,FILE *input, FILE *output,Receptor **irp,Receptor **orp,Stream **isp,Stream **osp) {
55  // define and then create the shell receptor
56  Symbol shell = _d_define_receptor(v->r->sem,"shell",__r_make_definitions(),DEV_COMPOSITORY_CONTEXT);
57  Receptor *r = _r_new(v->sem,shell);
58  Xaddr shellx = _v_new_receptor(v,v->r,shell,r);
59  _v_activate(v,shellx);
60 
61  // create stdin/out receptors
62 
63  Stream *output_stream = *osp = _st_new_unix_stream(output,0);
64  Stream *input_stream = *isp = _st_new_unix_stream(input,1);
65 
66  Receptor *i_r = *irp = _r_makeStreamEdgeReceptor(v->sem);
67  _r_addReader(i_r,input_stream,r->addr,DEFAULT_ASPECT,parse_line,LINE,false);
68  Xaddr ix = _v_new_receptor(v,v->r,STREAM_EDGE,i_r);
69  _v_activate(v,ix);
70 
71  Receptor *o_r = *orp = _r_makeStreamEdgeReceptor(v->sem);
72  _r_addWriter(o_r,output_stream,DEFAULT_ASPECT);
73  Xaddr ox = _v_new_receptor(v,v->r,STREAM_EDGE,o_r);
74  _v_activate(v,ox);
75 
76  // set up shell to express the line parsing protocol when it receives LINES from the stream reader
77  Protocol clp;
78  __sem_get_by_label(v->sem,"PARSE_COMMAND_FROM_LINE",&clp,DEV_COMPOSITORY_CONTEXT);
79  T *bindings = _t_new_root(PROTOCOL_BINDINGS);
80  T *res = _t_newr(bindings,RESOLUTION);
81  T *w = _t_newr(res,WHICH_RECEPTOR);
82  _t_news(w,ROLE,LINE_SENDER);
83  __r_make_addr(w,ACTUAL_RECEPTOR,i_r->addr);
84  res = _t_newr(bindings,RESOLUTION);
85  w = _t_newr(res,WHICH_RECEPTOR);
86  _t_news(w,ROLE,COMMAND_RECEIVER);
87  __r_make_addr(w,ACTUAL_RECEPTOR,r->addr);
88  res = _t_newr(bindings,RESOLUTION);
89  w = _t_newr(res,WHICH_SYMBOL);
90  _t_news(w,USAGE,COMMAND_TYPE);
91  _t_news(w,ACTUAL_SYMBOL,SHELL_COMMAND);
92 
93  _o_express_role(r,clp,COMMAND_RECEIVER,DEFAULT_ASPECT,bindings);
94  _t_free(bindings);
95 
96  // set up shell to use the CLOCK TELL_TIME protocol for the time command
97  Protocol time;
98  __sem_get_by_label(v->sem,"time",&time,CLOCK_CONTEXT);
99  T *code = _t_new_root(INITIATE_PROTOCOL);
100  _t_news(code,PNAME,time);
101  _t_news(code,WHICH_INTERACTION,tell_time);
102  bindings = _t_newr(code,PROTOCOL_BINDINGS);
103  res = _t_newr(bindings,RESOLUTION);
104  w = _t_newr(res,WHICH_RECEPTOR);
105  _t_news(w,ROLE,TIME_HEARER);
106  __r_make_addr(w,ACTUAL_RECEPTOR,r->addr);
107  res = _t_newr(bindings,RESOLUTION);
108  w = _t_newr(res,WHICH_RECEPTOR);
109  _t_news(w,ROLE,TIME_TELLER);
110  ReceptorAddress clock_addr = {3}; // @todo bogus!!! fix getting clock address somehow
111  __r_make_addr(w,ACTUAL_RECEPTOR,clock_addr);
112  res = _t_newr(bindings,RESOLUTION);
113  w = _t_newr(res,WHICH_PROCESS);
114  _t_news(w,GOAL,RESPONSE_HANDLER);
115 
116  addCommand(r,o_r->addr,"time","get time",code,w);
117 
118  // (expect (on flux SHELL_COMMAND:receptor) action (send std_out (convert_to_lines (send vmhost receptor-list))))
119 
120  code = _t_newi(0,MAGIC,MagicReceptors);
121  addCommand(r,o_r->addr,"receptors","get receptor list",code,NULL);
122 
123  // (expect (on flux SHELL_COMMAND:receptor) action (send std_out (convert_to_lines (send vmhost shutdown)))
124  code = _t_newi(0,MAGIC,MagicQuit);
125  addCommand(r,o_r->addr,"quit","shut down the vmhost",code,NULL);
126 
127  // (expect (on flux SHELL_COMMAND:debug) action (send std_out (convert_to_lines (magic toggle debug)))
128  code = _t_newi(0,MAGIC,MagicDebug);
129  addCommand(r,o_r->addr,"debug","toggle debug mode",code,NULL);
130 
131 }
132 
T * _t_new_root(Symbol symbol)
Definition: tree.c:160
Definition: ceptr_types.h:114
Definition: stream.h:30
command line shell receptor header files
Semantic tree regular expression header file.
SemanticID _d_define_receptor(SemTable *sem, char *label, T *definitions, Context c)
Definition: def.c:457
protocol helpers header file
T * _t_newp(T *parent, Symbol symbol, Process surface)
Definition: tree.c:251
ReceptorAddress addr
the address by which to get messages to this receptor instance
Definition: ceptr_types.h:241
void _r_add_expectation(Receptor *r, Aspect aspect, Symbol carrier, T *pattern, T *action, T *with, T *until, T *using, T *cid)
Adds an expectation to a receptor's aspect.
Definition: receptor.c:164
void _v_activate(VMHost *v, Xaddr x)
Definition: vmhost.c:172
Receptor * _r_new(SemTable *sem, SemanticID r)
Creates a new receptor.
Definition: receptor.c:88
SemTable * sem
Semantic Table for definitions on this host.
Definition: vmhost.h:44
Definition: vmhost.h:40
SemTable * sem
pointer back to the genotype table for this receptor's vmhost instance
Definition: ceptr_types.h:242
void _o_express_role(Receptor *r, Protocol protocol, Symbol role, Aspect aspect, T *bindings)
Definition: protocol.c:409
Receptor * r
Receptor data for this vm host.
Definition: vmhost.h:43
#define _sl(t, s)
macro to add a single symbol literal to semtrex tree
Definition: semtrex.h:122
void _t_add(T *t, T *c)
Definition: tree.c:261
Process _r_define_process(Receptor *r, T *code, char *name, char *intention, T *signature, T *link)
Definition: receptor.c:275
void _t_free(T *t)
Definition: tree.c:526