ia64/xen-unstable

changeset 1707:6235d9c48836

bitkeeper revision 1.1041.15.3 (40ec1dd4h5qRYtsl7ADmrQI9P_NxoA)

Merge xenbk@gandalf:/var/bk/xeno-unstable.bk
into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk
author mjw@wray-m-3.hpl.hp.com
date Wed Jul 07 15:59:16 2004 +0000 (2004-07-07)
parents 1a6a93fdeafc c476ce27bde8
children 05488465ed73
files .rootkeys tools/Makefile tools/libxutil/sys_net.c tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendMigrate.py tools/xfrd/Make.xfrd tools/xfrd/connection.c tools/xfrd/connection.h tools/xfrd/sxpr_parser.c tools/xfrd/sxpr_parser.h tools/xfrd/xen_domain.c tools/xfrd/xfrd.c tools/xfrd/xfrdClient.py
line diff
     1.1 --- a/.rootkeys	Wed Jul 07 13:07:37 2004 +0000
     1.2 +++ b/.rootkeys	Wed Jul 07 15:59:16 2004 +0000
     1.3 @@ -296,6 +296,8 @@ 40e9808eCsmywryb036TdtRMJHDMmQ tools/xfr
     1.4  40e9808e99OcM547cKMTfmCVSoWVAw tools/xfrd/select.h
     1.5  40e9808e5_PLdodqVOSx0b4T_f5aeg tools/xfrd/sxpr.c
     1.6  40e9808e0O4sHZtkDv5hlSqjYcdQAQ tools/xfrd/sxpr.h
     1.7 +40ec1cc6SIiGbynOi-1NtPesOlzF-Q tools/xfrd/sxpr_parser.c
     1.8 +40ec1cc6wpvvGxZiq4EFvNOcw0tUFg tools/xfrd/sxpr_parser.h
     1.9  40e9808eF3NVldqRNS5IHM8gbFAvpw tools/xfrd/xdr.c
    1.10  40e9808ezXzoRHm7pybXU69NtnjimA tools/xfrd/xdr.h
    1.11  40e9808edpUtf4bJ8IbqClPJj_OvbA tools/xfrd/xen_domain.c
     2.1 --- a/tools/Makefile	Wed Jul 07 13:07:37 2004 +0000
     2.2 +++ b/tools/Makefile	Wed Jul 07 15:59:16 2004 +0000
     2.3 @@ -6,6 +6,7 @@ all:
     2.4  	$(MAKE) -C examples
     2.5  	$(MAKE) -C xentrace
     2.6  	$(MAKE) -C python
     2.7 +	$(MAKE) -C xfrd
     2.8  
     2.9  install: all
    2.10  	$(MAKE) -C libxutil install
    2.11 @@ -14,6 +15,7 @@ install: all
    2.12  	$(MAKE) -C examples install
    2.13  	$(MAKE) -C xentrace install
    2.14  	$(MAKE) -C python install
    2.15 +	$(MAKE) -C xfrd install
    2.16  
    2.17  dist: $(TARGET)
    2.18  	$(MAKE) prefix=`pwd`/../../install dist=yes install
    2.19 @@ -26,4 +28,5 @@ clean:
    2.20  	$(MAKE) -C examples clean
    2.21  	$(MAKE) -C xentrace clean
    2.22  	$(MAKE) -C python clean
    2.23 +	$(MAKE) -C xfrd clean
    2.24  
     3.1 --- a/tools/libxutil/sys_net.c	Wed Jul 07 13:07:37 2004 +0000
     3.2 +++ b/tools/libxutil/sys_net.c	Wed Jul 07 15:59:16 2004 +0000
     3.3 @@ -18,6 +18,12 @@
     3.4  #include "sys_net.h"
     3.5  #include "sys_string.h"
     3.6  
     3.7 +#ifdef __KERNEL__
     3.8 +#  include <linux/errno.h>
     3.9 +#else
    3.10 +#  include <errno.h>
    3.11 +#endif
    3.12 +
    3.13  /** @file
    3.14   * All network data are kept in network order and only converted to
    3.15   * host order for display. Network data includes IP addresses, port numbers and
    3.16 @@ -80,7 +86,7 @@ inline static int indexof(const char *s,
    3.17   *
    3.18   * @param s input string
    3.19   * @param address where to put the address
    3.20 - * @return 0 on success, -1 on error
    3.21 + * @return 0 on success, negative on error
    3.22   */
    3.23  int get_inet_addr(const char *s, unsigned long *address){
    3.24      // Number of bits in a byte.
    3.25 @@ -96,7 +102,7 @@ int get_inet_addr(const char *s, unsigne
    3.26      unsigned long addr = 0;
    3.27      unsigned long v;
    3.28      int i;
    3.29 -    int err = -1;
    3.30 +    int err = -EINVAL;
    3.31      // Bit shift for the current byte.
    3.32      int shift = BYTE_BITS * (WORD_BYTES - 1);
    3.33      char buf[64];
    3.34 @@ -168,18 +174,18 @@ int inet_aton(const char *address, struc
    3.35   *
    3.36   * @param name input hostname or address string
    3.37   * @param address where to put the address
    3.38 - * @return 1 if address found OK, 0 otherwise
    3.39 + * @return 0 if address found OK, nonzero otherwise
    3.40   */
    3.41  int get_host_address(const char *name, unsigned long *address){
    3.42  #ifdef __KERNEL__
    3.43 -    return get_inet_addr(name, address) == 0;
    3.44 +    return get_inet_addr(name, address);
    3.45  #else
    3.46      struct hostent *host = gethostbyname(name);
    3.47      if(!host){
    3.48 -        return 0;
    3.49 +        return -EINVAL;
    3.50      }
    3.51      *address = ((struct in_addr *)(host->h_addr))->s_addr;
    3.52 -    return 1;
    3.53 +    return 0;
    3.54  #endif
    3.55  }
    3.56  
    3.57 @@ -187,33 +193,33 @@ int get_host_address(const char *name, u
    3.58   *
    3.59   * @param name service name
    3.60   * @param port where to put the port
    3.61 - * @return 1 if service port found OK, 0 otherwise
    3.62 + * @return 0 if service port found OK, negative otherwise
    3.63   */
    3.64  int get_service_port(const char *name, unsigned long *port){
    3.65  #ifdef __KERNEL__
    3.66 -    return 0;
    3.67 +    return -ENOSYS;
    3.68  #else
    3.69      struct servent *service;
    3.70      service = getservbyname(name, 0);
    3.71      if(!service){
    3.72 -        return 0;
    3.73 +        return -EINVAL;
    3.74      }
    3.75      *port = service->s_port;
    3.76 -    return 1;
    3.77 +    return 0;
    3.78  #endif
    3.79  }
    3.80  
    3.81  /** Convert a port number (in network order) to a service name.
    3.82   *
    3.83   * @param port the port number
    3.84 - * @return service name if found OK, 0 otherwise
    3.85 + * @return service name if found OK, NULL otherwise
    3.86   */
    3.87  char *get_port_service(unsigned long port){
    3.88  #ifdef __KERNEL__
    3.89 -    return 0;
    3.90 +    return NULL;
    3.91  #else
    3.92      struct servent *service = getservbyport(port, 0);
    3.93 -    return (service ? service->s_name : 0);
    3.94 +    return (service ? service->s_name : NULL);
    3.95  #endif
    3.96  }
    3.97  
    3.98 @@ -221,19 +227,27 @@ char *get_port_service(unsigned long por
    3.99   *
   3.100   * @param s input to convert
   3.101   * @param port where to put the port
   3.102 - * @return 1 if port found OK, 0 otherwise
   3.103 + * @return 0 if port found OK, -1 otherwise
   3.104   */
   3.105  int convert_service_to_port(const char *s, unsigned long *port){
   3.106 -    int ok = 0;
   3.107 +    int err = 0;
   3.108      unsigned long value;
   3.109 -    if(convert_atoul(s, &value)){
   3.110 -        ok = get_service_port(s, &value);
   3.111 +    printf("%s> %s\n", __FUNCTION__, s);
   3.112 +    if(convert_atoul(s, &value) == 0){
   3.113 +        int ok = (0 <= value) && (value <= PORT_MAX);
   3.114 +        printf("> value = %ld\n", value);
   3.115 +        if(ok){
   3.116 +            value = htons((unsigned short)value);
   3.117 +        } else {
   3.118 +            err = -EINVAL;
   3.119 +        }
   3.120      } else {
   3.121 -        ok = (0 <= value) && (value <= PORT_MAX);
   3.122 -        value = htons((unsigned short)value);
   3.123 +        printf("> get_service_port...\n");
   3.124 +        err = get_service_port(s, &value);
   3.125      }
   3.126 -    *port = (ok ? value : 0);
   3.127 -    return ok;
   3.128 +    *port = (err ? 0: value);
   3.129 +    printf("%s< err=%d\n", __FUNCTION__, err);
   3.130 +    return err;
   3.131  }
   3.132  
   3.133  #define MAC_ELEMENT_N  6 // Number of elements in a MAC address.
     4.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Jul 07 13:07:37 2004 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Jul 07 15:59:16 2004 +0000
     4.3 @@ -19,6 +19,7 @@ xroot = XendRoot.instance()
     4.4  import XendDB
     4.5  import XendDomainInfo
     4.6  import XendConsole
     4.7 +import XendMigrate
     4.8  import EventServer
     4.9  
    4.10  from xen.xend.server import SrvDaemon
    4.11 @@ -423,7 +424,9 @@ class XendDomain:
    4.12          """
    4.13          # Need a cancel too?
    4.14          # Don't forget to cancel restart for it.
    4.15 -        pass
    4.16 +        dom = int(id)
    4.17 +        xmigrate = XendMigrate.instance()
    4.18 +        return xmigrate.migrate_begin(dom, dst)
    4.19  
    4.20      def domain_save(self, id, dst, progress=0):
    4.21          """Save domain state to file, destroy domain on success.
     5.1 --- a/tools/python/xen/xend/XendMigrate.py	Wed Jul 07 13:07:37 2004 +0000
     5.2 +++ b/tools/python/xen/xend/XendMigrate.py	Wed Jul 07 15:59:16 2004 +0000
     5.3 @@ -14,11 +14,6 @@ import sxp
     5.4  import XendDB
     5.5  import EventServer; eserver = EventServer.instance()
     5.6  
     5.7 -from xen.xend.packing import SxpPacker, SxpUnpacker
     5.8 -from xen.xend import XendDomain
     5.9 -xd = XendDomain.instance()
    5.10 -
    5.11 -
    5.12  XFRD_PORT = 8002
    5.13  
    5.14  XFR_PROTO_MAJOR = 1
    5.15 @@ -27,55 +22,63 @@ XFR_PROTO_MINOR = 0
    5.16  class Migrate(Protocol):
    5.17  
    5.18      def __init__(self, minfo):
    5.19 -        self.packer = None
    5.20 -        self.unpacker = None
    5.21 +        self.parser = sxp.Parser()
    5.22          self.minfo = minfo
    5.23  
    5.24      def connectionMade(self):
    5.25 -        self.packer = SxpPacker(self.transport)
    5.26 -        self.unpacker = SxpPacker()
    5.27          # Send hello.
    5.28 -        self.packer.pack(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR])
    5.29 +        self.request(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR])
    5.30          # Send migrate.
    5.31          vmconfig = self.minfo.vmconfig()
    5.32          if not vmconfig:
    5.33              self.loseConnection()
    5.34              return
    5.35 -        self.packer.pack(['xfr.migrate',
    5.36 -                          self.minfo.src_dom,
    5.37 -                          vmconfig,
    5.38 -                          self.minfo.dst_host,
    5.39 -                          self.minfo.dst_port])
    5.40 +        self.request(['xfr.migrate',
    5.41 +                      self.minfo.src_dom,
    5.42 +                      vmconfig,
    5.43 +                      self.minfo.dst_host,
    5.44 +                      self.minfo.dst_port])
    5.45 +
    5.46 +    def request(self, req):
    5.47 +        sxp.show(req, out=self.transport)
    5.48 +        self.transport.write(' \n')
    5.49 +
    5.50 +    def loseConnection(self):
    5.51 +        self.transport.loseConnection()
    5.52  
    5.53      def connectionLost(self, reason):
    5.54          self.minfo.closed(reason)
    5.55  
    5.56 +    def dispatch(self, val):
    5.57 +        op = sxp.name(val)
    5.58 +        op = op.replace('.', '_')
    5.59 +        if op.startswith('xfr_'):
    5.60 +            fn = getattr(self, op, self.unknown)
    5.61 +        else:
    5.62 +            fn = self.unknown()
    5.63 +        fn(val)
    5.64 +
    5.65      def dataReceived(self, data):
    5.66 -        try:
    5.67 -            self.unpacker.reset(data)
    5.68 -            val = self.unpacker.unpack()
    5.69 -            print 'dataReceived>', 'val=', val
    5.70 -            op = val[0]
    5.71 -            op.replace('.', '_')
    5.72 -            if op.startwith('xfr_'):
    5.73 -                fn = getattr(self, op, self.unknown)
    5.74 -            else:
    5.75 -                fn = self.unknown
    5.76 -            fn(val)
    5.77 -        except Exception, ex:
    5.78 -            print 'dataReceived>', ex
    5.79 -            pass
    5.80 -
    5.81 +        self.parser.input(data)
    5.82 +        if self.parser.ready():
    5.83 +            val = self.parser.get_val()
    5.84 +            self.dispatch(val)
    5.85 +        if self.parser.at_eof():
    5.86 +            self.loseConnection()
    5.87 +            
    5.88      def unknown(self, val):
    5.89          print 'unknown>', val
    5.90  
    5.91      def xfr_progress(self, val):
    5.92          print 'xfr_progress>', val
    5.93  
    5.94 -    def xfr_error(self, val):
    5.95 +    def xfr_err(self, val):
    5.96          # If we get an error with non-zero code the migrate failed.
    5.97          # An error with code zero indicates hello success.
    5.98 -        err = int(val[1])
    5.99 +        print 'xfr_err>', val
   5.100 +        v = sxp.child(val)
   5.101 +        print 'xfr_err>', type(v), v
   5.102 +        err = int(sxp.child(val))
   5.103          if not err: return
   5.104          self.minfo.error(err);
   5.105          self.loseConnection()
   5.106 @@ -83,14 +86,15 @@ class Migrate(Protocol):
   5.107      def xfr_ok(self, val):
   5.108          # An ok indicates migrate completed successfully, and contains
   5.109          # the new domain id on the remote system.
   5.110 -        dom = int(val[1])
   5.111 +        print 'xfr_ok>', val
   5.112 +        dom = int(sxp.child(val))
   5.113          self.minfo.ok(dom)
   5.114          self.loseConnection()
   5.115  
   5.116  class MigrateClientFactory(ClientFactory):
   5.117  
   5.118      def __init__(self, minfo):
   5.119 -        ClientFactory.__init__(self)
   5.120 +        #ClientFactory.__init__(self)
   5.121          self.minfo = minfo
   5.122  
   5.123      def startedConnecting(self, connector):
   5.124 @@ -116,7 +120,7 @@ class XendMigrateInfo:
   5.125          self.state = 'begin'
   5.126          self.src_host = socket.gethostname()
   5.127          self.src_dom = dom
   5.128 -        self.dst_host = dst
   5.129 +        self.dst_host = host
   5.130          self.dst_port = port
   5.131          self.dst_dom = None
   5.132          self.start = 0
   5.133 @@ -139,12 +143,18 @@ class XendMigrateInfo:
   5.134          return sxpr
   5.135  
   5.136      def vmconfig(self):
   5.137 -        dominfo = xd.domain_get(self.dom)
   5.138 +        print 'vmconfig>'
   5.139 +        from xen.xend import XendDomain
   5.140 +        xd = XendDomain.instance()
   5.141 +
   5.142 +        dominfo = xd.domain_get(self.src_dom)
   5.143 +        print 'vmconfig>', type(dominfo), dominfo
   5.144          if dominfo:
   5.145 -            val = return sxp.to_string(dominfo)
   5.146 +            val = sxp.to_string(dominfo.sxpr())
   5.147          else:
   5.148              val = None
   5.149 -        return None
   5.150 +        print 'vmconfig<', 'val=', type(val), val
   5.151 +        return val
   5.152  
   5.153      def error(self, err):
   5.154          self.state = 'error'
   5.155 @@ -153,7 +163,7 @@ class XendMigrateInfo:
   5.156          self.state = 'ok'
   5.157          self.dst_dom = dom
   5.158  
   5.159 -    def close(self):
   5.160 +    def closed(self, reason=None):
   5.161          if self.state =='ok':
   5.162              eserver.inject('xend.migrate.ok', self.sxpr())
   5.163          else:
   5.164 @@ -208,15 +218,15 @@ class XendMigrate:
   5.165      def migrate_get(self, id):
   5.166          return self.migrate.get(id)
   5.167      
   5.168 -    def migrate_begin(self, dom, host):
   5.169 +    def migrate_begin(self, dom, host, port=XFRD_PORT):
   5.170          # Check dom for existence, not migrating already.
   5.171          # Subscribe to migrate notifications (for updating).
   5.172          id = self.nextid()
   5.173 -        info = XenMigrateInfo(id, dom, host, XFRD_PORT)
   5.174 +        info = XendMigrateInfo(id, dom, host, port)
   5.175          self._add_migrate(id, info)
   5.176          mcf = MigrateClientFactory(info)
   5.177          reactor.connectTCP('localhost', XFRD_PORT, mcf)
   5.178 -        return info.deferred
   5.179 +        return info
   5.180  
   5.181  def instance():
   5.182      global inst
     6.1 --- a/tools/xfrd/Make.xfrd	Wed Jul 07 13:07:37 2004 +0000
     6.2 +++ b/tools/xfrd/Make.xfrd	Wed Jul 07 15:59:16 2004 +0000
     6.3 @@ -15,7 +15,7 @@ UTIL_LIB_SRC += lzi_stream.c
     6.4  UTIL_LIB_SRC += marshal.c
     6.5  UTIL_LIB_SRC += string_stream.c
     6.6  UTIL_LIB_SRC += sxpr.c
     6.7 -#UTIL_LIB_SRC += sxpr_parser.c
     6.8 +UTIL_LIB_SRC += sxpr_parser.c
     6.9  UTIL_LIB_SRC += sys_net.c
    6.10  UTIL_LIB_SRC += sys_string.c
    6.11  #UTIL_LIB_SRC += util.c
     7.1 --- a/tools/xfrd/connection.c	Wed Jul 07 13:07:37 2004 +0000
     7.2 +++ b/tools/xfrd/connection.c	Wed Jul 07 15:59:16 2004 +0000
     7.3 @@ -8,6 +8,7 @@
     7.4  #include "connection.h"
     7.5  #include "file_stream.h"
     7.6  #include "lzi_stream.h"
     7.7 +#include "sxpr_parser.h"
     7.8  
     7.9  #define dprintf(fmt, args...) fprintf(stdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
    7.10  #define wprintf(fmt, args...) fprintf(stderr, "[WARN]  %s" fmt, __FUNCTION__, ##args)
    7.11 @@ -161,3 +162,34 @@ void Conn_close(Conn *conn){
    7.12      if(conn->out) IOStream_close(conn->out);
    7.13      shutdown(conn->sock, 2);
    7.14  }
    7.15 +
    7.16 +int Conn_sxpr(Conn *conn, Sxpr *sxpr){
    7.17 +    int err = 0;
    7.18 +    Sxpr val = ONONE;
    7.19 +    int c = 0;
    7.20 +
    7.21 +    dprintf(">\n");
    7.22 +    if(!conn->parser){
    7.23 +        conn->parser = Parser_new();
    7.24 +        set_error_stream(conn->parser, iostdout);
    7.25 +    }
    7.26 +    while(!err && c >= 0 && !Parser_ready(conn->parser)){
    7.27 +        c = IOStream_getc(conn->in);
    7.28 +        printf("%c", (char)c);
    7.29 +        if(c < 0){
    7.30 +            err = Parser_input_eof(conn->parser);
    7.31 +        } else {
    7.32 +            err = Parser_input_char(conn->parser, c);
    7.33 +        }
    7.34 +    }
    7.35 +    if(Parser_ready(conn->parser)){
    7.36 +        val = Parser_get_val(conn->parser);
    7.37 +    }
    7.38 +    if(err){
    7.39 +        objfree(val);
    7.40 +        val = ONONE;
    7.41 +    }
    7.42 +    *sxpr = val;
    7.43 +    dprintf("< err=%d\n", err);
    7.44 +    return err;
    7.45 +}
     8.1 --- a/tools/xfrd/connection.h	Wed Jul 07 13:07:37 2004 +0000
     8.2 +++ b/tools/xfrd/connection.h	Wed Jul 07 15:59:16 2004 +0000
     8.3 @@ -5,6 +5,7 @@
     8.4  #include <netinet/in.h>
     8.5  
     8.6  #include "iostream.h"
     8.7 +#include "sxpr_parser.h"
     8.8  
     8.9  /** A connection.
    8.10   * The underlying transport is a socket. 
    8.11 @@ -15,6 +16,7 @@ typedef struct Conn {
    8.12      int sock;
    8.13      IOStream *in;
    8.14      IOStream *out;
    8.15 +    Parser *parser;
    8.16  } Conn;
    8.17  
    8.18  enum {
    8.19 @@ -29,4 +31,6 @@ extern int Conn_init(Conn *conn, int fla
    8.20  extern int Conn_connect(Conn *conn, int flags, struct in_addr ipaddr, uint16_t port);
    8.21  extern void Conn_close(Conn *conn);
    8.22  
    8.23 +extern int Conn_sxpr(Conn *conn, Sxpr *sxpr);
    8.24 +
    8.25  #endif /* ! _VFC_CONNECTION_H_ */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/xfrd/sxpr_parser.c	Wed Jul 07 15:59:16 2004 +0000
     9.3 @@ -0,0 +1,943 @@
     9.4 +
     9.5 +#ifdef __KERNEL__
     9.6 +#  include <linux/config.h>
     9.7 +#  include <linux/module.h>
     9.8 +#  include <linux/kernel.h>
     9.9 +#  include <linux/string.h>
    9.10 +#  include <linux/errno.h>
    9.11 +#else
    9.12 +#  include <stdlib.h>
    9.13 +#  include <errno.h>
    9.14 +#endif
    9.15 +
    9.16 +#include "iostream.h"
    9.17 +#include "lexis.h"
    9.18 +#include "sxpr_parser.h"
    9.19 +#include "sys_string.h"
    9.20 +#include "enum.h"
    9.21 +
    9.22 +/** @file
    9.23 + * Sxpr parsing.
    9.24 + *
    9.25 + * So that the parser does not leak memory, all sxprs constructed by
    9.26 + * the parser must be freed on error.  On successful parse the sxpr
    9.27 + * returned becomes the responsibility of the caller.
    9.28 + *
    9.29 + * @author Mike Wray <mike.wray@hpl.hp.com>
    9.30 + */
    9.31 +
    9.32 +#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
    9.33 +#define printf(fmt, args...)   IOStream_print(iostdout, fmt, ##args)
    9.34 +
    9.35 +static void reset(Parser *z);
    9.36 +static int inputchar(Parser *p, char c);
    9.37 +static int savechar(Parser *p, char c);
    9.38 +extern void parse_error(Parser *in);
    9.39 +extern void parse_error_id(Parser *in, ParseErrorId id);
    9.40 +
    9.41 +static int begin_start(Parser *p, char c);
    9.42 +static int state_start(Parser *p, char c);
    9.43 +static int end_start(Parser *p);
    9.44 +
    9.45 +static int begin_comment(Parser *p, char c);
    9.46 +static int state_comment(Parser *p, char c);
    9.47 +static int end_comment(Parser *p);
    9.48 +
    9.49 +static int begin_string(Parser *p, char c);
    9.50 +static int state_string(Parser *p, char c);
    9.51 +static int end_string(Parser *p);
    9.52 +static int state_escape(Parser *p, char c);
    9.53 +static int state_octal(Parser *p, char c);
    9.54 +static int state_hex(Parser *p, char c);
    9.55 +
    9.56 +static int begin_atom(Parser *p, char c);
    9.57 +static int state_atom(Parser *p, char c);
    9.58 +static int end_atom(Parser *p);
    9.59 +
    9.60 +static int state_list(Parser *p, char c);
    9.61 +static int begin_list(Parser *p, char c);
    9.62 +static int end_list(Parser *p);
    9.63 +
    9.64 +/** Print a parse error.
    9.65 + *
    9.66 + * @param in parser
    9.67 + * @param msg format followed by printf arguments
    9.68 + */
    9.69 +void eprintf(Parser *in, char *msg, ...){
    9.70 +    va_list args;
    9.71 +    if(in->error_out){
    9.72 +        va_start(args, msg);
    9.73 +        IOStream_vprint(in->error_out, msg, args);
    9.74 +        va_end(args);
    9.75 +    }
    9.76 +}
    9.77 +
    9.78 +/** Print a parse warning.
    9.79 + *
    9.80 + * @param in parser
    9.81 + * @param msg format followed by printf arguments
    9.82 + */
    9.83 +void wprintf(Parser *in, char *msg, ...){
    9.84 +    va_list args;
    9.85 +    if(in->error_out){
    9.86 +        va_start(args, msg);
    9.87 +        IOStream_vprint(in->error_out, msg, args);
    9.88 +        va_end(args);
    9.89 +    }
    9.90 +}
    9.91 +
    9.92 +/*============================================================================*/
    9.93 +
    9.94 +/** Record defining the message for a parse error. */
    9.95 +typedef struct {
    9.96 +  ParseErrorId id;
    9.97 +  char *message;
    9.98 +} ParseError;
    9.99 +
   9.100 +/** Format for printing parse error messages. */
   9.101 +#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s"
   9.102 +
   9.103 +/** Message catalog for the parse error codes. */
   9.104 +static ParseError catalog[] = {
   9.105 +  { PARSE_ERR_UNSPECIFIED,            "unspecified error" },
   9.106 +  { PARSE_ERR_NOMEM,                  "out of memory" },
   9.107 +  { PARSE_ERR_UNEXPECTED_EOF,         "unexpected end of input" },
   9.108 +  { PARSE_ERR_TOKEN_TOO_LONG,         "token too long" },
   9.109 +  { PARSE_ERR_INVALID_SYNTAX,         "syntax error" },
   9.110 +  { PARSE_ERR_INVALID_ESCAPE,         "invalid escape" },
   9.111 +  { 0, NULL }
   9.112 +};
   9.113 +
   9.114 +/** Number of entries in the message catalog. */
   9.115 +const static int catalog_n = sizeof(catalog)/sizeof(ParseError);
   9.116 +
   9.117 +void ParserState_free(ParserState *z){
   9.118 +    if(!z) return;
   9.119 +    objfree(z->val);
   9.120 +    deallocate(z);
   9.121 +}
   9.122 +
   9.123 +int ParserState_new(ParserStateFn *fn, char *name,
   9.124 +                    ParserState *parent, ParserState **val){
   9.125 +    int err = 0;
   9.126 +    ParserState *z;
   9.127 +    z = ALLOCATE(ParserState);
   9.128 +    if(z){
   9.129 +        z->name = name;
   9.130 +        z->fn = fn;
   9.131 +        z->parent = parent;
   9.132 +        z->val = ONULL;
   9.133 +    } else {
   9.134 +        err = -ENOMEM;
   9.135 +    }
   9.136 +    if(!err) *val = z;
   9.137 +    return err;
   9.138 +}
   9.139 +
   9.140 +/** Free a parser.
   9.141 + * No-op if the parser is null.
   9.142 + *
   9.143 + * @param z parser 
   9.144 + */
   9.145 +void Parser_free(Parser *z){
   9.146 +    if(!z) return;
   9.147 +    objfree(z->val);
   9.148 +    z->val = ONONE;
   9.149 +    deallocate(z);
   9.150 +}
   9.151 +
   9.152 +/** Create a new parser. The error stream defaults to null.
   9.153 + */
   9.154 +Parser * Parser_new(void){
   9.155 +    Parser *z = ALLOCATE(Parser);
   9.156 +    int err = -ENOMEM;
   9.157 +  
   9.158 +    if(!z) goto exit;
   9.159 +    err = 0;
   9.160 +    reset(z);
   9.161 +  exit:
   9.162 +    if(err){
   9.163 +        Parser_free(z);
   9.164 +        z = NULL;
   9.165 +    }
   9.166 +    return z;
   9.167 +}
   9.168 +
   9.169 +/** Get the next character.
   9.170 + * Records the character read in the parser,
   9.171 + * and sets the line and character counts.
   9.172 + *
   9.173 + * @param p parser
   9.174 + * @return error flag: 0 on success, non-zero on error
   9.175 + */
   9.176 +static int inputchar(Parser *p, char c){
   9.177 +    int err = 0;
   9.178 +    if(c=='\n'){
   9.179 +        p->line_no++;
   9.180 +        p->char_no = 0;
   9.181 +    } else {
   9.182 +        p->char_no++;
   9.183 +    }
   9.184 +    return err;
   9.185 +}
   9.186 +
   9.187 +static int savechar(Parser *p, char c){
   9.188 +    int err = 0;
   9.189 +    if(p->buf_i >= p->buf_n){
   9.190 +        err = -ENOMEM;
   9.191 +        goto exit;
   9.192 +    }
   9.193 +    p->buf[p->buf_i] = c;
   9.194 +    p->buf_i++;
   9.195 +  exit:
   9.196 +    return err;
   9.197 +}
   9.198 +
   9.199 +int Parser_input_char(Parser *p, char c){
   9.200 +    int err = 0;
   9.201 +    if(at_eof(p)){
   9.202 +        //skip;
   9.203 +    } else {
   9.204 +        inputchar(p, c);
   9.205 +    }
   9.206 +    if(!p->state){
   9.207 +        err = begin_start(p, c);
   9.208 +        if(err) goto exit;
   9.209 +    }
   9.210 +    err = p->state->fn(p, c);
   9.211 +  exit:
   9.212 +    return err;
   9.213 +}
   9.214 +
   9.215 +int Parser_input_eof(Parser *p){
   9.216 +    int err = 0;
   9.217 +    p->eof = 1;
   9.218 +    err = Parser_input_char(p, IOSTREAM_EOF);
   9.219 +    return err;
   9.220 +}
   9.221 +
   9.222 +int Parser_input(Parser *p, char *buf, int buf_n){
   9.223 +    int err = 0;
   9.224 +    int i = 0;
   9.225 +    if(buf_n <= 0){
   9.226 +        err = Parser_input_eof(p);
   9.227 +        goto exit;
   9.228 +    }
   9.229 +    for(i = 0; i<buf_n; i++){
   9.230 +        err = Parser_input_char(p, buf[i]);
   9.231 +        if(err) goto exit;
   9.232 +    }
   9.233 +  exit:
   9.234 +    err = (err < 0 ? err : buf_n);
   9.235 +    return err;
   9.236 +}
   9.237 +
   9.238 +int Parser_push(Parser *p, ParserStateFn *fn, char *name){
   9.239 +    int err = 0;
   9.240 +    err = ParserState_new(fn, name, p->state, &p->state);
   9.241 +    return err;
   9.242 +}
   9.243 +        
   9.244 +int Parser_pop(Parser *p){
   9.245 +    int err = 0;
   9.246 +    ParserState *s = p->state;
   9.247 +    p->state = s->parent;
   9.248 +    ParserState_free(s);
   9.249 +    return err;
   9.250 +}
   9.251 +
   9.252 +int Parser_return(Parser *p){
   9.253 +    int err = 0;
   9.254 +    Sxpr val = ONONE;
   9.255 +    if(!p->state){
   9.256 +        err = -EINVAL;
   9.257 +        goto exit;
   9.258 +    }
   9.259 +    val = p->state->val;
   9.260 +    p->state->val = ONONE;
   9.261 +    err = Parser_pop(p);
   9.262 +    if(err) goto exit;
   9.263 +    if(p->state){
   9.264 +        err = cons_push(&p->state->val, val);
   9.265 +    } else {
   9.266 +        val = nrev(val);
   9.267 +        p->val = val;
   9.268 +    }
   9.269 +  exit:
   9.270 +    if(err){
   9.271 +        objfree(val);
   9.272 +    }
   9.273 +    return err;
   9.274 +}
   9.275 +
   9.276 +/** Determine if a character is a separator.
   9.277 + *
   9.278 + * @param p parser
   9.279 + * @param c character to test
   9.280 + * @return 1 if a separator, 0 otherwise
   9.281 + */
   9.282 +static int is_separator(Parser *p, char c){
   9.283 +    return in_sep_class(c);
   9.284 +}
   9.285 +
   9.286 +/** Return the current token.
   9.287 + * The return value points at the internal buffer, so
   9.288 + * it must not be modified (or freed). Use copy_token() if you need a copy.
   9.289 + *
   9.290 + * @param p parser
   9.291 + * @return token
   9.292 + */
   9.293 +char *peek_token(Parser *p){
   9.294 +    return p->buf;
   9.295 +}
   9.296 +
   9.297 +/** Return a copy of the current token.
   9.298 + * The returned value should be freed when finished with.
   9.299 + *
   9.300 + * @param p parser
   9.301 + * @return copy of token
   9.302 + */
   9.303 +char *copy_token(Parser *p){
   9.304 +    return strdup(peek_token(p));
   9.305 +}
   9.306 +
   9.307 +static int do_intern(Parser *p){
   9.308 +    int err = 0;
   9.309 +    Sxpr obj = intern(peek_token(p));
   9.310 +    if(NOMEMP(obj)){
   9.311 +        err = -ENOMEM;
   9.312 +    } else {
   9.313 +        p->state->val = obj;
   9.314 +    }
   9.315 +    return err;
   9.316 +}
   9.317 +
   9.318 +static int do_string(Parser *p){
   9.319 +    int err = 0;
   9.320 +    Sxpr obj;
   9.321 +    obj = string_new(peek_token(p));
   9.322 +    if(NOMEMP(obj)){
   9.323 +        err = -ENOMEM;
   9.324 +    } else {
   9.325 +        p->state->val = obj;
   9.326 +    }
   9.327 +    return err;
   9.328 +}
   9.329 +
   9.330 +void newtoken(Parser *p){
   9.331 +    memset(p->buf, 0, p->buf_n);
   9.332 +    p->buf_i = 0;
   9.333 +    p->tok_begin_line = p->line_no;
   9.334 +    p->tok_begin_char = p->char_no;
   9.335 +}
   9.336 +
   9.337 +int get_escape(char c, char *d){
   9.338 +    int err = 0;
   9.339 +    switch(c){
   9.340 +    case 'a':            *d = '\a'; break;
   9.341 +    case 'b':            *d = '\b'; break;
   9.342 +    case 'f':            *d = '\f'; break;
   9.343 +    case 'n':            *d = '\n'; break;
   9.344 +    case 'r':            *d = '\r'; break;
   9.345 +    case 't':            *d = '\t'; break;
   9.346 +    case 'v':            *d = '\v'; break;
   9.347 +    case c_escape:       *d = c_escape; break;
   9.348 +    case c_single_quote: *d = c_single_quote; break;
   9.349 +    case c_double_quote: *d = c_double_quote; break;
   9.350 +    default:
   9.351 +        err = -EINVAL;
   9.352 +    }
   9.353 +    return err;
   9.354 +}
   9.355 +
   9.356 +int Parser_ready(Parser *p){
   9.357 +    return CONSP(p->val) || (p->start_state && CONSP(p->start_state->val));
   9.358 +}
   9.359 +
   9.360 +Sxpr Parser_get_val(Parser *p){
   9.361 +    Sxpr v = ONONE;
   9.362 +    if(CONSP(p->val)){
   9.363 +        v = CAR(p->val);
   9.364 +        p->val = CDR(p->val);
   9.365 +    } else if (CONSP(p->start_state->val)){
   9.366 +        p->val = p->start_state->val;
   9.367 +        p->val = nrev(p->val);
   9.368 +        p->start_state->val = ONULL;
   9.369 +        v = CAR(p->val);
   9.370 +        p->val = CDR(p->val);
   9.371 +    }        
   9.372 +    return v;
   9.373 +}
   9.374 +
   9.375 +Sxpr Parser_get_all(Parser *p){
   9.376 +    Sxpr v = ONULL;
   9.377 +    if(CONSP(p->val)){
   9.378 +        v = p->val;
   9.379 +        p->val = ONONE;
   9.380 +    } else if(CONSP(p->start_state->val)){
   9.381 +        v = p->start_state->val;
   9.382 +        p->start_state->val = ONULL;
   9.383 +        v = nrev(v);
   9.384 +    }
   9.385 +    return v;
   9.386 +}
   9.387 +    
   9.388 +int begin_start(Parser *p, char c){
   9.389 +    int err = 0;
   9.390 +    err = Parser_push(p, state_start, "start");
   9.391 +    if(err) goto exit;
   9.392 +    p->start_state = p->state;
   9.393 +  exit:
   9.394 +    return err;
   9.395 +}
   9.396 +
   9.397 +int state_start(Parser *p, char c){
   9.398 +    int err = 0;
   9.399 +    if(at_eof(p)){
   9.400 +        err = end_start(p);
   9.401 +    } else if(in_space_class(c)){
   9.402 +        //skip
   9.403 +    } else if(in_comment_class(c)){
   9.404 +        begin_comment(p, c);
   9.405 +    } else if(c == c_list_open){
   9.406 +        begin_list(p, c);
   9.407 +    } else if(c == c_list_close){
   9.408 +        parse_error(p);
   9.409 +        err = -EINVAL;
   9.410 +    } else if(in_string_quote_class(c)){
   9.411 +        begin_string(p, c);
   9.412 +    } else if(in_printable_class(c)){
   9.413 +        begin_atom(p, c);
   9.414 +    } else if(c == 0x04){
   9.415 +        //ctrl-D, EOT: end-of-text.
   9.416 +        Parser_input_eof(p);
   9.417 +    } else {
   9.418 +        parse_error(p);
   9.419 +        err = -EINVAL;
   9.420 +    }
   9.421 +    return err;
   9.422 +}
   9.423 +
   9.424 +int end_start(Parser *p){
   9.425 +    int err = 0;
   9.426 +    err = Parser_return(p);
   9.427 +    return err;
   9.428 +}
   9.429 +
   9.430 +int begin_comment(Parser *p, char c){
   9.431 +    int err = 0;
   9.432 +    err = Parser_push(p, state_comment, "comment");
   9.433 +    if(err) goto exit;
   9.434 +    err = inputchar(p, c);
   9.435 +  exit:
   9.436 +    return err;
   9.437 +}
   9.438 +
   9.439 +int state_comment(Parser *p, char c){
   9.440 +    int err = 0;
   9.441 +    if(c == '\n' || at_eof(p)){
   9.442 +        err = end_comment(p);
   9.443 +    } else {
   9.444 +        err = inputchar(p, c);
   9.445 +    }
   9.446 +    return err;
   9.447 +}
   9.448 +
   9.449 +int end_comment(Parser *p){
   9.450 +    return Parser_pop(p);
   9.451 +}
   9.452 +
   9.453 +int begin_string(Parser *p, char c){
   9.454 +    int err = 0;
   9.455 +    err = Parser_push(p, state_string, "string");
   9.456 +    if(err) goto exit;
   9.457 +    newtoken(p);
   9.458 +    p->state->delim = c;
   9.459 +  exit:
   9.460 +    return err;
   9.461 +}
   9.462 +
   9.463 +int state_string(Parser *p, char c){
   9.464 +    int err = 0;
   9.465 +    if(at_eof(p)){
   9.466 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
   9.467 +        err = -EINVAL;
   9.468 +    } else if(c == p->state->delim){
   9.469 +        err = end_string(p);
   9.470 +    } else if(c == '\\'){
   9.471 +        err = Parser_push(p, state_escape, "escape");
   9.472 +    } else {
   9.473 +        err = savechar(p, c);
   9.474 +    }
   9.475 +    return err;
   9.476 +}
   9.477 +
   9.478 +int end_string(Parser *p){
   9.479 +    int err = 0;
   9.480 +    err = do_string(p);
   9.481 +    if(err) goto exit;
   9.482 +    err = Parser_return(p);
   9.483 +  exit:
   9.484 +    return err;
   9.485 +}
   9.486 +
   9.487 +int state_escape(Parser *p, char c){
   9.488 +    int err = 0;
   9.489 +    char d;
   9.490 +    if(at_eof(p)){
   9.491 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
   9.492 +        err = -EINVAL;
   9.493 +        goto exit;
   9.494 +    }
   9.495 +    if(get_escape(c, &d) == 0){
   9.496 +        err = savechar(p, d);
   9.497 +        if(err) goto exit;
   9.498 +        err = Parser_pop(p);
   9.499 +    } else if(c == 'x'){
   9.500 +        p->state->fn = state_hex;
   9.501 +        p->state->ival = 0;
   9.502 +        p->state->count = 0;
   9.503 +    } else {
   9.504 +        p->state->fn = state_octal;
   9.505 +        p->state->ival = 0;
   9.506 +        p->state->count = 0;
   9.507 +        err = Parser_input_char(p, c);
   9.508 +    }
   9.509 +  exit:
   9.510 +    return err;
   9.511 +}
   9.512 +
   9.513 +int octaldone(Parser *p){
   9.514 +    int err = 0;
   9.515 +    char d = (char)(p->state->ival & 0xff);
   9.516 +    err = Parser_pop(p);
   9.517 +    if(err) goto exit;
   9.518 +    err = Parser_input_char(p, d);
   9.519 +  exit:
   9.520 +    return err;
   9.521 +}
   9.522 +
   9.523 +int octaldigit(Parser *p, char c){
   9.524 +    int err = 0;
   9.525 +    p->state->ival *= 8;
   9.526 +    p->state->ival += c - '0'; 
   9.527 +    p->state->count++;
   9.528 +    if(err) goto exit;
   9.529 +    if(p->state->ival < 0 || p->state->ival > 0xff){
   9.530 +        parse_error(p);
   9.531 +        err = -EINVAL;
   9.532 +        goto exit;
   9.533 +    }
   9.534 +    if(p->state->count == 3){
   9.535 +        err = octaldone(p);
   9.536 +    }
   9.537 +  exit:
   9.538 +    return err;
   9.539 +}
   9.540 +
   9.541 +int state_octal(Parser *p, char c){
   9.542 +    int err = 0;
   9.543 +    if(at_eof(p)){
   9.544 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
   9.545 +        err = -EINVAL;
   9.546 +        goto exit;
   9.547 +    } else if('0' <= c && c <= '7'){
   9.548 +        err = octaldigit(p, c);
   9.549 +    } else {
   9.550 +        err = octaldone(p);
   9.551 +        if(err) goto exit;
   9.552 +        Parser_input_char(p, c);
   9.553 +    }
   9.554 +  exit:
   9.555 +    return err;
   9.556 +}
   9.557 +
   9.558 +int hexdone(Parser *p){
   9.559 +    int err = 0;
   9.560 +    char d = (char)(p->state->ival & 0xff);
   9.561 +    err = Parser_pop(p);
   9.562 +    if(err) goto exit;
   9.563 +    err = Parser_input_char(p, d);
   9.564 +  exit:
   9.565 +    return err;
   9.566 +}
   9.567 +    
   9.568 +int hexdigit(Parser *p, char c, char d){
   9.569 +    int err = 0;
   9.570 +    p->state->ival *= 16;
   9.571 +    p->state->ival += c - d; 
   9.572 +    p->state->count++;
   9.573 +    if(err) goto exit;
   9.574 +    if(p->state->ival < 0 || p->state->ival > 0xff){
   9.575 +        parse_error(p);
   9.576 +        err = -EINVAL;
   9.577 +        goto exit;
   9.578 +    }
   9.579 +    if(p->state->count == 2){
   9.580 +        err = hexdone(p);
   9.581 +    }
   9.582 +  exit:
   9.583 +    return err;
   9.584 +}
   9.585 +    
   9.586 +int state_hex(Parser *p, char c){
   9.587 +    int err = 0;
   9.588 +    if(at_eof(p)){
   9.589 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
   9.590 +        err = -EINVAL;
   9.591 +        goto exit;
   9.592 +    } else if('0' <= c && c <= '9'){
   9.593 +        err = hexdigit(p, c, '0');
   9.594 +    } else if('A' <= c && c <= 'F'){
   9.595 +        err = hexdigit(p, c, 'A');
   9.596 +    } else if('a' <= c && c <= 'f'){
   9.597 +        err = hexdigit(p, c, 'a');
   9.598 +    } else if(p->state->count){
   9.599 +        err =hexdone(p);
   9.600 +        if(err) goto exit;
   9.601 +        Parser_input_char(p, c);
   9.602 +    }
   9.603 +  exit:
   9.604 +    return err;
   9.605 +}
   9.606 +
   9.607 +int begin_atom(Parser *p, char c){
   9.608 +    int err = 0;
   9.609 +    err = Parser_push(p, state_atom, "atom");
   9.610 +    if(err) goto exit;
   9.611 +    newtoken(p);
   9.612 +    err = savechar(p, c);
   9.613 +  exit:
   9.614 +    return err;
   9.615 +}
   9.616 +
   9.617 +int state_atom(Parser *p, char c){
   9.618 +    int err = 0;
   9.619 +    if(at_eof(p)){
   9.620 +        err = end_atom(p);
   9.621 +    } else if(is_separator(p, c) ||
   9.622 +              in_space_class(c) ||
   9.623 +              in_comment_class(c)){
   9.624 +        err = end_atom(p);
   9.625 +        if(err) goto exit;
   9.626 +        err = Parser_input_char(p, c);
   9.627 +    } else {
   9.628 +        err = savechar(p, c);
   9.629 +    }
   9.630 +  exit:
   9.631 +    return err;
   9.632 +}
   9.633 +
   9.634 +int end_atom(Parser *p){
   9.635 +    int err = 0;
   9.636 +    err = do_intern(p);
   9.637 +    if(err) goto exit;
   9.638 +    err = Parser_return(p);
   9.639 +  exit:
   9.640 +    return err;
   9.641 +}
   9.642 +
   9.643 +int state_list(Parser *p, char c){
   9.644 +    int err = 0;
   9.645 +    if(at_eof(p)){
   9.646 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
   9.647 +        err = -EINVAL;
   9.648 +    } else if(c == c_list_close){
   9.649 +        p->state->val = nrev(p->state->val);
   9.650 +        err = end_list(p);
   9.651 +    } else {
   9.652 +        err = state_start(p, c);
   9.653 +    }
   9.654 +    return err;
   9.655 +    
   9.656 +}
   9.657 +
   9.658 +int begin_list(Parser *p, char c){
   9.659 +    return Parser_push(p, state_list, "list");
   9.660 +}
   9.661 +
   9.662 +int end_list(Parser *p){
   9.663 +    return Parser_return(p);
   9.664 +}
   9.665 +
   9.666 +/** Reset the fields of a parser to initial values.
   9.667 + *
   9.668 + * @param z parser
   9.669 + */
   9.670 +static void reset(Parser *z){
   9.671 +  IOStream *error_out = z->error_out;
   9.672 +  int flags = z->flags;
   9.673 +  memzero(z, sizeof(Parser));
   9.674 +  z->buf_n = sizeof(z->buf) - 1;
   9.675 +  z->buf_i = 0;
   9.676 +  z->line_no = 1;
   9.677 +  z->char_no = 0;
   9.678 +  z->error_out = error_out;
   9.679 +  z->flags = flags;
   9.680 +}
   9.681 +
   9.682 +/** Set the parser error stream.
   9.683 + * Parse errors are reported on the the error stream if it is non-null.
   9.684 + * 
   9.685 + * @param z parser
   9.686 + * @param error_out error stream
   9.687 + */
   9.688 +void set_error_stream(Parser *z, IOStream *error_out){
   9.689 +  if(z){
   9.690 +    z->error_out = error_out;
   9.691 +  }
   9.692 +}
   9.693 +
   9.694 +/** Get the parser error message for an error code.
   9.695 + *
   9.696 + * @param id error code
   9.697 + * @return error message (empty string if the code is unknown)
   9.698 + */
   9.699 +static char *get_message(ParseErrorId id){
   9.700 +  int i;
   9.701 +  for(i=0; i<catalog_n; i++){
   9.702 +    if(id == catalog[i].id){
   9.703 +      return catalog[i].message;
   9.704 +    }
   9.705 +  }
   9.706 +  return "";
   9.707 +}
   9.708 +
   9.709 +/** Get the line number.
   9.710 + *
   9.711 + * @param in parser
   9.712 + */
   9.713 +int get_line(Parser *in){
   9.714 +  return in->line_no;
   9.715 +}
   9.716 +
   9.717 +/** Get the column number.
   9.718 + *
   9.719 + * @param in parser
   9.720 + */
   9.721 +int get_column(Parser *in){
   9.722 +  return in->char_no;
   9.723 +}
   9.724 +
   9.725 +/** Get the line number the current token started on.
   9.726 + *
   9.727 + * @param in parser
   9.728 + */
   9.729 +int get_tok_line(Parser *in){
   9.730 +  return in->tok_begin_line;
   9.731 +}
   9.732 +
   9.733 +/** Get the column number the current token started on.
   9.734 + *
   9.735 + * @param in parser
   9.736 + */
   9.737 +int get_tok_column(Parser *in){
   9.738 +  return in->tok_begin_char;
   9.739 +}
   9.740 +
   9.741 +/** Report a parse error.
   9.742 + * Does nothing if the error stream is null or there is no error.
   9.743 + *
   9.744 + * @param in parser
   9.745 + */
   9.746 +static void report_error(Parser *in){
   9.747 +  if(in->error_out && in->err){
   9.748 +    char *msg = get_message(in->err);
   9.749 +    char *tok = peek_token(in);
   9.750 +    IOStream_print(in->error_out, PARSE_ERR_FMT,
   9.751 +		   get_tok_line(in), get_tok_column(in), msg);
   9.752 +    if(tok && tok[0]){
   9.753 +        IOStream_print(in->error_out, " '%s'", tok);
   9.754 +    }
   9.755 +    IOStream_print(in->error_out, "\n");
   9.756 +  }
   9.757 +}
   9.758 +
   9.759 +/** Get the error message for the current parse error code.
   9.760 + * Does nothing if there is no error.
   9.761 + *
   9.762 + * @param in parser
   9.763 + * @param buf where to place the message
   9.764 + * @param n maximum number of characters to place in buf
   9.765 + * @return current error code (zero for no error)
   9.766 + */
   9.767 +int parse_error_message(Parser *in, char *buf, int n){
   9.768 +    if(in->err){
   9.769 +        char *msg = get_message(in->err);
   9.770 +        snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in), get_tok_column(in), msg);
   9.771 +    }
   9.772 +    return in->err;
   9.773 +}
   9.774 +
   9.775 +/** Flag an unspecified parse error. All subsequent reads will fail.
   9.776 + *
   9.777 + * @param in parser
   9.778 + */
   9.779 +void parse_error(Parser *in){
   9.780 +    parse_error_id(in, PARSE_ERR_INVALID_SYNTAX);
   9.781 +}
   9.782 +
   9.783 +/** Flag a parse error. All subsequent reads will fail.
   9.784 + * Does not change the parser error code if it is already set.
   9.785 + *
   9.786 + * @param in parser
   9.787 + * @param id error code
   9.788 + */
   9.789 +void parse_error_id(Parser *in, ParseErrorId id){
   9.790 +    if(!in->err){
   9.791 +        in->err = id;
   9.792 +        report_error(in);
   9.793 +    }
   9.794 +}
   9.795 +
   9.796 +/** Test if the parser's error flag is set.
   9.797 + *
   9.798 + * @param in parser
   9.799 + * @return 1 if set, 0 otherwise
   9.800 + */
   9.801 +int has_error(Parser *in){
   9.802 +    return (in->err > 0);
   9.803 +}
   9.804 +
   9.805 +/** Test if the parser is at end of input.
   9.806 + *
   9.807 + * @param in parser
   9.808 + * @return 1 if at EOF, 0 otherwise
   9.809 + */
   9.810 +int at_eof(Parser *p){
   9.811 +    return p->eof;
   9.812 +}
   9.813 +
   9.814 +//#define SXPR_PARSER_MAIN
   9.815 +#ifdef SXPR_PARSER_MAIN
   9.816 +/* Stuff for standalone testing. */
   9.817 +
   9.818 +#include "file_stream.h"
   9.819 +#include "string_stream.h"
   9.820 +
   9.821 +int stringof(Sxpr exp, char **s){
   9.822 +    int err = 0;
   9.823 +    if(ATOMP(exp)){
   9.824 +        *s = atom_name(exp);
   9.825 +    } else if(STRINGP(exp)){
   9.826 +        *s = string_string(exp);
   9.827 +    } else {
   9.828 +        err = -EINVAL;
   9.829 +        *s = NULL;
   9.830 +    }
   9.831 +    return err;
   9.832 +}
   9.833 +
   9.834 +int child_string(Sxpr exp, Sxpr key, char **s){
   9.835 +    int err = 0;
   9.836 +    Sxpr val = sxpr_child_value(exp, key, ONONE);
   9.837 +    err = stringof(val, s);
   9.838 +    return err;
   9.839 +}
   9.840 +
   9.841 +int intof(Sxpr exp, int *v){
   9.842 +    int err = 0;
   9.843 +    char *s;
   9.844 +    unsigned long l;
   9.845 +    if(INTP(exp)){
   9.846 +        *v = OBJ_INT(exp);
   9.847 +    } else {
   9.848 +        err = stringof(exp, &s);
   9.849 +        if(err) goto exit;
   9.850 +        err = convert_atoul(s, &l);
   9.851 +        *v = (int)l;
   9.852 +    }
   9.853 + exit:
   9.854 +    return err;
   9.855 +}
   9.856 +
   9.857 +int child_int(Sxpr exp, Sxpr key, int *v){
   9.858 +    int err = 0;
   9.859 +    Sxpr val = sxpr_child_value(exp, key, ONONE);
   9.860 +    err = intof(val, v);
   9.861 +    return err;
   9.862 +}
   9.863 +
   9.864 +int eval_vnet(Sxpr exp){
   9.865 +    int err = 0;
   9.866 +    Sxpr oid = intern("id");
   9.867 +    int id;
   9.868 +    err = child_int(exp, oid, &id);
   9.869 +    if(err) goto exit;
   9.870 +    dprintf("> vnet id=%d\n", id);
   9.871 + exit:
   9.872 +    dprintf("< err=%d\n", err);
   9.873 +    return err;
   9.874 +}
   9.875 +
   9.876 +int eval_connect(Sxpr exp){
   9.877 +    int err = 0;
   9.878 +    Sxpr ovif = intern("vif");
   9.879 +    Sxpr ovnet = intern("vnet");
   9.880 +    char *vif;
   9.881 +    int vnet;
   9.882 +
   9.883 +    err = child_string(exp, ovif, &vif);
   9.884 +    if(err) goto exit;
   9.885 +    err = child_int(exp, ovnet, &vnet);
   9.886 +    if(err) goto exit;
   9.887 +    dprintf("> connect vif=%s vnet=%d\n", vif, vnet);
   9.888 + exit:
   9.889 +    dprintf("< err=%d\n", err);
   9.890 +    return err;
   9.891 +}
   9.892 +
   9.893 +int eval(Sxpr exp){
   9.894 +    int err = 0;
   9.895 +    Sxpr oconnect = intern("connect");
   9.896 +    Sxpr ovnet = intern("vnet");
   9.897 +    
   9.898 +    if(sxpr_elementp(exp, ovnet)){
   9.899 +        err = eval_vnet(exp);
   9.900 +    } else if(sxpr_elementp(exp, oconnect)){
   9.901 +        err = eval_connect(exp);
   9.902 +    } else {
   9.903 +        err = -EINVAL;
   9.904 +    }
   9.905 +    return err;
   9.906 +}
   9.907 +
   9.908 +/** Main program for testing.
   9.909 + * Parses input and prints it.
   9.910 + *
   9.911 + * @param argc number of arguments
   9.912 + * @param argv arguments
   9.913 + * @return error code
   9.914 + */
   9.915 +int main(int argc, char *argv[]){
   9.916 +    Parser *pin;
   9.917 +    int err = 0;
   9.918 +    char buf[1024];
   9.919 +    int k;
   9.920 +    Sxpr obj;
   9.921 +    //Sxpr l, x;
   9.922 +    int i = 0;
   9.923 +
   9.924 +    pin = Parser_new();
   9.925 +    set_error_stream(pin, iostdout);
   9.926 +    dprintf("> parse...\n");
   9.927 +    while(1){
   9.928 +        k = fread(buf, 1, 1, stdin);
   9.929 +        err = Parser_input(pin, buf, k);
   9.930 +        while(Parser_ready(pin)){
   9.931 +            obj = Parser_get_val(pin);
   9.932 +            printf("obj %d\n", i++);
   9.933 +            objprint(iostdout, obj, 0); printf("\n");
   9.934 +        }
   9.935 +        if(k <= 0) break;
   9.936 +    }
   9.937 +/*     obj = Parser_get_all(pin); */
   9.938 +/*     for(l = obj ; CONSP(l); l = CDR(l)){ */
   9.939 +/*         x = CAR(l); */
   9.940 +/*         objprint(iostdout, x, 0); printf("\n"); */
   9.941 +/*         eval(x); */
   9.942 +/*     } */
   9.943 +    dprintf("> err=%d\n", err);
   9.944 +    return 0;
   9.945 +}
   9.946 +#endif
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/xfrd/sxpr_parser.h	Wed Jul 07 15:59:16 2004 +0000
    10.3 @@ -0,0 +1,133 @@
    10.4 +/*
    10.5 + *
    10.6 + * This library is free software; you can redistribute it and/or modify
    10.7 + * it under the terms of the GNU Lesser General Public License as
    10.8 + * published by the Free Software Foundation; either version 2.1 of the
    10.9 + * License, or  (at your option) any later version. This library is 
   10.10 + * distributed in the  hope that it will be useful, but WITHOUT ANY
   10.11 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.12 + * FITNESS FOR A PARTICULAR PURPOSE.
   10.13 + * See the GNU Lesser General Public License for more details.
   10.14 + *
   10.15 + * You should have received a copy of the GNU Lesser General Public License
   10.16 + * along with this library; if not, write to the Free Software Foundation,
   10.17 + * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   10.18 + */
   10.19 +
   10.20 +#ifndef _XUTIL_SXPR_PARSER_H_
   10.21 +#define _XUTIL_SXPR_PARSER_H_
   10.22 +
   10.23 +#include "sxpr.h"
   10.24 +#include "iostream.h"
   10.25 +
   10.26 +/** @file
   10.27 + * Sxpr parsing definitions.
   10.28 + */
   10.29 +
   10.30 +/** Size of a parser input buffer.
   10.31 + * Tokens read must fit into this size (including trailing null).
   10.32 + */
   10.33 +#define PARSER_BUF_SIZE 1024
   10.34 +
   10.35 +struct Parser;
   10.36 +typedef int ParserStateFn(struct Parser *, char c);
   10.37 +
   10.38 +typedef struct ParserState {
   10.39 +    struct ParserState *parent;
   10.40 +    Sxpr val;
   10.41 +    int ival;
   10.42 +    int count;
   10.43 +    char delim;
   10.44 +    ParserStateFn *fn;
   10.45 +    char *name;
   10.46 +} ParserState;
   10.47 +
   10.48 +/** Structure representing an input source for the parser.
   10.49 + * Can read from any IOStream implementation.
   10.50 + */
   10.51 +typedef struct Parser {
   10.52 +    Sxpr val;
   10.53 +    /** Error reporting stream (null for no reports). */
   10.54 +    IOStream *error_out;
   10.55 +    int eof;
   10.56 +    /** Error flag. Non-zero if there has been a read error. */
   10.57 +    int err;
   10.58 +    /** Line number on input (from 1). */
   10.59 +    int line_no;
   10.60 +    /** Column number of input (reset on new line). */
   10.61 +    int char_no;
   10.62 +    /** Lookahead character. */
   10.63 +    char c;
   10.64 +    /** Buffer for reading tokens. */
   10.65 +    char buf[PARSER_BUF_SIZE];
   10.66 +    /** Size of token buffer. */
   10.67 +    int buf_n;
   10.68 +    int buf_i;
   10.69 +    /** Line the last token started on. */
   10.70 +    int tok_begin_line;
   10.71 +    /** Character number the last token started on. */
   10.72 +    int tok_begin_char;
   10.73 +    /** Parsing flags. */
   10.74 +    int flags;
   10.75 +    ParserState *state;
   10.76 +    ParserState *start_state;
   10.77 +} Parser;
   10.78 +
   10.79 +/** Parser error codes. */
   10.80 +typedef enum {
   10.81 +    PARSE_ERR_NONE=0,
   10.82 +    PARSE_ERR_UNSPECIFIED,
   10.83 +    PARSE_ERR_NOMEM,
   10.84 +    PARSE_ERR_UNEXPECTED_EOF,
   10.85 +    PARSE_ERR_TOKEN_TOO_LONG,
   10.86 +    PARSE_ERR_INVALID_SYNTAX,
   10.87 +    PARSE_ERR_INVALID_ESCAPE,
   10.88 +} ParseErrorId;
   10.89 +
   10.90 +
   10.91 +/** Parser flags. */
   10.92 +//enum {
   10.93 +//};
   10.94 +
   10.95 +/** Raise some parser flags.
   10.96 + *
   10.97 + * @param in parser
   10.98 + * @param flags flags mask
   10.99 + */
  10.100 +inline static void parser_flags_raise(Parser *in, int flags){
  10.101 +    in->flags |= flags;
  10.102 +}
  10.103 +
  10.104 +/** Lower some parser flags.
  10.105 + *
  10.106 + * @param in parser
  10.107 + * @param flags flags mask
  10.108 + */
  10.109 +inline static void parser_flags_lower(Parser *in, int flags){
  10.110 +    in->flags &= ~flags;
  10.111 +}
  10.112 +
  10.113 +/** Clear all parser flags.
  10.114 + *
  10.115 + * @param in parser
  10.116 + */
  10.117 +inline static void parser_flags_clear(Parser *in){
  10.118 +    in->flags = 0;
  10.119 +}
  10.120 +
  10.121 +extern void Parser_free(Parser *z);
  10.122 +extern Parser * Parser_new(void);
  10.123 +extern int Parser_input(Parser *p, char *buf, int buf_n);
  10.124 +extern int Parser_input_eof(Parser *p);
  10.125 +extern int Parser_input_char(Parser *p, char c);
  10.126 +extern void set_error_stream(Parser *z, IOStream *error_out);
  10.127 +
  10.128 +extern int parse_error_message(Parser *in, char *buf, int n);
  10.129 +extern int has_error(Parser *in);
  10.130 +extern int at_eof(Parser *in);
  10.131 +
  10.132 +int Parser_ready(Parser *p);
  10.133 +Sxpr Parser_get_val(Parser *p);
  10.134 +Sxpr Parser_get_all(Parser *p);
  10.135 +
  10.136 +#endif /* ! _XUTIL_SXPR_PARSER_H_ */
    11.1 --- a/tools/xfrd/xen_domain.c	Wed Jul 07 13:07:37 2004 +0000
    11.2 +++ b/tools/xfrd/xen_domain.c	Wed Jul 07 15:59:16 2004 +0000
    11.3 @@ -38,7 +38,7 @@ int xen_domain_snd(Conn *xend, IOStream 
    11.4          if(d > buf_n) d = buf_n;
    11.5          err = marshal_bytes(io, buf, d);
    11.6          if(err) goto exit;
    11.7 -        //dprintf("> k=%d n=%d\n", k, n);
    11.8 +        dprintf("> k=%d n=%d\n", k, n);
    11.9      }
   11.10      
   11.11    exit:
   11.12 @@ -68,7 +68,7 @@ int xen_domain_rcv(IOStream *io, uint32_
   11.13          if(d > buf_n) d = buf_n;
   11.14          err = unmarshal_bytes(io, buf, d);
   11.15          if(err) goto exit;
   11.16 -        //dprintf("> k=%d n=%d\n", k, n);
   11.17 +        dprintf("> k=%d n=%d\n", k, n);
   11.18      }
   11.19    exit:
   11.20  #else    
    12.1 --- a/tools/xfrd/xfrd.c	Wed Jul 07 13:07:37 2004 +0000
    12.2 +++ b/tools/xfrd/xfrd.c	Wed Jul 07 15:59:16 2004 +0000
    12.3 @@ -36,7 +36,7 @@
    12.4  #include "sys_net.h"
    12.5  #include "sys_string.h"
    12.6  
    12.7 -#include "xdr.h"
    12.8 +//#include "xdr.h"
    12.9  #include "enum.h"
   12.10  #include "xfrd.h"
   12.11  
   12.12 @@ -362,10 +362,10 @@ int addrof(Sxpr exp, uint32_t *v){
   12.13      err = stringof(exp, &h);
   12.14      if(err) goto exit;
   12.15      if(get_host_address(h, &a)){
   12.16 -        *v = a;
   12.17 -    } else {
   12.18          err = -EINVAL;
   12.19 +        goto exit;
   12.20      }
   12.21 +    *v = a;
   12.22    exit:
   12.23      dprintf("< err=%d v=%x\n", err, *v);
   12.24      return err;
   12.25 @@ -383,11 +383,12 @@ int portof(Sxpr exp, uint16_t *v){
   12.26          unsigned long p;
   12.27          err = stringof(exp, &s);
   12.28          if(err) goto exit;
   12.29 -        if(get_service_port(s, &p)){
   12.30 -            *v = p;
   12.31 -        } else {
   12.32 +        err = convert_service_to_port(s, &p);
   12.33 +        if(err){
   12.34              err = -EINVAL;
   12.35 +            goto exit;
   12.36          }
   12.37 +        *v = p;
   12.38      }
   12.39    exit:
   12.40      dprintf("< err=%d v=%u\n", err, *v);
   12.41 @@ -414,20 +415,12 @@ time_t stats(time_t t0, uint64_t offset,
   12.42   */
   12.43  int xfr_error(Conn *conn, int errcode){
   12.44      int err = 0;
   12.45 +
   12.46      if(!conn->out) return -ENOTCONN;
   12.47 -    err = pack_type(conn->out, T_CONS);
   12.48 -    if(err) goto exit;
   12.49 -    err = pack_bool(conn->out, 1);
   12.50 -    if(err) goto exit;
   12.51 -    err = pack_sxpr(conn->out, oxfr_err);
   12.52 -    if(err) goto exit;
   12.53 -    err = pack_bool(conn->out, 1);
   12.54 -    if(err) goto exit;
   12.55 -    err = pack_sxpr(conn->out, mkint(errcode));
   12.56 -    if(err) goto exit;
   12.57 -    err = pack_bool(conn->out, 0);
   12.58 -  exit:
   12.59 -    return err;
   12.60 +    if(errcode <0) errcode = -errcode;
   12.61 +    err = IOStream_print(conn->out, "(%s %d)",
   12.62 +                         atom_name(oxfr_err), errcode);
   12.63 +    return (err < 0 ? err : 0);
   12.64  }
   12.65  
   12.66  /** Read a response message - error or ok.
   12.67 @@ -441,7 +434,7 @@ int xfr_response(Conn *conn){
   12.68  
   12.69      dprintf(">\n");
   12.70      if(!conn->out) return -ENOTCONN;
   12.71 -    err = unpack_sxpr(conn->in, &sxpr);
   12.72 +    err = Conn_sxpr(conn, &sxpr);
   12.73      if(err) goto exit;
   12.74      if(sxpr_elementp(sxpr, oxfr_err)){
   12.75          int errcode;
   12.76 @@ -468,7 +461,7 @@ int xfr_hello(Conn *conn){
   12.77      Sxpr sxpr;
   12.78      if(!conn->in) return -ENOTCONN;
   12.79      dprintf(">\n");
   12.80 -    err = unpack_sxpr(conn->in, &sxpr);
   12.81 +    err = Conn_sxpr(conn, &sxpr);
   12.82      if(err) goto exit;
   12.83      if(!sxpr_elementp(sxpr, oxfr_hello)){
   12.84          dprintf("> sxpr_elementp test failed\n");
   12.85 @@ -503,21 +496,12 @@ int xfr_hello(Conn *conn){
   12.86  int xfr_send_hello(Conn *conn){
   12.87      int err = 0;
   12.88      dprintf(">\n");
   12.89 -    err = pack_type(conn->out, T_CONS);
   12.90 -    if(err) goto exit;
   12.91 -    err = pack_bool(conn->out, 1);
   12.92 -    if(err) goto exit;
   12.93 -    err = pack_sxpr(conn->out, oxfr_hello);
   12.94 -    if(err) goto exit;
   12.95 -    err = pack_bool(conn->out, 1);
   12.96 -    if(err) goto exit;
   12.97 -    err = pack_sxpr(conn->out, mkint(XFR_PROTO_MAJOR));
   12.98 -    if(err) goto exit;
   12.99 -    err = pack_bool(conn->out, 1);
  12.100 -    if(err) goto exit;
  12.101 -    err = pack_sxpr(conn->out, mkint(XFR_PROTO_MINOR));
  12.102 -    if(err) goto exit;
  12.103 -    err = pack_bool(conn->out, 0);
  12.104 +
  12.105 +    err = IOStream_print(conn->out, "(%s %d %d)",
  12.106 +                         atom_name(oxfr_hello),
  12.107 +                         XFR_PROTO_MAJOR,
  12.108 +                         XFR_PROTO_MINOR);
  12.109 +    if(err < 0) goto exit;
  12.110      IOStream_flush(conn->out);
  12.111      dprintf("> xfr_response...\n");
  12.112      err = xfr_response(conn);
  12.113 @@ -528,55 +512,26 @@ int xfr_send_hello(Conn *conn){
  12.114  
  12.115  int xfr_send_xfr(Conn *conn, uint32_t vmid){
  12.116      int err;
  12.117 -    err = pack_type(conn->out, T_CONS);
  12.118 -    if(err) goto exit;
  12.119 -    err = pack_bool(conn->out, 1);
  12.120 -    if(err) goto exit;
  12.121 -    err = pack_sxpr(conn->out, oxfr_xfr);
  12.122 -    if(err) goto exit;
  12.123 -    err = pack_bool(conn->out, 1);
  12.124 -    if(err) goto exit;
  12.125 -    err = pack_sxpr(conn->out, mkint(vmid));
  12.126 -    if(err) goto exit;
  12.127 -    err = pack_bool(conn->out, 0);
  12.128 -    if(err) goto exit;
  12.129 -  exit:
  12.130 -    return err;
  12.131 +
  12.132 +    err = IOStream_print(conn->out, "(%s %d)",
  12.133 +                         atom_name(oxfr_xfr), vmid);
  12.134 +    return (err < 0 ? err : 0);
  12.135  }
  12.136  
  12.137  int xfr_send_ok(Conn *conn, uint32_t vmid){
  12.138      int err = 0;
  12.139 -    err = pack_type(conn->out, T_CONS);
  12.140 -    if(err) goto exit;
  12.141 -    err = pack_bool(conn->out, 1);
  12.142 -    if(err) goto exit;
  12.143 -    err = pack_sxpr(conn->out, oxfr_ok);
  12.144 -    if(err) goto exit;
  12.145 -    err = pack_bool(conn->out, 1);
  12.146 -    if(err) goto exit;
  12.147 -    err = pack_sxpr(conn->out, mkint(vmid));
  12.148 -    if(err) goto exit;
  12.149 -    err = pack_bool(conn->out, 0);
  12.150 -  exit:
  12.151 -    return err;
  12.152 +
  12.153 +    err = IOStream_print(conn->out, "(%s %d)",
  12.154 +                         atom_name(oxfr_ok), vmid);
  12.155 +    return (err < 0 ? err : 0);
  12.156  }
  12.157  
  12.158  int xfr_send_suspend(Conn *conn, uint32_t vmid){
  12.159      int err = 0;
  12.160  
  12.161 -    err = pack_type(conn->out, T_CONS);
  12.162 -    if(err) goto exit;
  12.163 -    err = pack_bool(conn->out, 1);
  12.164 -    if(err) goto exit;
  12.165 -    err = pack_sxpr(conn->out, oxfr_suspend);
  12.166 -    if(err) goto exit;
  12.167 -    err = pack_bool(conn->out, 1);
  12.168 -    if(err) goto exit;
  12.169 -    err = pack_sxpr(conn->out, mkint(vmid));
  12.170 -    if(err) goto exit;
  12.171 -    err = pack_bool(conn->out, 0);
  12.172 -  exit:
  12.173 -    return err;
  12.174 +    err = IOStream_print(conn->out, "(%s %d)",
  12.175 +                         atom_name(oxfr_suspend), vmid);
  12.176 +    return (err < 0 ? err : 0);
  12.177  }
  12.178  
  12.179  /** Get vm state. Send transfer message.
  12.180 @@ -594,11 +549,12 @@ int xfr_send_state(XfrState *state, Conn
  12.181      // Send xfr message and the domain state.
  12.182      err = xfr_send_xfr(peer, state->vmid);
  12.183      if(err) goto exit;
  12.184 -    err = xen_domain_snd(xend, peer->out, state->vmid, state->vmconfig, state->vmconfig_n);
  12.185 +    err = xen_domain_snd(xend, peer->out,
  12.186 +                         state->vmid, state->vmconfig, state->vmconfig_n);
  12.187      if(err) goto exit;
  12.188      IOStream_flush(peer->out);
  12.189      // Read the response from the peer.
  12.190 -    err = unpack_sxpr(peer->in, &sxpr);
  12.191 +    err = Conn_sxpr(peer, &sxpr);
  12.192      if(err) goto exit;
  12.193      if(sxpr_elementp(sxpr, oxfr_err)){
  12.194          // Error.
  12.195 @@ -785,10 +741,14 @@ int xfrd_service(Args *args, int peersoc
  12.196      dprintf(">\n");
  12.197      err = Conn_init(conn, flags, peersock, peer_in);
  12.198      if(err) goto exit;
  12.199 +    dprintf(">xfr_hello... \n");
  12.200      err = xfr_hello(conn);
  12.201      if(err) goto exit;
  12.202 -    err = unpack_sxpr(conn->in, &sxpr);
  12.203 +    dprintf("> sxpr...\n");
  12.204 +    err = Conn_sxpr(conn, &sxpr);
  12.205      if(err) goto exit;
  12.206 +    dprintf("> sxpr=\n");
  12.207 +    objprint(iostdout, sxpr, PRINT_TYPE); IOStream_print(iostdout, "\n");
  12.208      if(sxpr_elementp(sxpr, oxfr_migrate)){
  12.209          // Migrate message from xend.
  12.210          uint32_t addr;
    13.1 --- a/tools/xfrd/xfrdClient.py	Wed Jul 07 13:07:37 2004 +0000
    13.2 +++ b/tools/xfrd/xfrdClient.py	Wed Jul 07 15:59:16 2004 +0000
    13.3 @@ -34,13 +34,11 @@ class TCPClient:
    13.4          
    13.5          self.sockin = self.sock.makefile("r")
    13.6          self.sockout = self.sock.makefile("w")
    13.7 -        self.packer = SxpPacker(self.sockout)
    13.8 -        self.unpacker = SxpUnpacker(self.sockin)
    13.9          #pass
   13.10  
   13.11      def request(self, req):
   13.12          print "request>", req
   13.13 -        self.packer.pack(req)
   13.14 +        sxp.show(req, out=self.sockout)
   13.15          self.sockout.flush()
   13.16          print "request<"
   13.17  
   13.18 @@ -52,10 +50,10 @@ class TCPClient:
   13.19  
   13.20      def read(self):
   13.21          while(1):
   13.22 -            v = self.unpacker.unpack()
   13.23 +            v = self.sockin.read()
   13.24              print 'read>', v
   13.25 -            if v[0] == 'xfr.err' and v[1]: return
   13.26 -            if v[0] == 'xfr.ok': return
   13.27 +            #if v[0] == 'xfr.err' and v[1]: return
   13.28 +            #if v[0] == 'xfr.ok': return
   13.29  
   13.30  XFR_PROTO_MAJOR = 1
   13.31  XFR_PROTO_MINOR = 0