The DejaVU Framework -- hush 3.0
[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?

source: handler.c hush-3.1/hush/api


[.] - [up] [top] - index README text make include source configure graphs slides talks
  include <hush/source.h>
  
  include <hush/handler.h>
  include <hush/dictionary.h>
  include <hush/string.h>
  
  ifndef CIAO
  include <hush/vm.h>
  endif
  
  include <hush/sys/io.h>
  
  include <hush/kit.h>
  include <hush/event.h>
  include <hush/sys/types.h>
  
  include <hush/session.h>
  include <hush/assert.h>
  
  include <hush/sys/cell.h>
  include <hush/sys/port.h>
  
  include <string.h>
  include <stdio.h>
  
  include "hush/sys/garbage.i"
  include "hush/sys/light.h"
  
  define TYPE handler
  include "hush/sys/table.i"
  
  static void checkflush(ostream& os, const char* s) {
          //if (s[0]=='\n') os.flush();
          }
  
  include <hush/api/io.h>
  
  static void printerr(const char* s) { cerr << s; checkflush(cerr,s); }
  static void printout(const char* s) { cout << s; checkflush(cerr,s); }
  
  int handler::initialized = 0;
  
  int handler::initialize() {
          IO::initialize();
          obscure::initialize();
          if (!handler::initialized) {
                  handler::_err = 0; //  &cerr;
                  handler::_out = 0; // &cout;
                  handler::_in = 0; // &cin;
                  }
                  IO* x = handler::_err = new IO;
          x->_print = printerr;
          session::_default->_register(x);
          x = handler::_out = new IO;
          x->_print = printout;
          session::_default->_register(x);
          return handler::initialized = 1;
          }
  
  IO* handler::_out = 0;
  IO* handler::_err = 0;
  IO* handler::_in  = 0;
  
  struct handler_state {
          handler_state(handler* x = 0) {
                  refs = 1;
                  _etc = 0; _mode = 0; _garb = 0; 
                  _bdy = 0; _ctx = x; _slf = 0; // _bdy is global!
                  i_options = 0; resources = 0;
                  s_options = 0;
                  }
          
          ~handler_state() {
                  if (_garb) delete _garb;
                  if (_etc) delete _etc;
                  }
  
          int refs;
          int _mode;
          cell* _etc;
          hush_garbage* _garb;
  
          handler* _bdy;  // for a unified body
          handler* _ctx;  // the context
          handler* _slf;  // for inner components
  
          dictionary<dvstring>* s_options;
          dictionary<int>* i_options;
          dictionary<void>* resources; 
  };
  
  define STATE ((handler_state*)_state)
  define THIS(X) ((handler_state*)((handler*) this)->_state)->X
  
  define NAME (_name)
  define MODE (STATE->_mode)
  define GARB (STATE->_garb)
  define LGARB ((light_garbage*)((handler*)this)->_garb)
  define ETC  (STATE->_etc)
  
  define REGISTER(X) \
          if (!_state) ((handler*)this)->_state = (void*) new handler_state; \
          if (!GARB)  GARB = new hush_garbage; \
          GARB->_register(X)
  
  ifndef CIAO
  define LREGISTER(X) \
          if (!LGARB)  LGARB = new light_garbage; \
          LGARB->_register(X)
  else
  define LREGISTER(X)
  endif
          
  define VAL  ((handler*) ETC ->el )
  
  int handler::_no = 0;
  
  IO& handler::out(const char* opts) const {
          opts = opts;
          if (!_out) _out = IO::_default;
          return *_out;
          }
  
  IO& handler::err(const char* opts) const {
          opts = opts;
          if (!_err) _err = IO::_default;
          if (!_err) _err = IO::_default = new IO;
          return *_err;
          }
  
  IO& handler::in(const char* opts) const {
          opts = opts;
          if (!_in) _in = IO::_default;
          return *_in;
          }
  
  void handler::_declare(const handler* h) const { REGISTER(h); }
  
  void handler::_register(const obscure* h) const { LREGISTER(h); }
  void handler::_register(const handler* h) const { LREGISTER(h); }
  void handler::_register(const term* p) const { LREGISTER(p); }
  void handler::_register(const char* p) const { LREGISTER(p); }
  void handler::_register(const dvstring* p) const { LREGISTER(p); }
  ifndef NOLIST
  void handler::_register(const dvlist_type* p) const { REGISTER(p); }
  endif
  void handler::_register(const iter_type* p) const { REGISTER(p); }
  void handler::_register(const dictionary_type* p) const { REGISTER(p); }
  void handler::_register(const garbage_type* p) const { REGISTER(p); }
  void handler::_register(const dvbinding* p) const { REGISTER(p); }
  void handler::_register(const srv_type* p) const { REGISTER(p); }
  void handler::_register(const clt_type* p) const { REGISTER(p); }
  void handler::_register(const vm_type* p) const { REGISTER(p); }
  
    
/ CORE(AE):

//If the member initializations are taken out core follows handler::handler() { handler::created++; _vmp = 0; _name = 0; _state = 0; // new handler_state; _event = 0; tk = 0; _garb = 0; // ... tk = kit::_default; } handler::~handler() { handler::_cleanup(); //if (LGARB) { delete (light_garbage*) LGARB; LGARB = 0; } if (_state && (--STATE->refs == 0)) delete STATE; handler::deleted++; } void handler::_cleanup(const char* opts) const { opts = opts; // AE for future refinement if (LGARB) { delete (light_garbage*) LGARB; /*LGARB = 0;*/ } if (_state && GARB) { delete (hush_garbage*) GARB; GARB = 0; } } handler_option& handler::operator[](const char* key) { handler_option* x = new handler_option(this,key); _register(x); return *x; } void handler::rename(const char* s) { if (_context()) _context()->rename(s); else if (s && _exists()) _this()->rename(s); else if (s) { if (NAME) delete[] NAME; NAME = new char[strlen(s)+1]; strcpy(NAME,s); } } char* handler::name() const { //if (_context()) return _context()->name(); else return NAME; } char* handler::description() const { return "handler"; } char* handler::mimetype() const { return "application/x-hush:.sh:"; } int handler::mode() const { return _state?MODE:0; } int handler::mode( int i ) { if (_exists()) return _this()->mode(); else { if (!_state) _state = new handler_state; int tmp = MODE; MODE = i; return tmp; } } /* int handler::mode( const char* s ) { if (_exists()) return _this()->mode(s); else { if (!_state) _state = new handler_state; int tmp = MODE; if (!strcmp(s,"explicit")) MODE = handler::explic; else if (!strcmp(s,"implicit")) MODE = handler::implicit; else _error("mode"); return tmp; } }*/ char* handler::category() const { return "hush"; } char* handler::info() const { return "handler"; } // obsolete kit* handler::thekit() const { if (_exists()) return _this()->thekit(); else return tk?tk: kit::_default; } event* handler::dispatch(event* e) { _event = e; if (_vmp) { return ((vm<handler>*)_vmp)->dispatch(e); } else { if (e->thekit()) tk = e->thekit(); // AE int result = this->operator()(); if (result != OK) return 0; // jrvosse else return _event; } } int handler::operator()() { require( tk ); if (!_event) return 0;
check for event

event* e = _event; if (tk->tracelevel() > 5) { err() << "EVENT: " << e->eventclass() << " " << e->info() << "(" << event::created << "," << event::deleted << ")" << "\n"; } if (tk->tracelevel() > 3) { err() << "EVENT " << e->type() << " " << e->name() << "\n"; } if ( e->type() == ButtonPress ) press(*e); else if ( e->type() == ButtonRelease ) release(*e); else if ( e->type() == KeyPress ) keypress(*e); else if ( e->type() == KeyRelease ) keyrelease(*e); else if ( e->type() == MotionNotify ) motion(*e); else if ( e->type() == EnterNotify ) enter(*e); else if ( e->type() == LeaveNotify ) leave(*e); else other(*e); return 0; } void handler::other(event&) { } int handler::verify() const { if (_exists()) return _this()->verify(); else return 1; } void handler::obsolete(const char* s) const { _obsolete(s); } void handler::dependent(handler* h) { if (_exists()) _this()->dependent(h); else { if (!_state) _state = new handler_state; if (h->contains(this)) { err() << "ERROR: circular dependency by linking "; err() << h->name() << " to " << this->name() << "\n"; } else if (!ETC) { ETC = new cell(h); } else ETC->insert(h); } } void handler::remove(handler* e) { if (_exists()) _this()->remove(e); else { cell* p = (_state && ETC)? ETC : 0; while (p) { handler* h = (handler*) p->el; if (h == e) p->el = 0; p = p->next; } } } void handler::process(event* e) { if (_exists()) _this()->process(e); else { event* x = e; cell* p = (_state && ETC) ? ETC: 0; handler* h = p ? (handler*) p->el : 0; while (h && p) { x = h->dispatch(x); p = p->next; h = p ? (handler*) p->el : 0; } } } int handler::contains(handler* h) { if (_exists()) return _this()->contains(h); else return (STATE && ETC)?ETC->contains(h):0; } void handler::option(const char* k, const char* v) { if (_exists()) _this()->option(k,v); else { int x = 0; // option(k); if (!x && v) { if (!_state) _state = new handler_state(); if (!STATE->s_options) { STATE->s_options = new dictionary<dvstring>; _register( STATE->s_options); } dvstring* p = new dvstring(v); STATE->s_options->_register(p); (*STATE->s_options)[k] = p; } } } char* handler::option(const char* k) { if (_exists()) return _this()->option(k); else if (k) { dvstring* result = 0; if (STATE && !STATE->s_options) result = 0; else result = (*STATE->s_options)[k]; if (result) return *result; else return 0; } else return 0; } void handler::_option(const char* s, int n) { if (_exists()) _this()->_option(s,n); else { int x = _option(s); if (!x && n) { if (!_state) _state = new handler_state(); if (!STATE->i_options) { STATE->i_options = new dictionary<int>; _register( STATE->i_options); } int* p = new int(n); STATE->i_options->_register(p); (*STATE->i_options)[s] = p; } } } int handler::_option(const char* s) { if (_exists()) return _this()->_option(s); else { int* pn = 0; int result = 0; if (STATE && !STATE->i_options) result = 0; else pn = (*STATE->i_options)[s]; if (pn) return *pn; else result = 0; return result; } } void handler::_resource(const char* s, handler* p) { if (_exists()) _this()->_resource(s,p); else { if (p) { if (!_state) _state = new handler_state(); if (!STATE->resources) { STATE->resources = new dictionary<void>; _register( STATE->resources ); } (*STATE->resources)[s] = (void*) p; } } } handler* handler::_resource(const char* s) { if (_exists()) return _this()->_resource(s); else { void* pn = 0; if (STATE && STATE->resources) pn = (*STATE->resources)[s]; return (handler*) pn; } }
/ Utilities

char* handler::flatten(int argc, char* argv[]) const { char* buf = new char [BUFSIZ];
LEAK!

char temp[BUFSIZ]; buf[0]='\0'; if (argc > 0) { strcpy(buf,*argv++); argc--; } while (--argc >= 0) { temp[0] = '\0'; sprintf(temp,"%s %s",buf,*argv++); strcpy(buf,temp); } return buf; } static int check(const char* s) { int b = 0; const char* p = s; while (!b && *p) if (*p++ == ' ') b = 1; return b; } char* handler::quote(int argc, char* argv[]) const { char* buf = new char [BUFSIZ];
LEAK!

char temp[BUFSIZ]; buf[0]='\0'; if (argc > 0) { strcpy(buf,*argv++); argc--; } while (--argc >= 0) { temp[0] = '\0'; if (check(*argv)) sprintf(temp,"%s {%s}",buf,*argv++); else sprintf(temp,"%s %s",buf,*argv++); strcpy(buf,temp); } return buf; } char* handler::gensym(const char* s) const { char* buf = new char [BUFSIZ];
LEAK!

if (!s) sprintf(buf,"handler%d",++handler::_no); else sprintf(buf,"%s%d",s,++handler::_no); return buf; }
/ The handler 'dispatch logic' for inner and outer contexts

int handler::invariant() const { // private _body(), _context() is virt return ((_body() != this) && (_context() != this) && (_self() != this) && !(_body() && _context()) ); }
/ Meta handlers

handler* handler::_redirect(handler* x) { // to inner component //AE require( invariant() ); require( x && x != this ); if (!_state) _state = new handler_state(); STATE->_slf = x; //promise( invariant() ); return this; } void handler::_reparent(handler* x) { // to outer component require( x && x != this && invariant() ); if (!_state) _state = new handler_state(); handler* h = x->_context(); if (h) { require( h != this ); STATE->_ctx = h; } else STATE->_ctx = x; _debug("_reparent"); promise( handler::invariant() ); } void handler::_alias(handler* x) { // Any idea? require( x && x != this && invariant() ); if (!_state) _state = new handler_state(); handler* h = x->_body(); if (h) { require( h != this ); STATE->_bdy = h; } else STATE->_bdy = x; _debug("_alias"); promise( handler::invariant() ); }
/ To check whether there is an inner or outer context

handler* handler::_body() const { return 0; } // private - override!! int handler::_exists() const { return _this() != this; } // private handler* handler::_this() const { // private -- as an example return (handler*) this; }
/ Public access functions -- non virtual

handler* handler::_context() const { //require( invariant() ); return STATE?STATE->_ctx:0; } handler* handler::_self() const { //require( invariant() ); return STATE?STATE->_slf:0; } // Notification void handler::_write(const char* s, const char* msg ) const { //err() cerr << "(" << category() << ") " << info() << "::" << s << " " << msg << " (" << name() << ")" << " <" << (void*)this << ", " << _body() << ". " << _context() << ">" << "\n"; } void* handler::_error(const char* s, const char* msg ) const { err() << "ERROR: "; _write(s,msg); return 0; } void handler::_warning(const char* s, const char* msg ) const { err() << "WARNING: "; _write(s,msg); } void handler::_debug(const char* s, const char* msg ) const { if (session::_trace > 3 ) { cerr << "DEBUG: "; _write(s,msg); //err() << "DEBUG: "; _write(s,msg); } } void handler::_obsolete(const char* s, const char* msg ) const { err() << "OBSOLETE: "; _write(s,msg); } // unquote char* handler::unquote(const char* s) const { static char buf[1024*10]; if (!s) return 0; char* p = (char*) s; int i=0; while ( p && *p != 0 ) { if ( *p != '\'' && *p != '\\' ) buf[i++] = *p++; else p++; } buf[i]='\0'; strcpy((char*)s,buf); return (char*) s; }

logic


  
  long handler::eval(const char* cmd) { return tk?tk->eval(cmd):0; }
  char* handler::evaluate(const char* cmd) { return tk?tk->evaluate(cmd):0; }
  
  char* handler::result(long id) { return tk?tk->result(id):0; }
  void handler::result(const char* s) {
          if (_event) _event->result(s); 
          }
  
  

slide: logic


Some more utilities


  
  #undef cerr
  #undef cout
  #undef ostream
  
  include <fstream.h>
  
  void handler::fileout(const char* f, const char* s) {
          if (f && s) {
                  ofstream out(f);
                  if (out.fail()) {
                          cerr << "handler::fileout fail " << f << endl;
                  } else {
                          out << s << endl;
                  }
          }
  }
  
  include <hush/agent.h>
  static char file_result[1024];
  
  char* handler::filein(const char* f) {
          if (!agent::_default) {
                  agent::_default = new agent();
                  _register(agent::_default);
                  }
          char* x = agent::_default->source(f);
          ifstream in;
          in.open(x);
          if (in.fail()) {
                  cerr << "handler::filein fail " << f << endl;        
          } else {
                  in >> (char*) file_result;
                  return (char*) file_result;
          }
  return 0;
  }
  
  

slide: Some more utilities

  

[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?
Hush Online Technology
hush@cs.vu.nl
11/03/98