debuggers.hg
changeset 4943:7f7c68433c4c
bitkeeper revision 1.1403 (4284c2edzLTGTr4gHmGzYsZMuetTRQ)
Switch to using unix-domain interface on xend instead
of http via libcurl.
Sundry other merges and fixes.
Signed-off-by: Mike Wray <mike.wray@hp.com>
Switch to using unix-domain interface on xend instead
of http via libcurl.
Sundry other merges and fixes.
Signed-off-by: Mike Wray <mike.wray@hp.com>
author | mjw@wray-m-3.hpl.hp.com |
---|---|
date | Fri May 13 15:08:29 2005 +0000 (2005-05-13) |
parents | 940a73d4b2a6 |
children | 69bd3136c3b7 |
files | .rootkeys tools/libxutil/fd_stream.c tools/libxutil/fd_stream.h tools/libxutil/lexis.h tools/libxutil/sxpr.c tools/libxutil/sxpr.h tools/libxutil/sxpr_parser.c tools/libxutil/sxpr_parser.h tools/libxutil/sys_string.c tools/libxutil/sys_string.h tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/event.py tools/xfrd/Make.xfrd tools/xfrd/Makefile tools/xfrd/connection.c tools/xfrd/lzi_stream.c tools/xfrd/xen_domain.c tools/xfrd/xfrd.c |
line diff
1.1 --- a/.rootkeys Fri May 13 15:01:20 2005 +0000 1.2 +++ b/.rootkeys Fri May 13 15:08:29 2005 +0000 1.3 @@ -754,6 +754,8 @@ 40e03332KYz7o1bn2MG_KPbBlyoIMA tools/lib 1.4 41a216cav5JJbtDQnusfuMa_1x_Xpw tools/libxutil/debug.h 1.5 40e9808eyjiahG5uF6AMelNVujBzCg tools/libxutil/enum.c 1.6 40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/libxutil/enum.h 1.7 +4284c2ecWyadIhHF1u_QSgWqIXkaLA tools/libxutil/fd_stream.c 1.8 +4284c2ecEOOcF6fZUf_NsZzYAoNo-w tools/libxutil/fd_stream.h 1.9 40e03332p5Dc_owJQRuN72ymJZddFQ tools/libxutil/file_stream.c 1.10 40e03332jWfB2viAhLSkq1WK0r_iDQ tools/libxutil/file_stream.h 1.11 40e03332rUjNMGg11n2rN6V4DCrvOg tools/libxutil/gzip_stream.c
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tools/libxutil/fd_stream.c Fri May 13 15:08:29 2005 +0000 2.3 @@ -0,0 +1,184 @@ 2.4 +/* 2.5 + * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 2.6 + * 2.7 + * This library is free software; you can redistribute it and/or modify 2.8 + * it under the terms of the GNU Lesser General Public License as published by 2.9 + * the Free Software Foundation; either version 2.1 of the License, or 2.10 + * (at your option) any later version. 2.11 + * 2.12 + * This library is distributed in the hope that it will be useful, 2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.15 + * GNU Lesser General Public License for more details. 2.16 + * 2.17 + * You should have received a copy of the GNU Lesser General Public License 2.18 + * along with this library; if not, write to the Free Software 2.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2.20 + */ 2.21 + 2.22 +/** @file 2.23 + * An IOStream implementation using fds. 2.24 + */ 2.25 +#ifndef __KERNEL__ 2.26 + 2.27 +#include <stdio.h> 2.28 +#include <stdlib.h> 2.29 +#include <string.h> 2.30 +#include <unistd.h> 2.31 +#include <errno.h> 2.32 +#include "allocate.h" 2.33 +#include "fd_stream.h" 2.34 + 2.35 +#define MODULE_NAME "fd_stream" 2.36 +#define DEBUG 1 2.37 +//#undef DEBUG 2.38 +#include "debug.h" 2.39 + 2.40 +static int fd_read(IOStream *s, void *buf, size_t n); 2.41 +static int fd_write(IOStream *s, const void *buf, size_t n); 2.42 +static int fd_error(IOStream *s); 2.43 +static int fd_close(IOStream *s); 2.44 +static void fd_free(IOStream *s); 2.45 +static int fd_flush(IOStream *s); 2.46 + 2.47 +/** Methods used by a fd IOStream. */ 2.48 +static const IOMethods fd_methods = { 2.49 + read: fd_read, 2.50 + write: fd_write, 2.51 + error: fd_error, 2.52 + close: fd_close, 2.53 + free: fd_free, 2.54 + flush: fd_flush, 2.55 +}; 2.56 + 2.57 +/** Get the fd data. 2.58 + * 2.59 + * @param io fd stream 2.60 + * @return data 2.61 + */ 2.62 +static inline FDData * fd_data(IOStream *io){ 2.63 + return (FDData *)io->data; 2.64 +} 2.65 + 2.66 +/** Test if a stream is a fd stream. 2.67 + * 2.68 + * @param io stream 2.69 + * @return 0 if a fd stream, -EINVAL if not 2.70 + */ 2.71 +int fd_stream_check(IOStream *io){ 2.72 + return (io && io->methods == &fd_methods ? 0 : -EINVAL); 2.73 +} 2.74 + 2.75 +/** Get the data for a fd stream. 2.76 + * 2.77 + * @param io stream 2.78 + * @param data return value for the data 2.79 + * @return 0 if a fd stream, -EINVAL if not 2.80 + */ 2.81 +int fd_stream_data(IOStream *io, FDData **data){ 2.82 + int err = fd_stream_check(io); 2.83 + if(err){ 2.84 + *data = NULL; 2.85 + } else { 2.86 + *data = fd_data(io); 2.87 + } 2.88 + return err; 2.89 +} 2.90 + 2.91 + 2.92 +/** Write to the underlying fd. 2.93 + * 2.94 + * @param stream input 2.95 + * @param buf where to put input 2.96 + * @param n number of bytes to write 2.97 + * @return number of bytes written 2.98 + */ 2.99 +static int fd_write(IOStream *s, const void *buf, size_t n){ 2.100 + FDData *data = fd_data(s); 2.101 + int k; 2.102 + k = write(data->fd, buf, n); 2.103 + return k; 2.104 +} 2.105 + 2.106 +/** Read from the underlying stream; 2.107 + * 2.108 + * @param stream input 2.109 + * @param buf where to put input 2.110 + * @param n number of bytes to read 2.111 + * @return number of bytes read 2.112 + */ 2.113 +static int fd_read(IOStream *s, void *buf, size_t n){ 2.114 + FDData *data = fd_data(s); 2.115 + int k; 2.116 + k = read(data->fd, buf, n); 2.117 + //printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k); 2.118 + return k; 2.119 +} 2.120 + 2.121 +/** Flush the fd (no-op). 2.122 + * 2.123 + * @param s fd stream 2.124 + * @return 0 on success, error code otherwise 2.125 + */ 2.126 +static int fd_flush(IOStream *s){ 2.127 + return 0; 2.128 +} 2.129 + 2.130 +/** Check if a fd stream has an error (no-op). 2.131 + * 2.132 + * @param s fd stream 2.133 + * @return 1 if has an error, 0 otherwise 2.134 + */ 2.135 +static int fd_error(IOStream *s){ 2.136 + return 0; 2.137 +} 2.138 + 2.139 +/** Close a fd stream. 2.140 + * 2.141 + * @param s fd stream to close 2.142 + * @return result of the close 2.143 + */ 2.144 +static int fd_close(IOStream *s){ 2.145 + FDData *data = fd_data(s); 2.146 + return close(data->fd); 2.147 +} 2.148 + 2.149 +/** Free a fd stream. 2.150 + * 2.151 + * @param s fd stream 2.152 + */ 2.153 +static void fd_free(IOStream *s){ 2.154 + FDData *data = fd_data(s); 2.155 + deallocate(data); 2.156 +} 2.157 + 2.158 +/** Create an IOStream for a fd. 2.159 + * 2.160 + * @param fd fd to wtap 2.161 + * @return new IOStream using fd for i/o 2.162 + */ 2.163 +IOStream *fd_stream_new(int fd){ 2.164 + int err = -ENOMEM; 2.165 + IOStream *io = NULL; 2.166 + FDData *data = NULL; 2.167 + 2.168 + io = ALLOCATE(IOStream); 2.169 + if(!io) goto exit; 2.170 + io->methods = &fd_methods; 2.171 + data = ALLOCATE(FDData); 2.172 + if(!data) goto exit; 2.173 + io->data = data; 2.174 + data->fd = fd; 2.175 + err = 0; 2.176 + exit: 2.177 + if(err){ 2.178 + if(io){ 2.179 + if(data) deallocate(data); 2.180 + deallocate(io); 2.181 + io = NULL; 2.182 + } 2.183 + } 2.184 + return io; 2.185 +} 2.186 + 2.187 +#endif
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/libxutil/fd_stream.h Fri May 13 15:08:29 2005 +0000 3.3 @@ -0,0 +1,36 @@ 3.4 +/* 3.5 + * Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 3.6 + * 3.7 + * This library is free software; you can redistribute it and/or modify 3.8 + * it under the terms of the GNU Lesser General Public License as published by 3.9 + * the Free Software Foundation; either version 2.1 of the License, or 3.10 + * (at your option) any later version. 3.11 + * 3.12 + * This library is distributed in the hope that it will be useful, 3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3.15 + * GNU Lesser General Public License for more details. 3.16 + * 3.17 + * You should have received a copy of the GNU Lesser General Public License 3.18 + * along with this library; if not, write to the Free Software 3.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 3.20 + */ 3.21 + 3.22 +#ifndef _XMC_FD_STREAM_H_ 3.23 +#define _XMC_FD_STREAM_H_ 3.24 + 3.25 +#ifndef __KERNEL__ 3.26 +#include "iostream.h" 3.27 + 3.28 +/** Data associated with a fd stream. */ 3.29 +typedef struct FDData { 3.30 + /** The socket file descriptor. */ 3.31 + int fd; 3.32 +} FDData; 3.33 + 3.34 +extern IOStream *fd_stream_new(int fd); 3.35 +extern int fd_stream_data(IOStream *io, FDData **data); 3.36 +extern int fd_stream_check(IOStream *io); 3.37 + 3.38 +#endif 3.39 +#endif /* !_XMC_FD_STREAM_H_ */
4.1 --- a/tools/libxutil/lexis.h Fri May 13 15:01:20 2005 +0000 4.2 +++ b/tools/libxutil/lexis.h Fri May 13 15:08:29 2005 +0000 4.3 @@ -34,7 +34,7 @@ 4.4 #define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 }) 4.5 4.6 /** Class of separator characters. */ 4.7 -#define sep_class "{}()<>[]@!;" 4.8 +#define sep_class "{}()<>[]!;\"'" 4.9 4.10 #define comment_class "#" 4.11
5.1 --- a/tools/libxutil/sxpr.c Fri May 13 15:01:20 2005 +0000 5.2 +++ b/tools/libxutil/sxpr.c Fri May 13 15:08:29 2005 +0000 5.3 @@ -28,6 +28,19 @@ 5.4 #include <errno.h> 5.5 #endif 5.6 5.7 +#ifdef __KERNEL__ 5.8 +#include <linux/random.h> 5.9 + 5.10 +int rand(void){ 5.11 + int v; 5.12 + get_random_bytes(&v, sizeof(v)); 5.13 + return v; 5.14 +} 5.15 + 5.16 +#else 5.17 +#include <stdlib.h> 5.18 +#endif 5.19 + 5.20 #undef free 5.21 5.22 /** @file 5.23 @@ -42,41 +55,51 @@ 5.24 static int atom_print(IOStream *io, Sxpr obj, unsigned flags); 5.25 static int atom_equal(Sxpr x, Sxpr y); 5.26 static void atom_free(Sxpr obj); 5.27 +static Sxpr atom_copy(Sxpr obj); 5.28 5.29 static int string_print(IOStream *io, Sxpr obj, unsigned flags); 5.30 static int string_equal(Sxpr x, Sxpr y); 5.31 static void string_free(Sxpr obj); 5.32 +static Sxpr string_copy(Sxpr obj); 5.33 5.34 static int cons_print(IOStream *io, Sxpr obj, unsigned flags); 5.35 static int cons_equal(Sxpr x, Sxpr y); 5.36 static void cons_free(Sxpr obj); 5.37 +static Sxpr cons_copy(Sxpr obj); 5.38 5.39 static int null_print(IOStream *io, Sxpr obj, unsigned flags); 5.40 static int none_print(IOStream *io, Sxpr obj, unsigned flags); 5.41 static int int_print(IOStream *io, Sxpr obj, unsigned flags); 5.42 static int bool_print(IOStream *io, Sxpr obj, unsigned flags); 5.43 +static int err_print(IOStream *io, Sxpr obj, unsigned flags); 5.44 +static int nomem_print(IOStream *io, Sxpr obj, unsigned flags); 5.45 5.46 /** Type definitions. */ 5.47 static SxprType types[1024] = { 5.48 - [T_NONE] { type: T_NONE, name: "none", print: none_print }, 5.49 - [T_NULL] { type: T_NULL, name: "null", print: null_print }, 5.50 - [T_UINT] { type: T_UINT, name: "int", print: int_print, }, 5.51 - [T_BOOL] { type: T_BOOL, name: "bool", print: bool_print, }, 5.52 - [T_ATOM] { type: T_ATOM, name: "atom", print: atom_print, 5.53 - pointer: TRUE, 5.54 - free: atom_free, 5.55 - equal: atom_equal, 5.56 - }, 5.57 - [T_STRING] { type: T_STRING, name: "string", print: string_print, 5.58 - pointer: TRUE, 5.59 - free: string_free, 5.60 - equal: string_equal, 5.61 - }, 5.62 - [T_CONS] { type: T_CONS, name: "cons", print: cons_print, 5.63 - pointer: TRUE, 5.64 - free: cons_free, 5.65 - equal: cons_equal, 5.66 - }, 5.67 + [T_NONE] { .type= T_NONE, .name= "none", .print= none_print }, 5.68 + [T_NULL] { .type= T_NULL, .name= "null", .print= null_print }, 5.69 + [T_UINT] { .type= T_UINT, .name= "int", .print= int_print, }, 5.70 + [T_BOOL] { .type= T_BOOL, .name= "bool", .print= bool_print, }, 5.71 + [T_ERR] { .type= T_ERR, .name= "err", .print= err_print, }, 5.72 + [T_NOMEM] { .type= T_ERR, .name= "nomem", .print= nomem_print, }, 5.73 + [T_ATOM] { .type= T_ATOM, .name= "atom", .print= atom_print, 5.74 + .pointer= TRUE, 5.75 + .free= atom_free, 5.76 + .equal= atom_equal, 5.77 + .copy= atom_copy, 5.78 + }, 5.79 + [T_STRING] { .type= T_STRING, .name= "string", .print= string_print, 5.80 + .pointer= TRUE, 5.81 + .free= string_free, 5.82 + .equal= string_equal, 5.83 + .copy= string_copy, 5.84 + }, 5.85 + [T_CONS] { .type= T_CONS, .name= "cons", .print= cons_print, 5.86 + .pointer= TRUE, 5.87 + .free= cons_free, 5.88 + .equal= cons_equal, 5.89 + .copy= cons_copy, 5.90 + }, 5.91 }; 5.92 5.93 /** Number of entries in the types array. */ 5.94 @@ -157,12 +180,29 @@ int objprint(IOStream *io, Sxpr x, unsig 5.95 int k = 0; 5.96 if(!io) return k; 5.97 if(flags & PRINT_TYPE){ 5.98 - k += IOStream_print(io, "%s:", def->name); 5.99 + k += IOStream_print(io, "%s:", def->name); 5.100 + } 5.101 + if(def->pointer && (flags & PRINT_ADDR)){ 5.102 + k += IOStream_print(io, "<%p>", get_ptr(x)); 5.103 } 5.104 k += print_fn(io, x, flags); 5.105 return k; 5.106 } 5.107 5.108 +Sxpr objcopy(Sxpr x){ 5.109 + SxprType *def = get_sxpr_type(get_type(x)); 5.110 + ObjCopyFn *copy_fn = (def ? def->copy : NULL); 5.111 + Sxpr v; 5.112 + if(copy_fn){ 5.113 + v = copy_fn(x); 5.114 + } else if(def->pointer){ 5.115 + v = ONOMEM; 5.116 + } else { 5.117 + v = x; 5.118 + } 5.119 + return v; 5.120 +} 5.121 + 5.122 /** General sxpr free function. 5.123 * Frees an sxpr using the free function for its type. 5.124 * Free functions must recursively free any subsxprs. 5.125 @@ -176,11 +216,11 @@ void objfree(Sxpr x){ 5.126 SxprType *def = get_sxpr_type(get_type(x)); 5.127 5.128 if(def){ 5.129 - if(def->free){ 5.130 - def->free(x); 5.131 - } else if (def->pointer){ 5.132 - hfree(x); 5.133 - } 5.134 + if(def->free){ 5.135 + def->free(x); 5.136 + } else if (def->pointer){ 5.137 + hfree(x); 5.138 + } 5.139 } 5.140 } 5.141 5.142 @@ -284,9 +324,9 @@ Sxpr cons_member_if(Sxpr l, ObjEqualFn * 5.143 */ 5.144 int cons_subset(Sxpr s, Sxpr t){ 5.145 for( ; CONSP(t); t = CDR(t)){ 5.146 - if(!CONSP(cons_member(s, CAR(t)))){ 5.147 - return 0; 5.148 - } 5.149 + if(!CONSP(cons_member(s, CAR(t)))){ 5.150 + return 0; 5.151 + } 5.152 } 5.153 return 1; 5.154 } 5.155 @@ -365,18 +405,27 @@ Sxpr setf(Sxpr k, Sxpr v, Sxpr l){ 5.156 #endif /* USE_GC */ 5.157 5.158 /** Create a new atom with the given name. 5.159 + * Makes an integer sxpr if the name can be parsed as an int. 5.160 * 5.161 * @param name the name 5.162 * @return new atom 5.163 */ 5.164 Sxpr atom_new(char *name){ 5.165 Sxpr n, obj = ONOMEM; 5.166 + long v; 5.167 5.168 - n = string_new(name); 5.169 - if(NOMEMP(n)) goto exit; 5.170 - obj = HALLOC(ObjAtom, T_ATOM); 5.171 - if(NOMEMP(obj)) goto exit; 5.172 - OBJ_ATOM(obj)->name = n; 5.173 + if(convert_atol(name, &v) == 0){ 5.174 + obj = OINT(v); 5.175 + } else { 5.176 + n = string_new(name); 5.177 + if(NOMEMP(n)) goto exit; 5.178 + obj = HALLOC(ObjAtom, T_ATOM); 5.179 + if(NOMEMP(obj)){ 5.180 + string_free(n); 5.181 + goto exit; 5.182 + } 5.183 + OBJ_ATOM(obj)->name = n; 5.184 + } 5.185 exit: 5.186 return obj; 5.187 } 5.188 @@ -392,6 +441,20 @@ void atom_free(Sxpr obj){ 5.189 hfree(obj); 5.190 } 5.191 5.192 +/** Copy an atom. 5.193 + * 5.194 + * @param obj to copy 5.195 + */ 5.196 +Sxpr atom_copy(Sxpr obj){ 5.197 + Sxpr v; 5.198 + if(OBJ_ATOM(obj)->interned){ 5.199 + v = obj; 5.200 + } else { 5.201 + v = atom_new(atom_name(obj)); 5.202 + } 5.203 + return v; 5.204 +} 5.205 + 5.206 /** Print an atom. Prints the atom name. 5.207 * 5.208 * @param io stream to print to 5.209 @@ -400,8 +463,7 @@ void atom_free(Sxpr obj){ 5.210 * @return number of bytes printed 5.211 */ 5.212 int atom_print(IOStream *io, Sxpr obj, unsigned flags){ 5.213 - //return string_print(io, OBJ_ATOM(obj)->name, (flags | PRINT_RAW)); 5.214 - return string_print(io, OBJ_ATOM(obj)->name, flags); 5.215 + return objprint(io, OBJ_ATOM(obj)->name, flags); 5.216 } 5.217 5.218 /** Atom equality. 5.219 @@ -430,13 +492,17 @@ char * atom_name(Sxpr obj){ 5.220 return string_string(OBJ_ATOM(obj)->name); 5.221 } 5.222 5.223 +int atom_length(Sxpr obj){ 5.224 + return string_length(OBJ_ATOM(obj)->name); 5.225 +} 5.226 + 5.227 /** Get the C string from a string sxpr. 5.228 * 5.229 * @param obj string sxpr 5.230 * @return string 5.231 */ 5.232 char * string_string(Sxpr obj){ 5.233 - return OBJ_STRING(obj); 5.234 + return OBJ_STRING(obj)->data; 5.235 } 5.236 5.237 /** Get the length of a string. 5.238 @@ -445,7 +511,7 @@ char * string_string(Sxpr obj){ 5.239 * @return length 5.240 */ 5.241 int string_length(Sxpr obj){ 5.242 - return strlen(OBJ_STRING(obj)); 5.243 + return OBJ_STRING(obj)->len; 5.244 } 5.245 5.246 /** Create a new string. The input string is copied, 5.247 @@ -456,12 +522,28 @@ int string_length(Sxpr obj){ 5.248 */ 5.249 Sxpr string_new(char *s){ 5.250 int n = (s ? strlen(s) : 0); 5.251 + return string_new_n(s, n); 5.252 +} 5.253 + 5.254 +/** Create a new string. The input string is copied, 5.255 + * and need not be null-terminated. 5.256 + * 5.257 + * @param s characters to put in the string (may be null) 5.258 + * @param n string length 5.259 + * @return new sxpr 5.260 + */ 5.261 +Sxpr string_new_n(char *s, int n){ 5.262 Sxpr obj; 5.263 - obj = halloc(n+1, T_STRING); 5.264 + obj = halloc(sizeof(ObjString) + n + 1, T_STRING); 5.265 if(!NOMEMP(obj)){ 5.266 - char *str = OBJ_STRING(obj); 5.267 - strncpy(str, s, n); 5.268 - str[n] = '\0'; 5.269 + char *str = OBJ_STRING(obj)->data; 5.270 + OBJ_STRING(obj)->len = n; 5.271 + if(s){ 5.272 + memcpy(str, s, n); 5.273 + str[n] = '\0'; 5.274 + } else { 5.275 + memset(str, 0, n + 1); 5.276 + } 5.277 } 5.278 return obj; 5.279 } 5.280 @@ -474,70 +556,180 @@ void string_free(Sxpr obj){ 5.281 hfree(obj); 5.282 } 5.283 5.284 +/** Copy a string. 5.285 + * 5.286 + * @param obj to copy 5.287 + */ 5.288 +Sxpr string_copy(Sxpr obj){ 5.289 + return string_new_n(string_string(obj), string_length(obj)); 5.290 +} 5.291 + 5.292 /** Determine if a string needs escapes when printed 5.293 * using the given flags. 5.294 * 5.295 * @param str string to check 5.296 + * @param n string length 5.297 * @param flags print flags 5.298 * @return 1 if needs escapes, 0 otherwise 5.299 */ 5.300 -int needs_escapes(char *str, unsigned flags){ 5.301 +int needs_escapes(char *str, int n, unsigned flags){ 5.302 char *c; 5.303 + int i; 5.304 int val = 0; 5.305 5.306 if(str){ 5.307 - for(c=str; *c; c++){ 5.308 - if(in_alpha_class(*c)) continue; 5.309 - if(in_decimal_digit_class(*c)) continue; 5.310 - if(in_class(*c, "/._+:@~-")) continue; 5.311 - val = 1; 5.312 - break; 5.313 - } 5.314 + for(i=0, c=str; i<n; i++, c++){ 5.315 + if(in_alpha_class(*c)) continue; 5.316 + if(in_decimal_digit_class(*c)) continue; 5.317 + if(in_class(*c, "/._+:@~-")) continue; 5.318 + val = 1; 5.319 + break; 5.320 + } 5.321 + } 5.322 + return val; 5.323 +} 5.324 + 5.325 +char randchar(void){ 5.326 + int r; 5.327 + char c; 5.328 + for( ; ; ){ 5.329 + r = rand(); 5.330 + c = (r >> 16) & 0xff; 5.331 + if('a' <= c && c <= 'z') break; 5.332 + } 5.333 + return c; 5.334 +} 5.335 + 5.336 +int string_contains(char *s, int s_n, char *k, int k_n){ 5.337 + int i, n = s_n - k_n; 5.338 + for(i=0; i < n; i++){ 5.339 + if(!memcmp(s+i, k, k_n)) return 1; 5.340 + } 5.341 + return 0; 5.342 +} 5.343 + 5.344 +int string_delim(char *s, int s_n, char *d, int d_n){ 5.345 + int i; 5.346 + if(d_n < 4) return -1; 5.347 + memset(d, 0, d_n+1); 5.348 + for(i=0; i<3; i++){ 5.349 + d[i] = randchar(); 5.350 + } 5.351 + for( ; i < d_n; i++){ 5.352 + if(!string_contains(s, s_n, d, i)){ 5.353 + return i; 5.354 + } 5.355 + d[i] = randchar(); 5.356 } 5.357 - //printf("\n> val=%d str=|%s|\n", val, str); 5.358 - return val; 5.359 + return -1; 5.360 +} 5.361 + 5.362 +/** Print the bytes in a string as-is. 5.363 + * 5.364 + * @param io stream 5.365 + * @param str string 5.366 + * @param n length 5.367 + * @return bytes written or error code 5.368 + */ 5.369 +int _string_print_raw(IOStream *io, char *str, int n){ 5.370 + int k = 0; 5.371 + k = IOStream_write(io, str, n); 5.372 + return k; 5.373 +} 5.374 + 5.375 +/** Print a string in counted data format. 5.376 + * 5.377 + * @param io stream 5.378 + * @param str string 5.379 + * @param n length 5.380 + * @return bytes written or error code 5.381 + */ 5.382 +int _string_print_counted(IOStream *io, char *str, int n){ 5.383 + int k = 0; 5.384 + k += IOStream_print(io, "%c%c%d%c", 5.385 + c_data_open, c_data_count, n, c_data_count); 5.386 + k += IOStream_write(io, str, n); 5.387 + return k; 5.388 +} 5.389 + 5.390 +/** Print a string in quoted data format. 5.391 + * 5.392 + * @param io stream 5.393 + * @param str string 5.394 + * @param n length 5.395 + * @return bytes written or error code 5.396 + */ 5.397 +int _string_print_quoted(IOStream *io, char *str, int n){ 5.398 + int k = 0; 5.399 + char d[10]; 5.400 + int d_n; 5.401 + d_n = string_delim(str, n, d, sizeof(d) - 1); 5.402 + k += IOStream_print(io, "%c%c%s%c", 5.403 + c_data_open, c_data_quote, d, c_data_quote); 5.404 + k += IOStream_write(io, str, n); 5.405 + k += IOStream_print(io, "%c%s%c", c_data_quote, d, c_data_quote); 5.406 + return k; 5.407 +} 5.408 + 5.409 +/** Print a string as a quoted string. 5.410 + * 5.411 + * @param io stream 5.412 + * @param str string 5.413 + * @param n length 5.414 + * @return bytes written or error code 5.415 + */ 5.416 +int _string_print_string(IOStream *io, char *str, int n){ 5.417 + int k = 0; 5.418 + 5.419 + k += IOStream_print(io, "\""); 5.420 + if(str){ 5.421 + char *s, *t; 5.422 + for(s = str, t = str + n; s < t; s++){ 5.423 + if(*s < ' ' || *s >= 127 ){ 5.424 + switch(*s){ 5.425 + case '\a': k += IOStream_print(io, "\\a"); break; 5.426 + case '\b': k += IOStream_print(io, "\\b"); break; 5.427 + case '\f': k += IOStream_print(io, "\\f"); break; 5.428 + case '\n': k += IOStream_print(io, "\\n"); break; 5.429 + case '\r': k += IOStream_print(io, "\\r"); break; 5.430 + case '\t': k += IOStream_print(io, "\\t"); break; 5.431 + case '\v': k += IOStream_print(io, "\\v"); break; 5.432 + default: 5.433 + // Octal escape; 5.434 + k += IOStream_print(io, "\\%o", *s); 5.435 + break; 5.436 + } 5.437 + } else if(*s == c_double_quote || 5.438 + *s == c_single_quote || 5.439 + *s == c_escape){ 5.440 + k += IOStream_print(io, "\\%c", *s); 5.441 + } else { 5.442 + k+= IOStream_print(io, "%c", *s); 5.443 + } 5.444 + } 5.445 + } 5.446 + k += IOStream_print(io, "\""); 5.447 + return k; 5.448 } 5.449 5.450 /** Print a string to a stream, with escapes if necessary. 5.451 * 5.452 * @param io stream to print to 5.453 * @param str string 5.454 + * @param n string length 5.455 * @param flags print flags 5.456 * @return number of bytes written 5.457 */ 5.458 -int _string_print(IOStream *io, char *str, unsigned flags){ 5.459 +int _string_print(IOStream *io, char *str, int n, unsigned flags){ 5.460 int k = 0; 5.461 - if((flags & PRINT_RAW) || !needs_escapes(str, flags)){ 5.462 - k += IOStream_print(io, str); 5.463 + if((flags & PRINT_COUNTED)){ 5.464 + k = _string_print_counted(io, str, n); 5.465 + } else if((flags & PRINT_RAW) || !needs_escapes(str, n, flags)){ 5.466 + k = _string_print_raw(io, str, n); 5.467 + } else if(n > 50){ 5.468 + k = _string_print_quoted(io, str, n); 5.469 } else { 5.470 - k += IOStream_print(io, "\""); 5.471 - if(str){ 5.472 - char *s; 5.473 - for(s = str; *s; s++){ 5.474 - if(*s < ' ' || *s >= 127 ){ 5.475 - switch(*s){ 5.476 - case '\a': k += IOStream_print(io, "\\a"); break; 5.477 - case '\b': k += IOStream_print(io, "\\b"); break; 5.478 - case '\f': k += IOStream_print(io, "\\f"); break; 5.479 - case '\n': k += IOStream_print(io, "\\n"); break; 5.480 - case '\r': k += IOStream_print(io, "\\r"); break; 5.481 - case '\t': k += IOStream_print(io, "\\t"); break; 5.482 - case '\v': k += IOStream_print(io, "\\v"); break; 5.483 - default: 5.484 - // Octal escape; 5.485 - k += IOStream_print(io, "\\%o", *s); 5.486 - break; 5.487 - } 5.488 - } else if(*s == c_double_quote || 5.489 - *s == c_single_quote || 5.490 - *s == c_escape){ 5.491 - k += IOStream_print(io, "\\%c", *s); 5.492 - } else { 5.493 - k+= IOStream_print(io, "%c", *s); 5.494 - } 5.495 - } 5.496 - } 5.497 - k += IOStream_print(io, "\""); 5.498 + k = _string_print_string(io, str, n); 5.499 } 5.500 return k; 5.501 } 5.502 @@ -550,7 +742,14 @@ int _string_print(IOStream *io, char *st 5.503 * @return number of bytes written 5.504 */ 5.505 int string_print(IOStream *io, Sxpr obj, unsigned flags){ 5.506 - return _string_print(io, OBJ_STRING(obj), flags); 5.507 + return _string_print(io, 5.508 + OBJ_STRING(obj)->data, 5.509 + OBJ_STRING(obj)->len, 5.510 + flags); 5.511 +} 5.512 + 5.513 +int string_eq(char *s, int s_n, char *t, int t_n){ 5.514 + return (s_n == t_n) && (memcmp(s, t, s_n) == 0); 5.515 } 5.516 5.517 /** Compare an sxpr with a string for equality. 5.518 @@ -563,9 +762,13 @@ int string_equal(Sxpr x, Sxpr y){ 5.519 int ok = 0; 5.520 ok = eq(x,y); 5.521 if(ok) goto exit; 5.522 - ok = has_type(y, T_STRING) && !strcmp(OBJ_STRING(x), OBJ_STRING(y)); 5.523 + ok = has_type(y, T_STRING) && 5.524 + string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len, 5.525 + OBJ_STRING(y)->data, OBJ_STRING(y)->len); 5.526 if(ok) goto exit; 5.527 - ok = has_type(y, T_ATOM) && !strcmp(OBJ_STRING(x), atom_name(y)); 5.528 + ok = has_type(y, T_ATOM) && 5.529 + string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len, 5.530 + atom_name(y), atom_length(y)); 5.531 exit: 5.532 return ok; 5.533 } 5.534 @@ -613,15 +816,38 @@ int cons_push(Sxpr *list, Sxpr elt){ 5.535 void cons_free(Sxpr obj){ 5.536 Sxpr next; 5.537 for(; CONSP(obj); obj = next){ 5.538 - next = CDR(obj); 5.539 - objfree(CAR(obj)); 5.540 - hfree(obj); 5.541 + next = CDR(obj); 5.542 + objfree(CAR(obj)); 5.543 + hfree(obj); 5.544 } 5.545 if(!NULLP(obj)){ 5.546 - objfree(obj); 5.547 + objfree(obj); 5.548 } 5.549 } 5.550 5.551 +/** Copy a cons. Recursively copies the car and cdr. 5.552 + * 5.553 + * @param obj to copy 5.554 + */ 5.555 +Sxpr cons_copy(Sxpr obj){ 5.556 + Sxpr v = ONULL; 5.557 + Sxpr l = ONULL, x = ONONE; 5.558 + for(l = obj; CONSP(l); l = CDR(l)){ 5.559 + x = objcopy(CAR(l)); 5.560 + if(NOMEMP(x)) goto exit; 5.561 + x = cons_new(x, v); 5.562 + if(NOMEMP(x)) goto exit; 5.563 + v = x; 5.564 + } 5.565 + v = nrev(v); 5.566 + exit: 5.567 + if(NOMEMP(x)){ 5.568 + objfree(v); 5.569 + v = ONOMEM; 5.570 + } 5.571 + return v; 5.572 +} 5.573 + 5.574 /** Free a cons and its cdr cells, but not the car sxprs. 5.575 * Does nothing if called on something that is not a cons. 5.576 * 5.577 @@ -630,8 +856,8 @@ void cons_free(Sxpr obj){ 5.578 void cons_free_cells(Sxpr obj){ 5.579 Sxpr next; 5.580 for(; CONSP(obj); obj = next){ 5.581 - next = CDR(obj); 5.582 - hfree(obj); 5.583 + next = CDR(obj); 5.584 + hfree(obj); 5.585 } 5.586 } 5.587 5.588 @@ -698,26 +924,26 @@ int cons_length(Sxpr obj){ 5.589 */ 5.590 Sxpr nrev(Sxpr l){ 5.591 if(CONSP(l)){ 5.592 - // Iterate down the cells in the list making the cdr of 5.593 - // each cell point to the previous cell. The last cell 5.594 - // is the head of the reversed list. 5.595 - Sxpr prev = ONULL; 5.596 - Sxpr cell = l; 5.597 - Sxpr next; 5.598 + // Iterate down the cells in the list making the cdr of 5.599 + // each cell point to the previous cell. The last cell 5.600 + // is the head of the reversed list. 5.601 + Sxpr prev = ONULL; 5.602 + Sxpr cell = l; 5.603 + Sxpr next; 5.604 5.605 - while(1){ 5.606 - next = CDR(cell); 5.607 - CDR(cell) = prev; 5.608 - if(!CONSP(next)) break; 5.609 - prev = cell; 5.610 - cell = next; 5.611 - } 5.612 - l = cell; 5.613 + while(1){ 5.614 + next = CDR(cell); 5.615 + CDR(cell) = prev; 5.616 + if(!CONSP(next)) break; 5.617 + prev = cell; 5.618 + cell = next; 5.619 + } 5.620 + l = cell; 5.621 } 5.622 return l; 5.623 } 5.624 5.625 -/** Print the null sxpr. 5.626 +/** Print the null sxpr. 5.627 * 5.628 * @param io stream to print to 5.629 * @param obj to print 5.630 @@ -761,6 +987,30 @@ static int bool_print(IOStream *io, Sxpr 5.631 return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false)); 5.632 } 5.633 5.634 +/** Print an error. 5.635 + * 5.636 + * @param io stream to print to 5.637 + * @param obj to print 5.638 + * @param flags print flags 5.639 + * @return number of bytes written 5.640 + */ 5.641 +static int err_print(IOStream *io, Sxpr obj, unsigned flags){ 5.642 + int err = OBJ_INT(obj); 5.643 + if(err < 0) err = -err; 5.644 + return IOStream_print(io, "[error:%d:%s]", err, strerror(err)); 5.645 +} 5.646 + 5.647 +/** Print the 'nomem' sxpr. 5.648 + * 5.649 + * @param io stream to print to 5.650 + * @param obj to print 5.651 + * @param flags print flags 5.652 + * @return number of bytes written 5.653 + */ 5.654 +static int nomem_print(IOStream *io, Sxpr obj, unsigned flags){ 5.655 + return IOStream_print(io, "[ENOMEM]"); 5.656 +} 5.657 + 5.658 int sxprp(Sxpr obj, Sxpr name){ 5.659 return CONSP(obj) && objequal(CAR(obj), name); 5.660 } 5.661 @@ -781,8 +1031,8 @@ Sxpr sxpr_name(Sxpr obj){ 5.662 } 5.663 5.664 int sxpr_is(Sxpr obj, char *s){ 5.665 - if(ATOMP(obj)) return !strcmp(atom_name(obj), s); 5.666 - if(STRINGP(obj)) return !strcmp(string_string(obj), s); 5.667 + if(ATOMP(obj)) return string_eq(atom_name(obj), atom_length(obj), s, strlen(s)); 5.668 + if(STRINGP(obj)) return string_eq(string_string(obj), string_length(obj), s, strlen(s)); 5.669 return 0; 5.670 } 5.671 5.672 @@ -915,11 +1165,11 @@ static int sym_equal_fn(void *x, void *y 5.673 */ 5.674 static void sym_free_fn(HashTable *table, HTEntry *entry){ 5.675 if(entry){ 5.676 - objfree(((ObjAtom*)entry->value)->name); 5.677 - HTEntry_free(entry); 5.678 + objfree(((ObjAtom*)entry->value)->name); 5.679 + HTEntry_free(entry); 5.680 } 5.681 } 5.682 - 5.683 + 5.684 /** Initialize the symbol table. 5.685 * 5.686 * @return 0 on sucess, error code otherwise 5.687 @@ -929,7 +1179,7 @@ static int init_symbols(void){ 5.688 if(symbols){ 5.689 symbols->key_hash_fn = sym_hash_fn; 5.690 symbols->key_equal_fn = sym_equal_fn; 5.691 - symbols->entry_free_fn = sym_free_fn; 5.692 + symbols->entry_free_fn = sym_free_fn; 5.693 return 0; 5.694 } 5.695 return -1; 5.696 @@ -950,8 +1200,8 @@ void cleanup_symbols(void){ 5.697 Sxpr get_symbol(char *sym){ 5.698 HTEntry *entry; 5.699 if(!symbols){ 5.700 - if(init_symbols()) return ONOMEM; 5.701 - return ONULL; 5.702 + if(init_symbols()) return ONOMEM; 5.703 + return ONULL; 5.704 } 5.705 entry = HashTable_get_entry(symbols, sym); 5.706 if(entry){ 5.707 @@ -969,10 +1219,10 @@ Sxpr get_symbol(char *sym){ 5.708 Sxpr intern(char *sym){ 5.709 Sxpr symbol = get_symbol(sym); 5.710 if(NULLP(symbol)){ 5.711 - if(!symbols) return ONOMEM; 5.712 + if(!symbols) return ONOMEM; 5.713 symbol = atom_new(sym); 5.714 if(!NOMEMP(symbol)){ 5.715 - OBJ_ATOM(symbol)->interned = TRUE; 5.716 + OBJ_ATOM(symbol)->interned = TRUE; 5.717 HashTable_add(symbols, atom_name(symbol), get_ptr(symbol)); 5.718 } 5.719 }
6.1 --- a/tools/libxutil/sxpr.h Fri May 13 15:01:20 2005 +0000 6.2 +++ b/tools/libxutil/sxpr.h Fri May 13 15:08:29 2005 +0000 6.3 @@ -52,142 +52,13 @@ typedef struct Sxpr { 6.4 /** Sxpr type. */ 6.5 TypeCode type; 6.6 union { 6.7 - /** Sxpr value. */ 6.8 + /** Sxpr value. */ 6.9 unsigned long ul; 6.10 - /** Pointer. */ 6.11 + /** Pointer. */ 6.12 void *ptr; 6.13 } v; 6.14 } Sxpr; 6.15 6.16 -/** Sxpr type to indicate out of memory. */ 6.17 -#define T_NOMEM ((TypeCode)-1) 6.18 -/** The 'unspecified' sxpr. */ 6.19 -#define T_NONE ((TypeCode)0) 6.20 -/** The empty list. */ 6.21 -#define T_NULL ((TypeCode)1) 6.22 -/** Unsigned integer. */ 6.23 -#define T_UINT ((TypeCode)2) 6.24 -/** A string. */ 6.25 -#define T_STRING ((TypeCode)3) 6.26 -/** An atom. */ 6.27 -#define T_ATOM ((TypeCode)4) 6.28 -/** A boolean. */ 6.29 -#define T_BOOL ((TypeCode)5) 6.30 - 6.31 -/** A cons (pair or list). */ 6.32 -#define T_CONS ((TypeCode)10) 6.33 - 6.34 -/** An error. */ 6.35 -#define T_ERR ((TypeCode)40) 6.36 - 6.37 -/** An atom. */ 6.38 -typedef struct ObjAtom { 6.39 - Sxpr name; 6.40 - Hashcode hashcode; 6.41 - int interned; 6.42 -} ObjAtom; 6.43 - 6.44 -/** A cons (pair). */ 6.45 -typedef struct ObjCons { 6.46 - Sxpr car; 6.47 - Sxpr cdr; 6.48 -} ObjCons; 6.49 - 6.50 -/** A vector. */ 6.51 -typedef struct ObjVector { 6.52 - int n; 6.53 - Sxpr data[0]; 6.54 -} ObjVector; 6.55 - 6.56 -/** Flags for sxpr printing. */ 6.57 -enum PrintFlags { 6.58 - PRINT_RAW = 0x001, 6.59 - PRINT_TYPE = 0x002, 6.60 - PRINT_PRETTY = 0x004, 6.61 - PRINT_NUM = 0x008, 6.62 -}; 6.63 - 6.64 -/** An integer sxpr. 6.65 - * 6.66 - * @param ty type 6.67 - * @param val integer value 6.68 - */ 6.69 -#define OBJI(ty, val) (Sxpr){ type: (ty), v: { ul: (val) }} 6.70 - 6.71 -/** A pointer sxpr. 6.72 - * If the pointer is non-null, returns an sxpr containing it. 6.73 - * If the pointer is null, returns ONOMEM. 6.74 - * 6.75 - * @param ty type 6.76 - * @param val pointer 6.77 - */ 6.78 -#define OBJP(ty, val) ((val) ? (Sxpr){ type: (ty), v: { ptr: (val) }} : ONOMEM) 6.79 - 6.80 -/** Make an integer sxpr containing a pointer. 6.81 - * 6.82 - * @param val pointer 6.83 - */ 6.84 -#define PTR(val) OBJP(T_UINT, (void*)(val)) 6.85 - 6.86 -/** Make an integer sxpr. 6.87 - * @param x value 6.88 - */ 6.89 -#define OINT(x) OBJI(T_UINT, x) 6.90 - 6.91 -/** Make an error sxpr. 6.92 - * 6.93 - * @param x value 6.94 - */ 6.95 -#define OERR(x) OBJI(T_ERR, x) 6.96 - 6.97 -/** Out of memory constant. */ 6.98 -#define ONOMEM OBJI(T_NOMEM, 0) 6.99 - 6.100 -/** The `unspecified' constant. */ 6.101 -#define ONONE OBJI(T_NONE, 0) 6.102 - 6.103 -/** Empty list constant. */ 6.104 -#define ONULL OBJI(T_NULL, 0) 6.105 - 6.106 -/** False constant. */ 6.107 -#define OFALSE OBJI(T_BOOL, 0) 6.108 - 6.109 -/** True constant. */ 6.110 -#define OTRUE OBJI(T_BOOL, 1) 6.111 - 6.112 -/* Recognizers for the various sxpr types. */ 6.113 -#define ATOMP(obj) has_type(obj, T_ATOM) 6.114 -#define BOOLP(obj) has_type(obj, T_BOOL) 6.115 -#define CONSP(obj) has_type(obj, T_CONS) 6.116 -#define ERRP(obj) has_type(obj, T_ERR) 6.117 -#define INTP(obj) has_type(obj, T_UINT) 6.118 -#define NOMEMP(obj) has_type(obj, T_NOMEM) 6.119 -#define NONEP(obj) has_type(obj, T_NONE) 6.120 -#define NULLP(obj) has_type(obj, T_NULL) 6.121 -#define STRINGP(obj) has_type(obj, T_STRING) 6.122 - 6.123 -#define TRUEP(obj) get_ul(obj) 6.124 - 6.125 -/** Convert an sxpr to an unsigned integer. */ 6.126 -#define OBJ_UINT(x) get_ul(x) 6.127 -/** Convert an sxpr to an integer. */ 6.128 -#define OBJ_INT(x) (int)get_ul(x) 6.129 - 6.130 -/* Conversions of sxprs to their values. 6.131 - * No checking is done. 6.132 - */ 6.133 -#define OBJ_STRING(x) ((char*)get_ptr(x)) 6.134 -#define OBJ_CONS(x) ((ObjCons*)get_ptr(x)) 6.135 -#define OBJ_ATOM(x) ((ObjAtom*)get_ptr(x)) 6.136 -#define OBJ_SET(x) ((ObjSet*)get_ptr(x)) 6.137 -#define CAR(x) (OBJ_CONS(x)->car) 6.138 -#define CDR(x) (OBJ_CONS(x)->cdr) 6.139 - 6.140 -#define CAAR(x) (CAR(CAR(x))) 6.141 -#define CADR(x) (CAR(CDR(x))) 6.142 -#define CDAR(x) (CDR(CAR(x))) 6.143 -#define CDDR(x) (CDR(CDR(x))) 6.144 - 6.145 /** Get the integer value from an sxpr. 6.146 * 6.147 * @param obj sxpr 6.148 @@ -208,22 +79,22 @@ static inline void * get_ptr(Sxpr obj){ 6.149 6.150 /** Create an sxpr containing a pointer. 6.151 * 6.152 - * @param type typecode 6.153 + * @param ty typecode 6.154 * @param val pointer 6.155 * @return sxpr 6.156 */ 6.157 -static inline Sxpr obj_ptr(TypeCode type, void *val){ 6.158 - return (Sxpr){ type: type, v: { ptr: val } }; 6.159 +static inline Sxpr obj_ptr(TypeCode ty, void *val){ 6.160 + return (Sxpr){ .type= ty, .v= { .ptr= val } }; 6.161 } 6.162 6.163 /** Create an sxpr containing an integer. 6.164 * 6.165 - * @param type typecode 6.166 + * @param ty typecode 6.167 * @param val integer 6.168 * @return sxpr 6.169 */ 6.170 -static inline Sxpr obj_ul(TypeCode type, unsigned long val){ 6.171 - return (Sxpr){ type: type, v: { ul: val } }; 6.172 +static inline Sxpr obj_ul(TypeCode ty, unsigned long val){ 6.173 + return (Sxpr){ .type= ty, .v= { .ul= val } }; 6.174 } 6.175 6.176 /** Get the type of an sxpr. 6.177 @@ -255,6 +126,160 @@ static inline int eq(Sxpr x, Sxpr y){ 6.178 return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y))); 6.179 } 6.180 6.181 +/** The 'unspecified' sxpr. */ 6.182 +#define T_NONE ((TypeCode)0) 6.183 +/** The empty list. */ 6.184 +#define T_NULL ((TypeCode)1) 6.185 +/** Unsigned integer. */ 6.186 +#define T_UINT ((TypeCode)2) 6.187 +/** A string. */ 6.188 +#define T_STRING ((TypeCode)3) 6.189 +/** An atom. */ 6.190 +#define T_ATOM ((TypeCode)4) 6.191 +/** A boolean. */ 6.192 +#define T_BOOL ((TypeCode)5) 6.193 + 6.194 +/** A cons (pair or list). */ 6.195 +#define T_CONS ((TypeCode)10) 6.196 + 6.197 +/** An error. */ 6.198 +#define T_ERR ((TypeCode)40) 6.199 +/** Sxpr type to indicate out of memory. */ 6.200 +#define T_NOMEM ((TypeCode)41) 6.201 + 6.202 +typedef struct ObjString { 6.203 + int len; 6.204 + char data[]; 6.205 +} ObjString; 6.206 + 6.207 +/** An atom. */ 6.208 +typedef struct ObjAtom { 6.209 + Sxpr name; 6.210 + Hashcode hashcode; 6.211 + int interned; 6.212 +} ObjAtom; 6.213 + 6.214 +/** A cons (pair). */ 6.215 +typedef struct ObjCons { 6.216 + Sxpr car; 6.217 + Sxpr cdr; 6.218 +} ObjCons; 6.219 + 6.220 +/** Flags for sxpr printing. */ 6.221 +enum PrintFlags { 6.222 + PRINT_RAW = 0x001, 6.223 + PRINT_TYPE = 0x002, 6.224 + PRINT_PRETTY = 0x004, 6.225 + PRINT_COUNTED = 0x008, 6.226 + PRINT_ADDR = 0x010, 6.227 +}; 6.228 + 6.229 +extern int _string_print(IOStream *io, char *str, int n, unsigned flags); 6.230 +extern int _string_print_raw(IOStream *io, char *str, int n); 6.231 +extern int _string_print_counted(IOStream *io, char *str, int n); 6.232 +extern int _string_print_quoted(IOStream *io, char *str, int n); 6.233 +extern int _string_print_string(IOStream *io, char *str, int n); 6.234 + 6.235 +/** An integer sxpr. 6.236 + * 6.237 + * @param ty type 6.238 + * @param val integer value 6.239 + */ 6.240 +#define OBJI(ty, val) obj_ul(ty, val) 6.241 + 6.242 +/** Make an integer sxpr. 6.243 + * @param x value 6.244 + */ 6.245 +#define OINT(x) OBJI(T_UINT, x) 6.246 + 6.247 +/** Make an error sxpr. 6.248 + * 6.249 + * @param x value 6.250 + */ 6.251 +#define OERR(x) OBJI(T_ERR, x) 6.252 + 6.253 +/** Out of memory constant. */ 6.254 +#define ONOMEM OBJI(T_NOMEM, 0) 6.255 + 6.256 +/** The `unspecified' constant. */ 6.257 +#define ONONE OBJI(T_NONE, 0) 6.258 + 6.259 +/** Empty list constant. */ 6.260 +#define ONULL OBJI(T_NULL, 0) 6.261 + 6.262 +/** False constant. */ 6.263 +#define OFALSE OBJI(T_BOOL, 0) 6.264 + 6.265 +/** True constant. */ 6.266 +#define OTRUE OBJI(T_BOOL, 1) 6.267 + 6.268 +/** A pointer sxpr. 6.269 + * If the pointer is non-null, returns an sxpr containing it. 6.270 + * If the pointer is null, returns ONOMEM. 6.271 + * 6.272 + * @param ty type 6.273 + * @param val pointer 6.274 + */ 6.275 +static inline Sxpr OBJP(int ty, void *val){ 6.276 + return (val ? obj_ptr(ty, val) : ONOMEM); 6.277 +} 6.278 + 6.279 +/** Make an integer sxpr containing a pointer. 6.280 + * 6.281 + * @param val pointer 6.282 + */ 6.283 +#define PTR(val) OBJP(T_UINT, (void*)(val)) 6.284 + 6.285 +/** Allocate some memory and return an sxpr containing it. 6.286 + * Returns ONOMEM if allocation failed. 6.287 + * 6.288 + * @param n number of bytes to allocate 6.289 + * @param ty typecode 6.290 + * @return sxpr 6.291 + */ 6.292 +#define halloc(_n, _ty) OBJP(_ty, allocate(_n)) 6.293 + 6.294 +/** Allocate an sxpr containing a pointer to the given type. 6.295 + * 6.296 + * @param _ctype type (uses sizeof to determine how many bytes to allocate) 6.297 + * @param _tycode typecode 6.298 + * @return sxpr, ONOMEM if allocation failed 6.299 + */ 6.300 +#define HALLOC(_ctype, _tycode) halloc(sizeof(_ctype), _tycode) 6.301 + 6.302 +/* Recognizers for the various sxpr types. */ 6.303 +#define ATOMP(obj) has_type(obj, T_ATOM) 6.304 +#define BOOLP(obj) has_type(obj, T_BOOL) 6.305 +#define CONSP(obj) has_type(obj, T_CONS) 6.306 +#define ERRP(obj) has_type(obj, T_ERR) 6.307 +#define INTP(obj) has_type(obj, T_UINT) 6.308 +#define NOMEMP(obj) has_type(obj, T_NOMEM) 6.309 +#define NONEP(obj) has_type(obj, T_NONE) 6.310 +#define NULLP(obj) has_type(obj, T_NULL) 6.311 +#define STRINGP(obj) has_type(obj, T_STRING) 6.312 + 6.313 +#define TRUEP(obj) get_ul(obj) 6.314 + 6.315 +/** Convert an sxpr to an unsigned integer. */ 6.316 +#define OBJ_UINT(x) get_ul(x) 6.317 +/** Convert an sxpr to an integer. */ 6.318 +#define OBJ_INT(x) (int)get_ul(x) 6.319 + 6.320 +/* Conversions of sxprs to their values. 6.321 + * No checking is done. 6.322 + */ 6.323 +#define OBJ_STRING(x) ((ObjString*)get_ptr(x)) 6.324 +#define OBJ_CONS(x) ((ObjCons*)get_ptr(x)) 6.325 +#define OBJ_ATOM(x) ((ObjAtom*)get_ptr(x)) 6.326 +#define OBJ_SET(x) ((ObjSet*)get_ptr(x)) 6.327 +#define CAR(x) (OBJ_CONS(x)->car) 6.328 +#define CDR(x) (OBJ_CONS(x)->cdr) 6.329 + 6.330 +#define CAAR(x) (CAR(CAR(x))) 6.331 +#define CADR(x) (CAR(CDR(x))) 6.332 +#define CDAR(x) (CDR(CAR(x))) 6.333 +#define CDDR(x) (CDR(CDR(x))) 6.334 + 6.335 /** Checked version of CAR 6.336 * 6.337 * @param x sxpr 6.338 @@ -273,28 +298,10 @@ static inline Sxpr cdr(Sxpr x){ 6.339 return (CONSP(x) ? CDR(x) : ONULL); 6.340 } 6.341 6.342 -/** Allocate some memory and return an sxpr containing it. 6.343 - * Returns ONOMEM if allocation failed. 6.344 - * 6.345 - * @param n number of bytes to allocate 6.346 - * @param ty typecode 6.347 - * @return sxpr 6.348 - */ 6.349 -static inline Sxpr halloc(size_t n, TypeCode ty){ 6.350 - return OBJP(ty, allocate(n)); 6.351 -} 6.352 - 6.353 -/** Allocate an sxpr containing a pointer to the given type. 6.354 - * 6.355 - * @param ty type (uses sizeof to determine how many bytes to allocate) 6.356 - * @param code typecode 6.357 - * @return sxpr, ONOMEM if allocation failed 6.358 - */ 6.359 -#define HALLOC(ty, code) halloc(sizeof(ty), code) 6.360 - 6.361 typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags); 6.362 typedef int ObjEqualFn(Sxpr obj, Sxpr other); 6.363 typedef void ObjFreeFn(Sxpr obj); 6.364 +typedef Sxpr ObjCopyFn(Sxpr obj); 6.365 6.366 /** An sxpr type definition. */ 6.367 typedef struct SxprType { 6.368 @@ -304,6 +311,7 @@ typedef struct SxprType { 6.369 ObjPrintFn *print; 6.370 ObjEqualFn *equal; 6.371 ObjFreeFn *free; 6.372 + ObjCopyFn *copy; 6.373 } SxprType; 6.374 6.375 6.376 @@ -321,6 +329,7 @@ static inline void hfree(Sxpr x){ 6.377 extern int objprint(IOStream *io, Sxpr x, unsigned flags); 6.378 extern int objequal(Sxpr x, Sxpr y); 6.379 extern void objfree(Sxpr x); 6.380 +extern Sxpr objcopy(Sxpr x); 6.381 6.382 extern void cons_free_cells(Sxpr obj); 6.383 extern Sxpr intern(char *s); 6.384 @@ -341,8 +350,10 @@ extern Sxpr cons_remove_if(Sxpr l, ObjEq 6.385 6.386 extern Sxpr atom_new(char *name); 6.387 extern char * atom_name(Sxpr obj); 6.388 +extern int atom_length(Sxpr obj); 6.389 6.390 extern Sxpr string_new(char *s); 6.391 +extern Sxpr string_new_n(char *s, int n); 6.392 extern char * string_string(Sxpr obj); 6.393 extern int string_length(Sxpr obj); 6.394 6.395 @@ -405,15 +416,20 @@ static inline Sxpr mkbool(int b){ 6.396 #define k_true "true" 6.397 #define k_false "false" 6.398 6.399 -#define c_var '$' 6.400 #define c_escape '\\' 6.401 #define c_single_quote '\'' 6.402 #define c_double_quote '"' 6.403 #define c_string_open c_double_quote 6.404 #define c_string_close c_double_quote 6.405 -#define c_data_open '[' 6.406 -#define c_data_close ']' 6.407 -#define c_binary '*' 6.408 + 6.409 +#define c_data_open '<' 6.410 +#define c_data_quote '<' 6.411 +#define c_data_count '*' 6.412 +//#define c_data_open '[' 6.413 +//#define c_data_close ']' 6.414 +//#define c_binary '*' 6.415 + 6.416 +#define c_var '$' 6.417 #define c_eval '!' 6.418 #define c_concat_open '{' 6.419 #define c_concat_close '}'
7.1 --- a/tools/libxutil/sxpr_parser.c Fri May 13 15:01:20 2005 +0000 7.2 +++ b/tools/libxutil/sxpr_parser.c Fri May 13 15:08:29 2005 +0000 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 7.6 + * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com> 7.7 * 7.8 * This library is free software; you can redistribute it and/or modify 7.9 * it under the terms of the GNU Lesser General Public License as 7.10 @@ -26,6 +26,8 @@ 7.11 # include <errno.h> 7.12 #endif 7.13 7.14 +#include "sys_net.h" 7.15 + 7.16 #include "iostream.h" 7.17 #include "lexis.h" 7.18 #include "sxpr_parser.h" 7.19 @@ -42,45 +44,24 @@ 7.20 * @author Mike Wray <mike.wray@hpl.hp.com> 7.21 */ 7.22 7.23 +#ifdef DEBUG 7.24 #define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args) 7.25 +#else 7.26 +#define dprintf(fmt, args...) do{ }while(0) 7.27 +#endif 7.28 + 7.29 #undef printf 7.30 #define printf(fmt, args...) IOStream_print(iostdout, fmt, ##args) 7.31 7.32 -static void reset(Parser *z); 7.33 -static int inputchar(Parser *p, char c); 7.34 -static int savechar(Parser *p, char c); 7.35 -extern void parse_error(Parser *in); 7.36 -extern void parse_error_id(Parser *in, ParseErrorId id); 7.37 - 7.38 +static int state_start(Parser *p, char c); 7.39 static int begin_start(Parser *p, char c); 7.40 -static int state_start(Parser *p, char c); 7.41 -static int end_start(Parser *p); 7.42 - 7.43 -static int begin_comment(Parser *p, char c); 7.44 -static int state_comment(Parser *p, char c); 7.45 -static int end_comment(Parser *p); 7.46 - 7.47 -static int begin_string(Parser *p, char c); 7.48 -static int state_string(Parser *p, char c); 7.49 -static int end_string(Parser *p); 7.50 -static int state_escape(Parser *p, char c); 7.51 -static int state_octal(Parser *p, char c); 7.52 -static int state_hex(Parser *p, char c); 7.53 - 7.54 -static int begin_atom(Parser *p, char c); 7.55 -static int state_atom(Parser *p, char c); 7.56 -static int end_atom(Parser *p); 7.57 - 7.58 -static int state_list(Parser *p, char c); 7.59 -static int begin_list(Parser *p, char c); 7.60 -static int end_list(Parser *p); 7.61 7.62 /** Print a parse error. 7.63 * 7.64 * @param in parser 7.65 * @param msg format followed by printf arguments 7.66 */ 7.67 -void eprintf(Parser *in, char *msg, ...){ 7.68 +static void eprintf(Parser *in, char *msg, ...){ 7.69 va_list args; 7.70 if(in->error_out){ 7.71 va_start(args, msg); 7.72 @@ -94,7 +75,7 @@ void eprintf(Parser *in, char *msg, ...) 7.73 * @param in parser 7.74 * @param msg format followed by printf arguments 7.75 */ 7.76 -void wprintf(Parser *in, char *msg, ...){ 7.77 +static void wprintf(Parser *in, char *msg, ...){ 7.78 va_list args; 7.79 if(in->error_out){ 7.80 va_start(args, msg); 7.81 @@ -107,8 +88,8 @@ void wprintf(Parser *in, char *msg, ...) 7.82 7.83 /** Record defining the message for a parse error. */ 7.84 typedef struct { 7.85 - ParseErrorId id; 7.86 - char *message; 7.87 + ParseErrorId id; 7.88 + char *message; 7.89 } ParseError; 7.90 7.91 /** Format for printing parse error messages. */ 7.92 @@ -116,18 +97,189 @@ typedef struct { 7.93 7.94 /** Message catalog for the parse error codes. */ 7.95 static ParseError catalog[] = { 7.96 - { PARSE_ERR_UNSPECIFIED, "unspecified error" }, 7.97 - { PARSE_ERR_NOMEM, "out of memory" }, 7.98 - { PARSE_ERR_UNEXPECTED_EOF, "unexpected end of input" }, 7.99 - { PARSE_ERR_TOKEN_TOO_LONG, "token too long" }, 7.100 - { PARSE_ERR_INVALID_SYNTAX, "syntax error" }, 7.101 - { PARSE_ERR_INVALID_ESCAPE, "invalid escape" }, 7.102 - { 0, NULL } 7.103 + { PARSE_ERR_UNSPECIFIED, "unspecified error" }, 7.104 + { PARSE_ERR_NOMEM, "out of memory" }, 7.105 + { PARSE_ERR_UNEXPECTED_EOF, "unexpected end of input" }, 7.106 + { PARSE_ERR_TOKEN_TOO_LONG, "token too long" }, 7.107 + { PARSE_ERR_INVALID_SYNTAX, "syntax error" }, 7.108 + { PARSE_ERR_INVALID_ESCAPE, "invalid escape" }, 7.109 + { 0, NULL } 7.110 }; 7.111 7.112 /** Number of entries in the message catalog. */ 7.113 const static int catalog_n = sizeof(catalog)/sizeof(ParseError); 7.114 7.115 +/** Set the parser error stream. 7.116 + * Parse errors are reported on the the error stream if it is non-null. 7.117 + * 7.118 + * @param z parser 7.119 + * @param error_out error stream 7.120 + */ 7.121 +void Parser_set_error_stream(Parser *z, IOStream *error_out){ 7.122 + z->error_out = error_out; 7.123 +} 7.124 + 7.125 +/** Get the parser error message for an error code. 7.126 + * 7.127 + * @param id error code 7.128 + * @return error message (empty string if the code is unknown) 7.129 + */ 7.130 +static char *get_message(ParseErrorId id){ 7.131 + int i; 7.132 + for(i = 0; i < catalog_n; i++){ 7.133 + if(id == catalog[i].id){ 7.134 + return catalog[i].message; 7.135 + } 7.136 + } 7.137 + return ""; 7.138 +} 7.139 + 7.140 +/** Get the line number. 7.141 + * 7.142 + * @param in parser 7.143 + */ 7.144 +static int get_line(Parser *in){ 7.145 + return in->line_no; 7.146 +} 7.147 + 7.148 +/** Get the column number. 7.149 + * 7.150 + * @param in parser 7.151 + */ 7.152 +static int get_column(Parser *in){ 7.153 + return in->char_no; 7.154 +} 7.155 + 7.156 +/** Get the line number the current token started on. 7.157 + * 7.158 + * @param in parser 7.159 + */ 7.160 +static int get_tok_line(Parser *in){ 7.161 + return in->tok_begin_line; 7.162 +} 7.163 + 7.164 +/** Get the column number the current token started on. 7.165 + * 7.166 + * @param in parser 7.167 + */ 7.168 +static int get_tok_column(Parser *in){ 7.169 + return in->tok_begin_char; 7.170 +} 7.171 + 7.172 +/** Return the current token. 7.173 + * The return value points at the internal buffer, so 7.174 + * it must not be modified (or freed). Use copy_token() if you need a copy. 7.175 + * 7.176 + * @param p parser 7.177 + * @return token 7.178 + */ 7.179 +char *peek_token(Parser *p){ 7.180 + return p->tok; 7.181 +} 7.182 + 7.183 +int token_len(Parser *p){ 7.184 + return p->tok_end - p->tok; 7.185 +} 7.186 + 7.187 +/** Return a copy of the current token. 7.188 + * The returned value should be freed when finished with. 7.189 + * 7.190 + * @param p parser 7.191 + * @return copy of token 7.192 + */ 7.193 +char *copy_token(Parser *p){ 7.194 + int n = token_len(p); 7.195 + char *buf = allocate(n + 1); 7.196 + if(buf){ 7.197 + memcpy(buf, peek_token(p), n); 7.198 + buf[n] = '\0'; 7.199 + } 7.200 + return buf; 7.201 +} 7.202 + 7.203 +void new_token(Parser *p){ 7.204 + memset(p->buf, 0, p->buf_end - p->buf); 7.205 + p->tok = p->buf; 7.206 + p->tok_end = p->tok; 7.207 + p->tok_begin_line = p->line_no; 7.208 + p->tok_begin_char = p->char_no; 7.209 +} 7.210 + 7.211 +/** Report a parse error. 7.212 + * Does nothing if the error stream is null or there is no error. 7.213 + * 7.214 + * @param in parser 7.215 + */ 7.216 +static void report_error(Parser *in){ 7.217 + if(in->error_out && in->err){ 7.218 + char *msg = get_message(in->err); 7.219 + char *tok = peek_token(in); 7.220 + IOStream_print(in->error_out, PARSE_ERR_FMT, 7.221 + get_tok_line(in), get_tok_column(in), msg); 7.222 + if(tok && tok[0]){ 7.223 + IOStream_print(in->error_out, " '%s'", tok); 7.224 + } 7.225 + IOStream_print(in->error_out, "\n"); 7.226 + } 7.227 +} 7.228 + 7.229 +/** Get the error message for the current parse error code. 7.230 + * Does nothing if there is no error. 7.231 + * 7.232 + * @param in parser 7.233 + * @param buf where to place the message 7.234 + * @param n maximum number of characters to place in buf 7.235 + * @return current error code (zero for no error) 7.236 + */ 7.237 +int Parser_error_message(Parser *in, char *buf, int n){ 7.238 + if(in->err){ 7.239 + char *msg = get_message(in->err); 7.240 + snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in), 7.241 + get_tok_column(in), msg); 7.242 + } 7.243 + return in->err; 7.244 +} 7.245 + 7.246 +/** Flag a parse error. All subsequent reads will fail. 7.247 + * Does not change the parser error code if it is already set. 7.248 + * 7.249 + * @param in parser 7.250 + * @param id error code 7.251 + */ 7.252 +int Parser_error_id(Parser *in, ParseErrorId id){ 7.253 + if(!in->err){ 7.254 + in->err = id; 7.255 + report_error(in); 7.256 + } 7.257 + return -EINVAL; 7.258 +} 7.259 + 7.260 +/** Flag an unspecified parse error. 7.261 + * 7.262 + * @param in parser 7.263 + */ 7.264 +int Parser_error(Parser *in){ 7.265 + return Parser_error_id(in, PARSE_ERR_INVALID_SYNTAX); 7.266 +} 7.267 + 7.268 +/** Test if the parser's error flag is set. 7.269 + * 7.270 + * @param in parser 7.271 + * @return 1 if set, 0 otherwise 7.272 + */ 7.273 +int Parser_has_error(Parser *in){ 7.274 + return (in->err > 0); 7.275 +} 7.276 + 7.277 +/** Test if the parser is at end of input. 7.278 + * 7.279 + * @param in parser 7.280 + * @return 1 if at EOF, 0 otherwise 7.281 + */ 7.282 +int Parser_at_eof(Parser *p){ 7.283 + return p->eof; 7.284 +} 7.285 + 7.286 void ParserState_free(ParserState *z){ 7.287 if(!z) return; 7.288 objfree(z->val); 7.289 @@ -136,19 +288,28 @@ void ParserState_free(ParserState *z){ 7.290 7.291 int ParserState_new(ParserStateFn *fn, char *name, 7.292 ParserState *parent, ParserState **val){ 7.293 - int err = 0; 7.294 + int err = -ENOMEM; 7.295 ParserState *z; 7.296 z = ALLOCATE(ParserState); 7.297 - if(z){ 7.298 - z->name = name; 7.299 - z->fn = fn; 7.300 - z->parent = parent; 7.301 - z->val = ONULL; 7.302 - } else { 7.303 - err = -ENOMEM; 7.304 + if(!z) goto exit; 7.305 + z->name = name; 7.306 + z->fn = fn; 7.307 + z->parent = parent; 7.308 + z->val = ONULL; 7.309 + err = 0; 7.310 + exit: 7.311 + *val = (err ? NULL : z); 7.312 + return err; 7.313 +} 7.314 + 7.315 +void Parser_pop(Parser *p){ 7.316 + ParserState *s = p->state; 7.317 + if(!s) return; 7.318 + p->state = s->parent; 7.319 + if (p->start_state == s) { 7.320 + p->start_state = NULL; 7.321 } 7.322 - if(!err) *val = z; 7.323 - return err; 7.324 + ParserState_free(s); 7.325 } 7.326 7.327 /** Free a parser. 7.328 @@ -158,19 +319,80 @@ int ParserState_new(ParserStateFn *fn, c 7.329 */ 7.330 void Parser_free(Parser *z){ 7.331 if(!z) return; 7.332 + // Hmmm. Need to free states, but careful about double free of values. 7.333 + while(z->state){ 7.334 + objfree(z->state->val); 7.335 + Parser_pop(z); 7.336 + } 7.337 + if(z->buf) deallocate(z->buf); 7.338 objfree(z->val); 7.339 z->val = ONONE; 7.340 deallocate(z); 7.341 } 7.342 7.343 +int Parser_push(Parser *p, ParserStateFn *fn, char *name){ 7.344 + return ParserState_new(fn, name, p->state, &p->state); 7.345 +} 7.346 + 7.347 +int Parser_return(Parser *p){ 7.348 + int err = 0; 7.349 + Sxpr val = ONONE; 7.350 + if(!p->state){ 7.351 + err = -EINVAL; 7.352 + goto exit; 7.353 + } 7.354 + val = p->state->val; 7.355 + p->state->val = ONONE; 7.356 + Parser_pop(p); 7.357 + if(p->state){ 7.358 + err = cons_push(&p->state->val, val); 7.359 + } else { 7.360 + val = nrev(val); 7.361 + p->val = val; 7.362 + } 7.363 + exit: 7.364 + if(err){ 7.365 + objfree(val); 7.366 + } 7.367 + return err; 7.368 +} 7.369 + 7.370 +/** Reset the fields of a parser to initial values. 7.371 + * 7.372 + * @param z parser 7.373 + */ 7.374 +static void reset(Parser *z){ 7.375 + // leave flags 7.376 + // leave error_out 7.377 + while(z->state){ 7.378 + Parser_pop(z); 7.379 + } 7.380 + z->val = ONONE; 7.381 + z->eof = 0; 7.382 + z->err = 0; 7.383 + z->line_no = 1; 7.384 + z->char_no = 0; 7.385 + memset(z->buf, 0, z->buf_end - z->buf); 7.386 + z->tok = z->buf; 7.387 + z->tok_end = z->tok; 7.388 + z->tok_begin_line = 0; 7.389 + z->tok_begin_char = 0; 7.390 + z->start_state = NULL; 7.391 +} 7.392 + 7.393 /** Create a new parser. The error stream defaults to null. 7.394 */ 7.395 Parser * Parser_new(void){ 7.396 Parser *z = ALLOCATE(Parser); 7.397 + int n = PARSER_BUF_SIZE; 7.398 int err = -ENOMEM; 7.399 7.400 if(!z) goto exit; 7.401 + z->buf = allocate(n); 7.402 + if(!z->buf) goto exit; 7.403 err = 0; 7.404 + z->buf_end = z->buf + n; 7.405 + z->begin = begin_start; 7.406 reset(z); 7.407 exit: 7.408 if(err){ 7.409 @@ -187,7 +409,7 @@ Parser * Parser_new(void){ 7.410 * @param p parser 7.411 * @return error flag: 0 on success, non-zero on error 7.412 */ 7.413 -static int inputchar(Parser *p, char c){ 7.414 +static int input_char(Parser *p, char c){ 7.415 int err = 0; 7.416 if(c=='\n'){ 7.417 p->line_no++; 7.418 @@ -198,95 +420,24 @@ static int inputchar(Parser *p, char c){ 7.419 return err; 7.420 } 7.421 7.422 -static int savechar(Parser *p, char c){ 7.423 - int err = 0; 7.424 - if(p->buf_i >= p->buf_n){ 7.425 - err = -ENOMEM; 7.426 - goto exit; 7.427 - } 7.428 - p->buf[p->buf_i] = c; 7.429 - p->buf_i++; 7.430 - exit: 7.431 - return err; 7.432 -} 7.433 - 7.434 -int Parser_input_char(Parser *p, char c){ 7.435 +int save_char(Parser *p, char c){ 7.436 int err = 0; 7.437 - if(at_eof(p)){ 7.438 - //skip; 7.439 - } else { 7.440 - inputchar(p, c); 7.441 - } 7.442 - if(!p->state){ 7.443 - err = begin_start(p, c); 7.444 - if(err) goto exit; 7.445 - } 7.446 - err = p->state->fn(p, c); 7.447 - exit: 7.448 - return err; 7.449 -} 7.450 - 7.451 -int Parser_input_eof(Parser *p){ 7.452 - int err = 0; 7.453 - p->eof = 1; 7.454 - err = Parser_input_char(p, IOSTREAM_EOF); 7.455 - return err; 7.456 -} 7.457 - 7.458 -int Parser_input(Parser *p, char *buf, int buf_n){ 7.459 - int err = 0; 7.460 - int i = 0; 7.461 - if(buf_n <= 0){ 7.462 - err = Parser_input_eof(p); 7.463 - goto exit; 7.464 + if(p->tok_end >= p->buf_end){ 7.465 + int buf_n = (p->buf_end - p->buf) + PARSER_BUF_INCREMENT; 7.466 + char *buf = allocate(buf_n); 7.467 + if(!buf){ 7.468 + err = -ENOMEM; 7.469 + goto exit; 7.470 + } 7.471 + memcpy(buf, p->buf, p->tok_end - p->buf); 7.472 + p->buf_end = buf + buf_n; 7.473 + p->tok = buf + (p->tok - p->buf); 7.474 + p->tok_end = buf + (p->tok_end - p->buf); 7.475 + deallocate(p->buf); 7.476 + p->buf = buf; 7.477 } 7.478 - for(i = 0; i<buf_n; i++){ 7.479 - err = Parser_input_char(p, buf[i]); 7.480 - if(err) goto exit; 7.481 - } 7.482 + *p->tok_end++ = c; 7.483 exit: 7.484 - err = (err < 0 ? err : buf_n); 7.485 - return err; 7.486 -} 7.487 - 7.488 -int Parser_push(Parser *p, ParserStateFn *fn, char *name){ 7.489 - int err = 0; 7.490 - err = ParserState_new(fn, name, p->state, &p->state); 7.491 - return err; 7.492 -} 7.493 - 7.494 -int Parser_pop(Parser *p){ 7.495 - int err = 0; 7.496 - ParserState *s = p->state; 7.497 - p->state = s->parent; 7.498 - if (p->start_state == s) { 7.499 - p->start_state = NULL; 7.500 - } 7.501 - ParserState_free(s); 7.502 - return err; 7.503 -} 7.504 - 7.505 -int Parser_return(Parser *p){ 7.506 - int err = 0; 7.507 - Sxpr val = ONONE; 7.508 - if(!p->state){ 7.509 - err = -EINVAL; 7.510 - goto exit; 7.511 - } 7.512 - val = p->state->val; 7.513 - p->state->val = ONONE; 7.514 - err = Parser_pop(p); 7.515 - if(err) goto exit; 7.516 - if(p->state){ 7.517 - err = cons_push(&p->state->val, val); 7.518 - } else { 7.519 - val = nrev(val); 7.520 - p->val = val; 7.521 - } 7.522 - exit: 7.523 - if(err){ 7.524 - objfree(val); 7.525 - } 7.526 return err; 7.527 } 7.528 7.529 @@ -300,30 +451,8 @@ static int is_separator(Parser *p, char 7.530 return in_sep_class(c); 7.531 } 7.532 7.533 -/** Return the current token. 7.534 - * The return value points at the internal buffer, so 7.535 - * it must not be modified (or freed). Use copy_token() if you need a copy. 7.536 - * 7.537 - * @param p parser 7.538 - * @return token 7.539 - */ 7.540 -char *peek_token(Parser *p){ 7.541 - return p->buf; 7.542 -} 7.543 - 7.544 -/** Return a copy of the current token. 7.545 - * The returned value should be freed when finished with. 7.546 - * 7.547 - * @param p parser 7.548 - * @return copy of token 7.549 - */ 7.550 -char *copy_token(Parser *p){ 7.551 - return strdup(peek_token(p)); 7.552 -} 7.553 - 7.554 -static int do_intern(Parser *p){ 7.555 +int Parser_set_value(Parser *p, Sxpr obj){ 7.556 int err = 0; 7.557 - Sxpr obj = intern(peek_token(p)); 7.558 if(NOMEMP(obj)){ 7.559 err = -ENOMEM; 7.560 } else { 7.561 @@ -331,27 +460,33 @@ static int do_intern(Parser *p){ 7.562 } 7.563 return err; 7.564 } 7.565 + 7.566 +int Parser_intern(Parser *p){ 7.567 + Sxpr obj = intern(peek_token(p)); 7.568 + return Parser_set_value(p, obj); 7.569 +} 7.570 7.571 -static int do_string(Parser *p){ 7.572 - int err = 0; 7.573 - Sxpr obj; 7.574 - obj = string_new(peek_token(p)); 7.575 - if(NOMEMP(obj)){ 7.576 - err = -ENOMEM; 7.577 - } else { 7.578 - p->state->val = obj; 7.579 - } 7.580 - return err; 7.581 +int Parser_atom(Parser *p){ 7.582 + Sxpr obj = atom_new(peek_token(p)); 7.583 + return Parser_set_value(p, obj); 7.584 } 7.585 7.586 -void newtoken(Parser *p){ 7.587 - memset(p->buf, 0, p->buf_n); 7.588 - p->buf_i = 0; 7.589 - p->tok_begin_line = p->line_no; 7.590 - p->tok_begin_char = p->char_no; 7.591 +int Parser_string(Parser *p){ 7.592 + Sxpr obj = string_new_n(peek_token(p), token_len(p)); 7.593 + return Parser_set_value(p, obj); 7.594 } 7.595 7.596 -int get_escape(char c, char *d){ 7.597 +int Parser_data(Parser *p){ 7.598 + Sxpr obj = string_new_n(peek_token(p), token_len(p)); 7.599 + return Parser_set_value(p, obj); 7.600 +} 7.601 + 7.602 +int Parser_uint(Parser *p){ 7.603 + unsigned int x = htonl(*(unsigned int *)peek_token(p)); 7.604 + return Parser_set_value(p, OINT(x)); 7.605 +} 7.606 + 7.607 +static int get_escape(char c, char *d){ 7.608 int err = 0; 7.609 switch(c){ 7.610 case 'a': *d = '\a'; break; 7.611 @@ -377,15 +512,18 @@ int Parser_ready(Parser *p){ 7.612 Sxpr Parser_get_val(Parser *p){ 7.613 Sxpr v = ONONE; 7.614 if(CONSP(p->val)){ 7.615 - v = CAR(p->val); 7.616 - p->val = CDR(p->val); 7.617 - } else if (CONSP(p->start_state->val)){ 7.618 + } else if (p->start_state && CONSP(p->start_state->val)){ 7.619 p->val = p->start_state->val; 7.620 p->val = nrev(p->val); 7.621 p->start_state->val = ONULL; 7.622 - v = CAR(p->val); 7.623 - p->val = CDR(p->val); 7.624 - } 7.625 + } else { 7.626 + goto exit; 7.627 + } 7.628 + Sxpr w = p->val; 7.629 + v = CAR(w); 7.630 + p->val = CDR(w); 7.631 + hfree(w); 7.632 + exit: 7.633 return v; 7.634 } 7.635 7.636 @@ -401,118 +539,132 @@ Sxpr Parser_get_all(Parser *p){ 7.637 } 7.638 return v; 7.639 } 7.640 - 7.641 -int begin_start(Parser *p, char c){ 7.642 - int err = 0; 7.643 - err = Parser_push(p, state_start, "start"); 7.644 - if(err) goto exit; 7.645 - p->start_state = p->state; 7.646 - exit: 7.647 - return err; 7.648 -} 7.649 7.650 -int state_start(Parser *p, char c){ 7.651 +static int state_comment(Parser *p, char c){ 7.652 int err = 0; 7.653 - if(at_eof(p)){ 7.654 - err = end_start(p); 7.655 - } else if(in_space_class(c)){ 7.656 - //skip 7.657 - } else if(in_comment_class(c)){ 7.658 - begin_comment(p, c); 7.659 - } else if(c == c_list_open){ 7.660 - begin_list(p, c); 7.661 - } else if(c == c_list_close){ 7.662 - parse_error(p); 7.663 - err = -EINVAL; 7.664 - } else if(in_string_quote_class(c)){ 7.665 - begin_string(p, c); 7.666 - } else if(in_printable_class(c)){ 7.667 - begin_atom(p, c); 7.668 - } else if(c == 0x04){ 7.669 - //ctrl-D, EOT: end-of-text. 7.670 - Parser_input_eof(p); 7.671 + if(c == '\n' || Parser_at_eof(p)){ 7.672 + Parser_pop(p); 7.673 } else { 7.674 - parse_error(p); 7.675 - err = -EINVAL; 7.676 + err = input_char(p, c); 7.677 } 7.678 return err; 7.679 } 7.680 7.681 -int end_start(Parser *p){ 7.682 - int err = 0; 7.683 - err = Parser_return(p); 7.684 - return err; 7.685 -} 7.686 - 7.687 -int begin_comment(Parser *p, char c){ 7.688 +static int begin_comment(Parser *p, char c){ 7.689 int err = 0; 7.690 err = Parser_push(p, state_comment, "comment"); 7.691 if(err) goto exit; 7.692 - err = inputchar(p, c); 7.693 + err = input_char(p, c); 7.694 exit: 7.695 return err; 7.696 } 7.697 7.698 -int state_comment(Parser *p, char c){ 7.699 - int err = 0; 7.700 - if(c == '\n' || at_eof(p)){ 7.701 - err = end_comment(p); 7.702 - } else { 7.703 - err = inputchar(p, c); 7.704 - } 7.705 - return err; 7.706 -} 7.707 - 7.708 -int end_comment(Parser *p){ 7.709 - return Parser_pop(p); 7.710 -} 7.711 - 7.712 -int begin_string(Parser *p, char c){ 7.713 +static int end_string(Parser *p){ 7.714 int err = 0; 7.715 - err = Parser_push(p, state_string, "string"); 7.716 - if(err) goto exit; 7.717 - newtoken(p); 7.718 - p->state->delim = c; 7.719 - exit: 7.720 - return err; 7.721 -} 7.722 - 7.723 -int state_string(Parser *p, char c){ 7.724 - int err = 0; 7.725 - if(at_eof(p)){ 7.726 - parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.727 - err = -EINVAL; 7.728 - } else if(c == p->state->delim){ 7.729 - err = end_string(p); 7.730 - } else if(c == '\\'){ 7.731 - err = Parser_push(p, state_escape, "escape"); 7.732 - } else { 7.733 - err = savechar(p, c); 7.734 - } 7.735 - return err; 7.736 -} 7.737 - 7.738 -int end_string(Parser *p){ 7.739 - int err = 0; 7.740 - err = do_string(p); 7.741 + err = Parser_string(p); 7.742 if(err) goto exit; 7.743 err = Parser_return(p); 7.744 exit: 7.745 return err; 7.746 } 7.747 7.748 -int state_escape(Parser *p, char c){ 7.749 +static int octaldone(Parser *p){ 7.750 + int err = 0; 7.751 + char d = (char)(p->state->ival & 0xff); 7.752 + Parser_pop(p); 7.753 + err = Parser_input_char(p, d); 7.754 + return err; 7.755 +} 7.756 + 7.757 +static int octaldigit(Parser *p, int d){ 7.758 + int err = 0; 7.759 + p->state->ival *= 8; 7.760 + p->state->ival += d; 7.761 + p->state->count++; 7.762 + if(err) goto exit; 7.763 + if(p->state->ival < 0 || p->state->ival > 0xff){ 7.764 + err = Parser_error(p); 7.765 + goto exit; 7.766 + } 7.767 + if(p->state->count == 3){ 7.768 + err = octaldone(p); 7.769 + } 7.770 + exit: 7.771 + return err; 7.772 +} 7.773 + 7.774 +static int state_octal(Parser *p, char c){ 7.775 + int err = 0; 7.776 + if(Parser_at_eof(p)){ 7.777 + err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.778 + goto exit; 7.779 + } else if('0' <= c && c <= '7'){ 7.780 + err = octaldigit(p, c - '0'); 7.781 + } else { 7.782 + err = octaldone(p); 7.783 + if(err) goto exit; 7.784 + Parser_input_char(p, c); 7.785 + } 7.786 + exit: 7.787 + return err; 7.788 +} 7.789 + 7.790 +static int hexdone(Parser *p){ 7.791 + int err = 0; 7.792 + char d = (char)(p->state->ival & 0xff); 7.793 + Parser_pop(p); 7.794 + err = Parser_input_char(p, d); 7.795 + return err; 7.796 +} 7.797 + 7.798 +static int hexdigit(Parser *p, int d){ 7.799 + int err = 0; 7.800 + p->state->ival *= 16; 7.801 + p->state->ival += d; 7.802 + p->state->count++; 7.803 + if(err) goto exit; 7.804 + if(p->state->ival < 0 || p->state->ival > 0xff){ 7.805 + err = Parser_error(p); 7.806 + goto exit; 7.807 + } 7.808 + if(p->state->count == 2){ 7.809 + err = hexdone(p); 7.810 + } 7.811 + exit: 7.812 + return err; 7.813 +} 7.814 + 7.815 +static int state_hex(Parser *p, char c){ 7.816 + int err = 0; 7.817 + if(Parser_at_eof(p)){ 7.818 + err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.819 + goto exit; 7.820 + } else if('0' <= c && c <= '9'){ 7.821 + err = hexdigit(p, c - '0'); 7.822 + } else if('A' <= c && c <= 'F'){ 7.823 + err = hexdigit(p, c - 'A' + 10); 7.824 + } else if('a' <= c && c <= 'f'){ 7.825 + err = hexdigit(p, c - 'a' + 10); 7.826 + } else if(p->state->count){ 7.827 + err = hexdone(p); 7.828 + if(err) goto exit; 7.829 + Parser_input_char(p, c); 7.830 + } 7.831 + exit: 7.832 + return err; 7.833 +} 7.834 + 7.835 +static int state_escape(Parser *p, char c){ 7.836 int err = 0; 7.837 char d; 7.838 - if(at_eof(p)){ 7.839 - parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.840 - err = -EINVAL; 7.841 + if(Parser_at_eof(p)){ 7.842 + err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.843 goto exit; 7.844 } 7.845 if(get_escape(c, &d) == 0){ 7.846 - err = savechar(p, d); 7.847 + err = save_char(p, d); 7.848 if(err) goto exit; 7.849 - err = Parser_pop(p); 7.850 + Parser_pop(p); 7.851 } else if(c == 'x'){ 7.852 p->state->fn = state_hex; 7.853 p->state->ival = 0; 7.854 @@ -527,113 +679,42 @@ int state_escape(Parser *p, char c){ 7.855 return err; 7.856 } 7.857 7.858 -int octaldone(Parser *p){ 7.859 +static int state_string(Parser *p, char c){ 7.860 int err = 0; 7.861 - char d = (char)(p->state->ival & 0xff); 7.862 - err = Parser_pop(p); 7.863 - if(err) goto exit; 7.864 - err = Parser_input_char(p, d); 7.865 - exit: 7.866 + if(Parser_at_eof(p)){ 7.867 + err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.868 + } else if(c == p->state->delim){ 7.869 + err = end_string(p); 7.870 + } else if(c == '\\'){ 7.871 + err = Parser_push(p, state_escape, "escape"); 7.872 + } else { 7.873 + err = save_char(p, c); 7.874 + } 7.875 return err; 7.876 } 7.877 7.878 -int octaldigit(Parser *p, char c){ 7.879 +static int begin_string(Parser *p, char c){ 7.880 int err = 0; 7.881 - p->state->ival *= 8; 7.882 - p->state->ival += c - '0'; 7.883 - p->state->count++; 7.884 + err = Parser_push(p, state_string, "string"); 7.885 if(err) goto exit; 7.886 - if(p->state->ival < 0 || p->state->ival > 0xff){ 7.887 - parse_error(p); 7.888 - err = -EINVAL; 7.889 - goto exit; 7.890 - } 7.891 - if(p->state->count == 3){ 7.892 - err = octaldone(p); 7.893 - } 7.894 - exit: 7.895 - return err; 7.896 -} 7.897 - 7.898 -int state_octal(Parser *p, char c){ 7.899 - int err = 0; 7.900 - if(at_eof(p)){ 7.901 - parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.902 - err = -EINVAL; 7.903 - goto exit; 7.904 - } else if('0' <= c && c <= '7'){ 7.905 - err = octaldigit(p, c); 7.906 - } else { 7.907 - err = octaldone(p); 7.908 - if(err) goto exit; 7.909 - Parser_input_char(p, c); 7.910 - } 7.911 + new_token(p); 7.912 + p->state->delim = c; 7.913 exit: 7.914 return err; 7.915 } 7.916 7.917 -int hexdone(Parser *p){ 7.918 +static int end_atom(Parser *p){ 7.919 int err = 0; 7.920 - char d = (char)(p->state->ival & 0xff); 7.921 - err = Parser_pop(p); 7.922 - if(err) goto exit; 7.923 - err = Parser_input_char(p, d); 7.924 - exit: 7.925 - return err; 7.926 -} 7.927 - 7.928 -int hexdigit(Parser *p, char c, char d){ 7.929 - int err = 0; 7.930 - p->state->ival *= 16; 7.931 - p->state->ival += c - d; 7.932 - p->state->count++; 7.933 + err = Parser_atom(p); 7.934 if(err) goto exit; 7.935 - if(p->state->ival < 0 || p->state->ival > 0xff){ 7.936 - parse_error(p); 7.937 - err = -EINVAL; 7.938 - goto exit; 7.939 - } 7.940 - if(p->state->count == 2){ 7.941 - err = hexdone(p); 7.942 - } 7.943 - exit: 7.944 - return err; 7.945 -} 7.946 - 7.947 -int state_hex(Parser *p, char c){ 7.948 - int err = 0; 7.949 - if(at_eof(p)){ 7.950 - parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.951 - err = -EINVAL; 7.952 - goto exit; 7.953 - } else if('0' <= c && c <= '9'){ 7.954 - err = hexdigit(p, c, '0'); 7.955 - } else if('A' <= c && c <= 'F'){ 7.956 - err = hexdigit(p, c, 'A'); 7.957 - } else if('a' <= c && c <= 'f'){ 7.958 - err = hexdigit(p, c, 'a'); 7.959 - } else if(p->state->count){ 7.960 - err =hexdone(p); 7.961 - if(err) goto exit; 7.962 - Parser_input_char(p, c); 7.963 - } 7.964 + err = Parser_return(p); 7.965 exit: 7.966 return err; 7.967 } 7.968 7.969 -int begin_atom(Parser *p, char c){ 7.970 +static int state_atom(Parser *p, char c){ 7.971 int err = 0; 7.972 - err = Parser_push(p, state_atom, "atom"); 7.973 - if(err) goto exit; 7.974 - newtoken(p); 7.975 - err = savechar(p, c); 7.976 - exit: 7.977 - return err; 7.978 -} 7.979 - 7.980 -int state_atom(Parser *p, char c){ 7.981 - int err = 0; 7.982 - if(at_eof(p)){ 7.983 + if(Parser_at_eof(p)){ 7.984 err = end_atom(p); 7.985 } else if(is_separator(p, c) || 7.986 in_space_class(c) || 7.987 @@ -642,257 +723,231 @@ int state_atom(Parser *p, char c){ 7.988 if(err) goto exit; 7.989 err = Parser_input_char(p, c); 7.990 } else { 7.991 - err = savechar(p, c); 7.992 + err = save_char(p, c); 7.993 } 7.994 exit: 7.995 return err; 7.996 } 7.997 7.998 -int end_atom(Parser *p){ 7.999 +static int begin_atom(Parser *p, char c){ 7.1000 int err = 0; 7.1001 - err = do_intern(p); 7.1002 + err = Parser_push(p, state_atom, "atom"); 7.1003 + if(err) goto exit; 7.1004 + new_token(p); 7.1005 + err = save_char(p, c); 7.1006 + exit: 7.1007 + return err; 7.1008 +} 7.1009 + 7.1010 +static int end_data(Parser *p){ 7.1011 + int err = 0; 7.1012 + err = Parser_data(p); 7.1013 if(err) goto exit; 7.1014 err = Parser_return(p); 7.1015 exit: 7.1016 return err; 7.1017 } 7.1018 7.1019 -int state_list(Parser *p, char c){ 7.1020 +static int counted_data(Parser *p, char c){ 7.1021 + int err = 0; 7.1022 + err = save_char(p, c); 7.1023 + if(err) goto exit; 7.1024 + if(token_len(p) == p->state->count){ 7.1025 + err = end_data(p); 7.1026 + } 7.1027 + exit: 7.1028 + return err; 7.1029 +} 7.1030 + 7.1031 +static int counted_data_count(Parser *p, char c){ 7.1032 + int err = 0; 7.1033 + if(c == p->state->delim){ 7.1034 + new_token(p); 7.1035 + p->state->count = p->state->ival; 7.1036 + p->state->fn = counted_data; 7.1037 + } else if('0' <= c && c <= '9'){ 7.1038 + p->state->ival *= 10; 7.1039 + p->state->ival += c - '0'; 7.1040 + } else { 7.1041 + err = -EINVAL; 7.1042 + } 7.1043 + return err; 7.1044 +} 7.1045 + 7.1046 +static int quoted_data(Parser *p, char c){ 7.1047 + int err = 0; 7.1048 + int count = p->state->count; 7.1049 + err = save_char(p, c); 7.1050 + if(err) goto exit; 7.1051 + // Check that buf is longer than delim and 7.1052 + // ends with delim. If so, trim delim off and return. 7.1053 + if((token_len(p) >= count) && 7.1054 + !memcmp(p->tok_end - count, p->buf, count)){ 7.1055 + p->tok_end -= count; 7.1056 + end_data(p); 7.1057 + } 7.1058 + exit: 7.1059 + return err; 7.1060 +} 7.1061 + 7.1062 +static int quoted_data_delim(Parser *p, char c){ 7.1063 + // Saves the delim in the token buffer. 7.1064 int err = 0; 7.1065 - if(at_eof(p)){ 7.1066 - parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.1067 - err = -EINVAL; 7.1068 + err = save_char(p, c); 7.1069 + if(err) goto exit; 7.1070 + if(c == p->state->delim){ 7.1071 + p->state->fn = quoted_data; 7.1072 + p->state->count = token_len(p); 7.1073 + // Advance the token pointer past the delim. 7.1074 + p->tok = p->tok_end; 7.1075 + } 7.1076 + exit: 7.1077 + return err; 7.1078 +} 7.1079 + 7.1080 +static int state_data(Parser *p, char c){ 7.1081 + // Quoted data: 7.1082 + // <<delim< anything not containing delimiter<delim< 7.1083 + // Where 'delim' is anything not containing '<'. 7.1084 + // Counted data: 7.1085 + // <*nnn..* N bytes 7.1086 + // Where nnn... is N in decimal ( 7.1087 + int err = 0; 7.1088 + switch(c){ 7.1089 + case c_data_count: 7.1090 + p->state->delim = c; 7.1091 + p->state->fn = counted_data_count; 7.1092 + p->state->ival = 0; 7.1093 + new_token(p); 7.1094 + break; 7.1095 + case c_data_quote: 7.1096 + p->state->delim = c; 7.1097 + p->state->fn = quoted_data_delim; 7.1098 + new_token(p); 7.1099 + err = save_char(p, c); 7.1100 + break; 7.1101 + default: 7.1102 + err = Parser_error(p); 7.1103 + break; 7.1104 + } 7.1105 + return err; 7.1106 +} 7.1107 + 7.1108 +static int begin_data(Parser *p, char c){ 7.1109 + int err = 0; 7.1110 + err = Parser_push(p, state_data, "data"); 7.1111 + if(err) goto exit; 7.1112 + new_token(p); 7.1113 + exit: 7.1114 + return err; 7.1115 +} 7.1116 + 7.1117 +static int state_list(Parser *p, char c){ 7.1118 + int err = 0; 7.1119 + dprintf(">\n"); 7.1120 + if(Parser_at_eof(p)){ 7.1121 + err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); 7.1122 } else if(c == c_list_close){ 7.1123 p->state->val = nrev(p->state->val); 7.1124 - err = end_list(p); 7.1125 + err = Parser_return(p); 7.1126 } else { 7.1127 err = state_start(p, c); 7.1128 } 7.1129 + dprintf("< err=%d\n", err); 7.1130 return err; 7.1131 7.1132 } 7.1133 7.1134 -int begin_list(Parser *p, char c){ 7.1135 +static int begin_list(Parser *p, char c){ 7.1136 return Parser_push(p, state_list, "list"); 7.1137 } 7.1138 7.1139 -int end_list(Parser *p){ 7.1140 - return Parser_return(p); 7.1141 -} 7.1142 - 7.1143 -/** Reset the fields of a parser to initial values. 7.1144 - * 7.1145 - * @param z parser 7.1146 - */ 7.1147 -static void reset(Parser *z){ 7.1148 - IOStream *error_out = z->error_out; 7.1149 - int flags = z->flags; 7.1150 - memzero(z, sizeof(Parser)); 7.1151 - z->buf_n = sizeof(z->buf) - 1; 7.1152 - z->buf_i = 0; 7.1153 - z->line_no = 1; 7.1154 - z->char_no = 0; 7.1155 - z->error_out = error_out; 7.1156 - z->flags = flags; 7.1157 -} 7.1158 - 7.1159 -/** Set the parser error stream. 7.1160 - * Parse errors are reported on the the error stream if it is non-null. 7.1161 - * 7.1162 - * @param z parser 7.1163 - * @param error_out error stream 7.1164 - */ 7.1165 -void set_error_stream(Parser *z, IOStream *error_out){ 7.1166 - if(z){ 7.1167 - z->error_out = error_out; 7.1168 - } 7.1169 +static int state_start(Parser *p, char c){ 7.1170 + int err = 0; 7.1171 + dprintf(">\n"); 7.1172 + if(Parser_at_eof(p)){ 7.1173 + err = Parser_return(p); 7.1174 + } else if(in_space_class(c)){ 7.1175 + //skip 7.1176 + } else if(in_comment_class(c)){ 7.1177 + begin_comment(p, c); 7.1178 + } else if(c == c_list_open){ 7.1179 + begin_list(p, c); 7.1180 + } else if(c == c_list_close){ 7.1181 + err = Parser_error(p); 7.1182 + } else if(in_string_quote_class(c)){ 7.1183 + begin_string(p, c); 7.1184 + } else if(c == c_data_open){ 7.1185 + begin_data(p, c); 7.1186 + } else if(in_printable_class(c)){ 7.1187 + begin_atom(p, c); 7.1188 + } else if(c == 0x04){ 7.1189 + //ctrl-D, EOT: end-of-text. 7.1190 + Parser_input_eof(p); 7.1191 + } else { 7.1192 + err = Parser_error(p); 7.1193 + } 7.1194 + dprintf("< err=%d\n", err); 7.1195 + return err; 7.1196 } 7.1197 7.1198 -/** Get the parser error message for an error code. 7.1199 - * 7.1200 - * @param id error code 7.1201 - * @return error message (empty string if the code is unknown) 7.1202 - */ 7.1203 -static char *get_message(ParseErrorId id){ 7.1204 - int i; 7.1205 - for(i=0; i<catalog_n; i++){ 7.1206 - if(id == catalog[i].id){ 7.1207 - return catalog[i].message; 7.1208 - } 7.1209 - } 7.1210 - return ""; 7.1211 -} 7.1212 - 7.1213 -/** Get the line number. 7.1214 - * 7.1215 - * @param in parser 7.1216 - */ 7.1217 -int get_line(Parser *in){ 7.1218 - return in->line_no; 7.1219 -} 7.1220 - 7.1221 -/** Get the column number. 7.1222 - * 7.1223 - * @param in parser 7.1224 - */ 7.1225 -int get_column(Parser *in){ 7.1226 - return in->char_no; 7.1227 -} 7.1228 - 7.1229 -/** Get the line number the current token started on. 7.1230 - * 7.1231 - * @param in parser 7.1232 - */ 7.1233 -int get_tok_line(Parser *in){ 7.1234 - return in->tok_begin_line; 7.1235 +int begin_start(Parser *p, char c){ 7.1236 + int err = 0; 7.1237 + dprintf(">\n"); 7.1238 + err = Parser_push(p, state_start, "start"); 7.1239 + if(err) goto exit; 7.1240 + p->start_state = p->state; 7.1241 + exit: 7.1242 + dprintf("< err=%d\n", err); 7.1243 + return err; 7.1244 } 7.1245 7.1246 -/** Get the column number the current token started on. 7.1247 - * 7.1248 - * @param in parser 7.1249 - */ 7.1250 -int get_tok_column(Parser *in){ 7.1251 - return in->tok_begin_char; 7.1252 -} 7.1253 - 7.1254 -/** Report a parse error. 7.1255 - * Does nothing if the error stream is null or there is no error. 7.1256 - * 7.1257 - * @param in parser 7.1258 - */ 7.1259 -static void report_error(Parser *in){ 7.1260 - if(in->error_out && in->err){ 7.1261 - char *msg = get_message(in->err); 7.1262 - char *tok = peek_token(in); 7.1263 - IOStream_print(in->error_out, PARSE_ERR_FMT, 7.1264 - get_tok_line(in), get_tok_column(in), msg); 7.1265 - if(tok && tok[0]){ 7.1266 - IOStream_print(in->error_out, " '%s'", tok); 7.1267 +int Parser_input_char(Parser *p, char c){ 7.1268 + int err = 0; 7.1269 + if(Parser_at_eof(p)){ 7.1270 + //skip; 7.1271 + } else { 7.1272 + input_char(p, c); 7.1273 } 7.1274 - IOStream_print(in->error_out, "\n"); 7.1275 - } 7.1276 + if(!p->state){ 7.1277 + err = p->begin(p, c); 7.1278 + if(err) goto exit; 7.1279 + } 7.1280 + err = p->state->fn(p, c); 7.1281 + exit: 7.1282 + return err; 7.1283 } 7.1284 7.1285 -/** Get the error message for the current parse error code. 7.1286 - * Does nothing if there is no error. 7.1287 - * 7.1288 - * @param in parser 7.1289 - * @param buf where to place the message 7.1290 - * @param n maximum number of characters to place in buf 7.1291 - * @return current error code (zero for no error) 7.1292 - */ 7.1293 -int parse_error_message(Parser *in, char *buf, int n){ 7.1294 - if(in->err){ 7.1295 - char *msg = get_message(in->err); 7.1296 - snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in), get_tok_column(in), msg); 7.1297 - } 7.1298 - return in->err; 7.1299 -} 7.1300 - 7.1301 -/** Flag an unspecified parse error. All subsequent reads will fail. 7.1302 - * 7.1303 - * @param in parser 7.1304 - */ 7.1305 -void parse_error(Parser *in){ 7.1306 - parse_error_id(in, PARSE_ERR_INVALID_SYNTAX); 7.1307 +int Parser_input_eof(Parser *p){ 7.1308 + int err = 0; 7.1309 + p->eof = 1; 7.1310 + err = Parser_input_char(p, IOSTREAM_EOF); 7.1311 + return err; 7.1312 } 7.1313 7.1314 -/** Flag a parse error. All subsequent reads will fail. 7.1315 - * Does not change the parser error code if it is already set. 7.1316 - * 7.1317 - * @param in parser 7.1318 - * @param id error code 7.1319 - */ 7.1320 -void parse_error_id(Parser *in, ParseErrorId id){ 7.1321 - if(!in->err){ 7.1322 - in->err = id; 7.1323 - report_error(in); 7.1324 +int Parser_input(Parser *p, char *buf, int buf_n){ 7.1325 + int err = 0; 7.1326 + int i = 0; 7.1327 + dprintf("> |%s|\n", buf); 7.1328 + if(buf_n <= 0){ 7.1329 + err = Parser_input_eof(p); 7.1330 + goto exit; 7.1331 } 7.1332 -} 7.1333 - 7.1334 -/** Test if the parser's error flag is set. 7.1335 - * 7.1336 - * @param in parser 7.1337 - * @return 1 if set, 0 otherwise 7.1338 - */ 7.1339 -int has_error(Parser *in){ 7.1340 - return (in->err > 0); 7.1341 -} 7.1342 - 7.1343 -/** Test if the parser is at end of input. 7.1344 - * 7.1345 - * @param in parser 7.1346 - * @return 1 if at EOF, 0 otherwise 7.1347 - */ 7.1348 -int at_eof(Parser *p){ 7.1349 - return p->eof; 7.1350 + for(i = 0; i < buf_n; i++){ 7.1351 + err = Parser_input_char(p, buf[i]); 7.1352 + if(err) goto exit; 7.1353 + } 7.1354 + exit: 7.1355 + err = (err < 0 ? err : buf_n); 7.1356 + dprintf("< err=%d\n", err); 7.1357 + return err; 7.1358 } 7.1359 7.1360 #ifdef SXPR_PARSER_MAIN 7.1361 /* Stuff for standalone testing. */ 7.1362 7.1363 #include "file_stream.h" 7.1364 -#include "string_stream.h" 7.1365 - 7.1366 -extern int stringof(Sxpr exp, char **s); 7.1367 -int child_string(Sxpr exp, Sxpr key, char **s){ 7.1368 - int err = 0; 7.1369 - Sxpr val = sxpr_child_value(exp, key, ONONE); 7.1370 - err = stringof(val, s); 7.1371 - return err; 7.1372 -} 7.1373 - 7.1374 -extern int intof(Sxpr exp, int *v); 7.1375 -int child_int(Sxpr exp, Sxpr key, int *v){ 7.1376 - int err = 0; 7.1377 - Sxpr val = sxpr_child_value(exp, key, ONONE); 7.1378 - err = intof(val, v); 7.1379 - return err; 7.1380 -} 7.1381 - 7.1382 -int eval_vnet(Sxpr exp){ 7.1383 - int err = 0; 7.1384 - Sxpr oid = intern("id"); 7.1385 - int id; 7.1386 - err = child_int(exp, oid, &id); 7.1387 - if(err) goto exit; 7.1388 - dprintf("> vnet id=%d\n", id); 7.1389 - exit: 7.1390 - dprintf("< err=%d\n", err); 7.1391 - return err; 7.1392 -} 7.1393 - 7.1394 -int eval_connect(Sxpr exp){ 7.1395 - int err = 0; 7.1396 - Sxpr ovif = intern("vif"); 7.1397 - Sxpr ovnet = intern("vnet"); 7.1398 - char *vif; 7.1399 - int vnet; 7.1400 - 7.1401 - err = child_string(exp, ovif, &vif); 7.1402 - if(err) goto exit; 7.1403 - err = child_int(exp, ovnet, &vnet); 7.1404 - if(err) goto exit; 7.1405 - dprintf("> connect vif=%s vnet=%d\n", vif, vnet); 7.1406 - exit: 7.1407 - dprintf("< err=%d\n", err); 7.1408 - return err; 7.1409 -} 7.1410 - 7.1411 -int eval(Sxpr exp){ 7.1412 - int err = 0; 7.1413 - Sxpr oconnect = intern("connect"); 7.1414 - Sxpr ovnet = intern("vnet"); 7.1415 - 7.1416 - if(sxpr_elementp(exp, ovnet)){ 7.1417 - err = eval_vnet(exp); 7.1418 - } else if(sxpr_elementp(exp, oconnect)){ 7.1419 - err = eval_connect(exp); 7.1420 - } else { 7.1421 - err = -EINVAL; 7.1422 - } 7.1423 - return err; 7.1424 -} 7.1425 +//#include "string_stream.h" 7.1426 7.1427 /** Main program for testing. 7.1428 * Parses input and prints it. 7.1429 @@ -907,14 +962,16 @@ int main(int argc, char *argv[]){ 7.1430 char buf[1024]; 7.1431 int k; 7.1432 Sxpr obj; 7.1433 - //Sxpr l, x; 7.1434 int i = 0; 7.1435 7.1436 pin = Parser_new(); 7.1437 - set_error_stream(pin, iostdout); 7.1438 + Parser_set_error_stream(pin, iostdout); 7.1439 dprintf("> parse...\n"); 7.1440 while(1){ 7.1441 - k = fread(buf, 1, 1, stdin); 7.1442 + k = fread(buf, 1, 100, stdin); 7.1443 + if(k>=0){ 7.1444 + buf[k+1] = '\0'; 7.1445 + } 7.1446 err = Parser_input(pin, buf, k); 7.1447 while(Parser_ready(pin)){ 7.1448 obj = Parser_get_val(pin); 7.1449 @@ -923,12 +980,6 @@ int main(int argc, char *argv[]){ 7.1450 } 7.1451 if(k <= 0) break; 7.1452 } 7.1453 -/* obj = Parser_get_all(pin); */ 7.1454 -/* for(l = obj ; CONSP(l); l = CDR(l)){ */ 7.1455 -/* x = CAR(l); */ 7.1456 -/* objprint(iostdout, x, 0); printf("\n"); */ 7.1457 -/* eval(x); */ 7.1458 -/* } */ 7.1459 dprintf("> err=%d\n", err); 7.1460 return 0; 7.1461 }
8.1 --- a/tools/libxutil/sxpr_parser.h Fri May 13 15:01:20 2005 +0000 8.2 +++ b/tools/libxutil/sxpr_parser.h Fri May 13 15:08:29 2005 +0000 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com> 8.6 + * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com> 8.7 * 8.8 * This library is free software; you can redistribute it and/or modify 8.9 * it under the terms of the GNU Lesser General Public License as 8.10 @@ -25,10 +25,13 @@ 8.11 * Sxpr parsing definitions. 8.12 */ 8.13 8.14 -/** Size of a parser input buffer. 8.15 - * Tokens read must fit into this size (including trailing null). 8.16 +/** Initial size of a parser input buffer. 8.17 */ 8.18 -#define PARSER_BUF_SIZE 4096 8.19 +#define PARSER_BUF_SIZE 512 8.20 + 8.21 +/** Input buffer size increment (when it's full). 8.22 + */ 8.23 +#define PARSER_BUF_INCREMENT 512 8.24 8.25 struct Parser; 8.26 typedef int ParserStateFn(struct Parser *, char c); 8.27 @@ -43,13 +46,14 @@ typedef struct ParserState { 8.28 char *name; 8.29 } ParserState; 8.30 8.31 -/** Structure representing an input source for the parser. 8.32 - * Can read from any IOStream implementation. 8.33 - */ 8.34 typedef struct Parser { 8.35 + /** Initial state function. */ 8.36 + ParserStateFn *begin; 8.37 + /** Parse value. */ 8.38 Sxpr val; 8.39 /** Error reporting stream (null for no reports). */ 8.40 IOStream *error_out; 8.41 + /** End-of-file flag, */ 8.42 int eof; 8.43 /** Error flag. Non-zero if there has been a read error. */ 8.44 int err; 8.45 @@ -57,13 +61,11 @@ typedef struct Parser { 8.46 int line_no; 8.47 /** Column number of input (reset on new line). */ 8.48 int char_no; 8.49 - /** Lookahead character. */ 8.50 - char c; 8.51 /** Buffer for reading tokens. */ 8.52 - char buf[PARSER_BUF_SIZE]; 8.53 - /** Size of token buffer. */ 8.54 - int buf_n; 8.55 - int buf_i; 8.56 + char *buf; 8.57 + char *buf_end; 8.58 + char *tok; 8.59 + char *tok_end; 8.60 /** Line the last token started on. */ 8.61 int tok_begin_line; 8.62 /** Character number the last token started on. */ 8.63 @@ -95,7 +97,7 @@ typedef enum { 8.64 * @param in parser 8.65 * @param flags flags mask 8.66 */ 8.67 -inline static void parser_flags_raise(Parser *in, int flags){ 8.68 +inline static void Parser_flags_raise(Parser *in, int flags){ 8.69 in->flags |= flags; 8.70 } 8.71 8.72 @@ -104,7 +106,7 @@ inline static void parser_flags_raise(Pa 8.73 * @param in parser 8.74 * @param flags flags mask 8.75 */ 8.76 -inline static void parser_flags_lower(Parser *in, int flags){ 8.77 +inline static void Parser_flags_lower(Parser *in, int flags){ 8.78 in->flags &= ~flags; 8.79 } 8.80 8.81 @@ -112,7 +114,7 @@ inline static void parser_flags_lower(Pa 8.82 * 8.83 * @param in parser 8.84 */ 8.85 -inline static void parser_flags_clear(Parser *in){ 8.86 +inline static void Parser_flags_clear(Parser *in){ 8.87 in->flags = 0; 8.88 } 8.89 8.90 @@ -121,14 +123,32 @@ extern Parser * Parser_new(void); 8.91 extern int Parser_input(Parser *p, char *buf, int buf_n); 8.92 extern int Parser_input_eof(Parser *p); 8.93 extern int Parser_input_char(Parser *p, char c); 8.94 -extern void set_error_stream(Parser *z, IOStream *error_out); 8.95 +extern void Parser_set_error_stream(Parser *z, IOStream *error_out); 8.96 + 8.97 +extern int Parser_error_message(Parser *in, char *buf, int n); 8.98 +extern int Parser_has_error(Parser *in); 8.99 +extern int Parser_at_eof(Parser *in); 8.100 + 8.101 +extern int Parser_ready(Parser *p); 8.102 +extern Sxpr Parser_get_val(Parser *p); 8.103 +extern Sxpr Parser_get_all(Parser *p); 8.104 8.105 -extern int parse_error_message(Parser *in, char *buf, int n); 8.106 -extern int has_error(Parser *in); 8.107 -extern int at_eof(Parser *in); 8.108 +/* Internal parser api. */ 8.109 +void Parser_pop(Parser *p); 8.110 +int Parser_push(Parser *p, ParserStateFn *fn, char *name); 8.111 +int Parser_return(Parser *p); 8.112 +int Parser_at_eof(Parser *p); 8.113 +int Parser_error(Parser *in); 8.114 +int Parser_set_value(Parser *p, Sxpr val); 8.115 +int Parser_intern(Parser *p); 8.116 +int Parser_string(Parser *p); 8.117 +int Parser_data(Parser *p); 8.118 +int Parser_uint(Parser *p); 8.119 8.120 -int Parser_ready(Parser *p); 8.121 -Sxpr Parser_get_val(Parser *p); 8.122 -Sxpr Parser_get_all(Parser *p); 8.123 +char *peek_token(Parser *p); 8.124 +char *copy_token(Parser *p); 8.125 +void new_token(Parser *p); 8.126 +int save_char(Parser *p, char c); 8.127 +int token_len(Parser *p); 8.128 8.129 #endif /* ! _XUTIL_SXPR_PARSER_H_ */
9.1 --- a/tools/libxutil/sys_string.c Fri May 13 15:01:20 2005 +0000 9.2 +++ b/tools/libxutil/sys_string.c Fri May 13 15:08:29 2005 +0000 9.3 @@ -49,6 +49,27 @@ inline static const char * convert_set_b 9.4 return s; 9.5 } 9.6 9.7 +/** Set the sign to use for converting a string to a number. 9.8 + * Value is 1 for positive, -1 for negative. 9.9 + * 9.10 + * @param s input string 9.11 + * @param sign where to put the sign 9.12 + * @return rest of s to parse as a number 9.13 + */ 9.14 +inline static const char * convert_set_sign(const char *s, int *sign){ 9.15 + *sign = 1; 9.16 + if(s){ 9.17 + if(*s == '+'){ 9.18 + *sign = 1; 9.19 + s++; 9.20 + } else if (*s == '-'){ 9.21 + *sign = -1; 9.22 + s++; 9.23 + } 9.24 + } 9.25 + return s; 9.26 +} 9.27 + 9.28 /** Get the numerical value of a digit in the given base. 9.29 * 9.30 * @param c digit character 9.31 @@ -103,6 +124,40 @@ int convert_atoul(const char *str, unsig 9.32 return err; 9.33 } 9.34 9.35 +/** Convert a string to a long by parsing it as a number. 9.36 + * Will accept hex or decimal in usual C syntax. 9.37 + * 9.38 + * @param str input string 9.39 + * @param val where to put the result 9.40 + * @return 0 if converted OK, negative otherwise 9.41 + */ 9.42 +int convert_atol(const char *str, long *val){ 9.43 + int err = 0; 9.44 + unsigned long v = 0; 9.45 + int base, sign = 1; 9.46 + const char *s = str; 9.47 + 9.48 + if(!s) { 9.49 + err = -EINVAL; 9.50 + goto exit; 9.51 + } 9.52 + s = convert_set_sign(s, &sign); 9.53 + s = convert_set_base(s, &base); 9.54 + for( ; !err && *s; s++){ 9.55 + int digit = convert_get_digit(*s, base); 9.56 + if(digit<0){ 9.57 + err = -EINVAL; 9.58 + goto exit; 9.59 + } 9.60 + v *= base; 9.61 + v += digit; 9.62 + } 9.63 + if(sign < 0) v = -v; 9.64 + exit: 9.65 + *val = (err ? 0 : v); 9.66 + return err; 9.67 +} 9.68 + 9.69 /** Combine a directory path with a relative path to produce 9.70 * a new path. 9.71 *
10.1 --- a/tools/libxutil/sys_string.h Fri May 13 15:01:20 2005 +0000 10.2 +++ b/tools/libxutil/sys_string.h Fri May 13 15:08:29 2005 +0000 10.3 @@ -86,6 +86,7 @@ static inline size_t strnlen(const char 10.4 /*============================================================================*/ 10.5 10.6 extern int convert_atoul(const char *s, unsigned long *v); 10.7 +extern int convert_atol(const char *s, long *v); 10.8 extern int path_concat(char *s, char *t, char **val); 10.9 10.10 #endif /* !_XUTIL_SYS_STRING_H_ */
11.1 --- a/tools/python/xen/xend/server/SrvDaemon.py Fri May 13 15:01:20 2005 +0000 11.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py Fri May 13 15:08:29 2005 +0000 11.3 @@ -60,7 +60,6 @@ class Daemon: 11.4 if not pm: continue 11.5 xm = xendre.match(pm.group('cmd')) 11.6 if not xm: continue 11.7 - #print 'pid=', pm.group('pid'), 'cmd=', pm.group('cmd') 11.8 pids.append(int(pm.group('pid'))) 11.9 return pids 11.10 11.11 @@ -313,7 +312,7 @@ class Daemon: 11.12 os.setuid(pwd.getpwnam(XEND_USER)[2]) 11.13 return 0 11.14 except KeyError, error: 11.15 - print "Error: no such user '%s'" % XEND_USER 11.16 + print >>sys.stderr, "Error: no such user '%s'" % XEND_USER 11.17 return 1 11.18 11.19 def stop(self): 11.20 @@ -328,7 +327,6 @@ class Daemon: 11.21 self.listenChannels() 11.22 servers = SrvServer.create() 11.23 self.daemonize() 11.24 - print 'running serverthread...' 11.25 servers.start() 11.26 except Exception, ex: 11.27 print >>sys.stderr, 'Exception starting xend:', ex 11.28 @@ -342,14 +340,12 @@ class Daemon: 11.29 11.30 def listenChannels(self): 11.31 def virqReceived(virq): 11.32 - print 'virqReceived>', virq 11.33 eserver.inject('xend.virq', virq) 11.34 11.35 self.channelF.setVirqHandler(virqReceived) 11.36 self.channelF.start() 11.37 11.38 def exit(self, rc=0): 11.39 - #reactor.disconnectAll() 11.40 if self.channelF: 11.41 self.channelF.stop() 11.42 # Calling sys.exit() raises a SystemExit exception, which only
12.1 --- a/tools/python/xen/xend/server/event.py Fri May 13 15:01:20 2005 +0000 12.2 +++ b/tools/python/xen/xend/server/event.py Fri May 13 15:08:29 2005 +0000 12.3 @@ -3,17 +3,13 @@ import StringIO 12.4 12.5 from xen.web import reactor, protocol 12.6 12.7 -from xen.lowlevel import xu 12.8 - 12.9 from xen.xend import sxp 12.10 from xen.xend import PrettyPrint 12.11 -from xen.xend import EventServer 12.12 -eserver = EventServer.instance() 12.13 +from xen.xend import EventServer; eserver = EventServer.instance() 12.14 from xen.xend.XendError import XendError 12.15 - 12.16 from xen.xend import XendRoot; xroot = XendRoot.instance() 12.17 12.18 -DEBUG = 1 12.19 +DEBUG = 0 12.20 12.21 class EventProtocol(protocol.Protocol): 12.22 """Asynchronous handler for a connected event socket. 12.23 @@ -30,7 +26,7 @@ class EventProtocol(protocol.Protocol): 12.24 self.pretty = 0 12.25 12.26 # For debugging subscribe to everything and make output pretty. 12.27 - self.subscribe(['*']) 12.28 + #self.subscribe(['*']) 12.29 self.pretty = 1 12.30 12.31 def dataReceived(self, data): 12.32 @@ -45,10 +41,7 @@ class EventProtocol(protocol.Protocol): 12.33 except SystemExit: 12.34 raise 12.35 except: 12.36 - if DEBUG: 12.37 - raise 12.38 - else: 12.39 - self.send_error() 12.40 + self.send_error() 12.41 12.42 def loseConnection(self): 12.43 if self.transport: 12.44 @@ -73,7 +66,11 @@ class EventProtocol(protocol.Protocol): 12.45 return 0 12.46 12.47 def send_result(self, res): 12.48 - return self.send_reply(['ok', res]) 12.49 + if res is None: 12.50 + resp = ['ok'] 12.51 + else: 12.52 + resp = ['ok', res] 12.53 + return self.send_reply(resp) 12.54 12.55 def send_error(self): 12.56 (extype, exval) = sys.exc_info()[:2] 12.57 @@ -129,7 +126,6 @@ class EventProtocol(protocol.Protocol): 12.58 12.59 def op_pretty(self, name, req): 12.60 self.pretty = 1 12.61 - return ['ok'] 12.62 12.63 def op_console_disconnect(self, name, req): 12.64 id = sxp.child_value(req, 'id') 12.65 @@ -137,7 +133,6 @@ class EventProtocol(protocol.Protocol): 12.66 raise XendError('Missing console id') 12.67 id = int(id) 12.68 self.daemon.console_disconnect(id) 12.69 - return ['ok'] 12.70 12.71 def op_info(self, name, req): 12.72 val = ['info'] 12.73 @@ -151,13 +146,11 @@ class EventProtocol(protocol.Protocol): 12.74 # (sys.subscribe event*) 12.75 # Subscribe to the events: 12.76 self.subscribe(v[1:]) 12.77 - return ['ok'] 12.78 12.79 def op_sys_inject(self, name, v): 12.80 # (sys.inject event) 12.81 event = v[1] 12.82 eserver.inject(sxp.name(event), event) 12.83 - return ['ok'] 12.84 12.85 def op_trace(self, name, v): 12.86 mode = (v[1] == 'on') 12.87 @@ -181,6 +174,27 @@ class EventProtocol(protocol.Protocol): 12.88 import controller 12.89 controller.DEBUG = (mode == 'on') 12.90 12.91 + def op_domain_ls(self, name, v): 12.92 + xd = xroot.get_component("xen.xend.XendDomain") 12.93 + return xd.domain_ls() 12.94 + 12.95 + def op_domain_configure(self, name, v): 12.96 + domid = sxp.child_value(v, "dom") 12.97 + config = sxp.child_value(v, "config") 12.98 + if domid is None: 12.99 + raise XendError("missing domain id") 12.100 + if config is None: 12.101 + raise XendError("missing domain config") 12.102 + xd = xroot.get_component("xen.xend.XendDomain") 12.103 + xd.domain_configure(domid, config) 12.104 + 12.105 + def op_domain_unpause(self, name, v): 12.106 + domid = sxp.child_value(v, "dom") 12.107 + if domid is None: 12.108 + raise XendError("missing domain id") 12.109 + xd = xroot.get_component("xen.xend.XendDomain") 12.110 + xd.domain_unpause(domid) 12.111 + 12.112 class EventFactory(protocol.ServerFactory): 12.113 """Asynchronous handler for the event server socket. 12.114 """
13.1 --- a/tools/xfrd/Make.xfrd Fri May 13 15:01:20 2005 +0000 13.2 +++ b/tools/xfrd/Make.xfrd Fri May 13 15:08:29 2005 +0000 13.3 @@ -6,6 +6,7 @@ UTIL_LIB = libutil.a 13.4 UTIL_LIB_SRC = 13.5 UTIL_LIB_SRC += allocate.c 13.6 UTIL_LIB_SRC += enum.c 13.7 +UTIL_LIB_SRC += fd_stream.c 13.8 UTIL_LIB_SRC += file_stream.c 13.9 UTIL_LIB_SRC += gzip_stream.c 13.10 UTIL_LIB_SRC += hash_table.c 13.11 @@ -19,7 +20,7 @@ UTIL_LIB_SRC += sxpr_parser.c 13.12 UTIL_LIB_SRC += sys_net.c 13.13 UTIL_LIB_SRC += sys_string.c 13.14 #UTIL_LIB_SRC += util.c 13.15 -UTIL_LIB_SRC += xdr.c 13.16 +#UTIL_LIB_SRC += xdr.c 13.17 13.18 #---------------------------------------------------------------------------- 13.19 # Xfrd.
14.1 --- a/tools/xfrd/Makefile Fri May 13 15:01:20 2005 +0000 14.2 +++ b/tools/xfrd/Makefile Fri May 13 15:08:29 2005 +0000 14.3 @@ -26,18 +26,11 @@ UTIL_LIB_OBJ = $(UTIL_LIB_SRC:.c=.o) 14.4 XFRD_PROG_OBJ = $(XFRD_PROG_SRC:.c=.o) 14.5 XFRD_PROG_OBJ += $(UTIL_LIB) 14.6 14.7 -# Flag controlling whether to use stubs. 14.8 -# Define to use stubs, undefine to use the real Xen functions. 14.9 -#CPPFLAGS += -D _XEN_XFR_STUB_ 14.10 - 14.11 -ifeq ($(SXPR_DEBUG),1) 14.12 -CPPFLAGS += -D _XEN_XFR_STUB_ -D SXPR_PARSER_MAIN 14.13 -endif 14.14 - 14.15 CC := gcc 14.16 14.17 CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing 14.18 CFLAGS += $(INCLUDES) 14.19 + 14.20 # Make gcc generate dependencies. 14.21 CFLAGS += -Wp,-MD,.$(@F).d 14.22 PROG_DEP = .*.d 14.23 @@ -55,12 +48,6 @@ XFRD_LIBS += -L $(XEN_LIBXUTIL) -lxutil 14.24 # zlib library. 14.25 XFRD_LIBS += -lz 14.26 14.27 -CURL_FLAGS = $(shell curl-config --cflags) 14.28 -CURL_LIBS = $(shell curl-config --libs) 14.29 -CFLAGS += $(CURL_FLAGS) 14.30 -# libcurl libraries. 14.31 -XFRD_LIBS += $(CURL_LIBS) 14.32 - 14.33 #$(warning XFRD_LIBS = $(XFRD_LIBS)) 14.34 14.35 all: build
15.1 --- a/tools/xfrd/connection.c Fri May 13 15:01:20 2005 +0000 15.2 +++ b/tools/xfrd/connection.c Fri May 13 15:08:29 2005 +0000 15.3 @@ -171,7 +171,7 @@ int Conn_sxpr(Conn *conn, Sxpr *sxpr){ 15.4 dprintf(">\n"); 15.5 if(!conn->parser){ 15.6 conn->parser = Parser_new(); 15.7 - set_error_stream(conn->parser, iostdout); 15.8 + Parser_set_error_stream(conn->parser, iostdout); 15.9 } 15.10 while(!err && c >= 0 && !Parser_ready(conn->parser)){ 15.11 c = IOStream_getc(conn->in);
16.1 --- a/tools/xfrd/lzi_stream.c Fri May 13 15:01:20 2005 +0000 16.2 +++ b/tools/xfrd/lzi_stream.c Fri May 13 15:08:29 2005 +0000 16.3 @@ -475,7 +475,6 @@ static int lzi_close(IOStream *io){ 16.4 */ 16.5 static void lzi_free(IOStream *s){ 16.6 LZIState *state = lzi_state(s); 16.7 - IOStream_free(state->io); 16.8 LZIState_free(state); 16.9 s->data = NULL; 16.10 } 16.11 @@ -525,8 +524,8 @@ IOStream *lzi_stream_fdopen(int fd, cons 16.12 err = 0; 16.13 exit: 16.14 if(err){ 16.15 - IOStream_free(io); 16.16 - IOStream_free(zio); 16.17 + IOStream_close(io); 16.18 + IOStream_close(zio); 16.19 zio = NULL; 16.20 } 16.21 return zio;
17.1 --- a/tools/xfrd/xen_domain.c Fri May 13 15:01:20 2005 +0000 17.2 +++ b/tools/xfrd/xen_domain.c Fri May 13 15:08:29 2005 +0000 17.3 @@ -1,17 +1,18 @@ 17.4 #include <unistd.h> 17.5 #include <stdlib.h> 17.6 #include <stdio.h> 17.7 +#include <sys/socket.h> 17.8 +#include <sys/un.h> 17.9 17.10 -#ifdef _XEN_XFR_STUB_ 17.11 -typedef unsigned long u32; 17.12 -#else 17.13 #include "xc.h" 17.14 #include "xc_io.h" 17.15 -#endif 17.16 + 17.17 +#include "sxpr.h" 17.18 +#include "sxpr_parser.h" 17.19 +#include "file_stream.h" 17.20 +#include "fd_stream.h" 17.21 17.22 #include "xen_domain.h" 17.23 -#include "marshal.h" 17.24 -#include "xdr.h" 17.25 #include "xfrd.h" 17.26 17.27 #define MODULE_NAME "XFRD" 17.28 @@ -33,7 +34,6 @@ int domain_configure(void *data, u32 dom 17.29 return xen_domain_configure(dom, vmconfig, vmconfig_n); 17.30 } 17.31 17.32 -#ifndef _XEN_XFR_STUB_ 17.33 static int xc_handle = 0; 17.34 17.35 int xcinit(void){ 17.36 @@ -50,7 +50,6 @@ void xcfini(void){ 17.37 xc_handle = 0; 17.38 } 17.39 } 17.40 -#endif 17.41 17.42 /** Write domain state. 17.43 * 17.44 @@ -62,31 +61,6 @@ int xen_domain_snd(Conn *xend, IOStream 17.45 char *vmconfig, int vmconfig_n, 17.46 int live, int resource){ 17.47 int err = 0; 17.48 -#ifdef _XEN_XFR_STUB_ 17.49 - char buf[1024]; 17.50 - int n, k, d, buf_n; 17.51 - dprintf("> dom=%d\n", dom); 17.52 - err = marshal_uint32(io, dom); 17.53 - if(err) goto exit; 17.54 - err = marshal_string(io, vmconfig, vmconfig_n); 17.55 - if(err) goto exit; 17.56 - n = 32 * 1024 * 1024; 17.57 - n = 32 * 1024; 17.58 - buf_n = sizeof(buf); 17.59 - err = marshal_uint32(io, n); 17.60 - for(k = 0; k < n; k += d){ 17.61 - d = n - k; 17.62 - if(d > buf_n) d = buf_n; 17.63 - err = marshal_bytes(io, buf, d); 17.64 - if(err) goto exit; 17.65 - dprintf("> k=%d n=%d\n", k, n); 17.66 - } 17.67 - 17.68 - dom = 99; 17.69 - err = domain_suspend(xend, dom); 17.70 - IOStream_close(io); 17.71 - exit: 17.72 -#else 17.73 XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt; 17.74 ioctxt->domain = dom; 17.75 ioctxt->io = io; 17.76 @@ -101,7 +75,6 @@ int xen_domain_snd(Conn *xend, IOStream 17.77 } 17.78 ioctxt->resource = resource; 17.79 err = xc_linux_save(xcinit(), ioctxt); 17.80 -#endif 17.81 dprintf("< err=%d\n", err); 17.82 return err; 17.83 } 17.84 @@ -114,25 +87,6 @@ int xen_domain_rcv(IOStream *io, 17.85 char **vmconfig, int *vmconfig_n, 17.86 int *configured){ 17.87 int err = 0; 17.88 -#ifdef _XEN_XFR_STUB_ 17.89 - char buf[1024]; 17.90 - int n, k, d, buf_n; 17.91 - dprintf(">\n"); 17.92 - err = unmarshal_uint32(io, dom); 17.93 - if(err) goto exit; 17.94 - err = unmarshal_new_string(io, vmconfig, vmconfig_n); 17.95 - if(err) goto exit; 17.96 - err = unmarshal_uint32(io, &n); 17.97 - buf_n = sizeof(buf); 17.98 - for(k = 0; k < n; k += d){ 17.99 - d = n - k; 17.100 - if(d > buf_n) d = buf_n; 17.101 - err = unmarshal_bytes(io, buf, d); 17.102 - if(err) goto exit; 17.103 - dprintf("> k=%d n=%d\n", k, n); 17.104 - } 17.105 - exit: 17.106 -#else 17.107 XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt; 17.108 dprintf(">\n"); 17.109 ioctxt->io = io; 17.110 @@ -147,137 +101,182 @@ int xen_domain_rcv(IOStream *io, 17.111 *vmconfig = ioctxt->vmconfig; 17.112 *vmconfig_n = ioctxt->vmconfig_n; 17.113 *configured = (ioctxt->flags & XCFLAGS_CONFIGURE); 17.114 -#endif 17.115 dprintf("< err=%d\n", err); 17.116 return err; 17.117 } 17.118 17.119 -#include <curl/curl.h> 17.120 -#include "http.h" 17.121 - 17.122 -/** Flag indicating whether we need to initialize libcurl. 17.123 - */ 17.124 -static int do_curl_global_init = 1; 17.125 +typedef struct xend { 17.126 + int fd; 17.127 + IOStream *io; 17.128 + Parser *parser; 17.129 + int seeneof; 17.130 +} Xend; 17.131 17.132 -/** Get a curl handle, initializing libcurl if needed. 17.133 - * 17.134 - * @return curl handle 17.135 - */ 17.136 -static CURL *curlinit(void){ 17.137 - if(do_curl_global_init){ 17.138 - do_curl_global_init = 0; 17.139 - // Stop libcurl using the proxy. There's a curl option to 17.140 - // set the proxy - but no option to defeat it. 17.141 - unsetenv("http_proxy"); 17.142 - curl_global_init(CURL_GLOBAL_ALL); 17.143 - } 17.144 - return curl_easy_init(); 17.145 -} 17.146 - 17.147 -/** Curl debug function. 17.148 - */ 17.149 -int curldebug(CURL *curl, curl_infotype ty, char *buf, int buf_n, void *data){ 17.150 - // printf("%*s\n", buf_n, buf); /* Does not compile correctly on non 32bit platforms */ 17.151 - fwrite(data, buf_n, 1, stdout); 17.152 - printf("\n"); 17.153 - return 0; 17.154 +char *xend_server_addr(void){ 17.155 + char * val = getenv("XEND_EVENT_ADDR"); 17.156 + return (val ? val : "/var/lib/xend/event-socket"); 17.157 } 17.158 17.159 -/** Setup a curl handle with a url. 17.160 - * Creates the url by formatting 'fmt' and the remaining arguments. 17.161 - * 17.162 - * @param pcurl return parameter for the curl handle 17.163 - * @param url url buffer 17.164 - * @param url_n size of url 17.165 - * @param fmt url format string, followed by parameters 17.166 - * @return 0 on success, error code otherwise 17.167 +/** Open a unix-domain socket to the xend server. 17.168 */ 17.169 -static int curlsetup(CURL **pcurl, struct curl_slist **pheaders, char *url, int url_n, char *fmt, ...){ 17.170 +int xend_open_fd(void){ 17.171 + struct sockaddr_un addr_un = { .sun_family = AF_UNIX }; 17.172 + struct sockaddr *addr = (struct sockaddr*)&addr_un; 17.173 + int addr_n = sizeof(addr_un); 17.174 int err = 0; 17.175 - va_list args; 17.176 - CURL *curl = NULL; 17.177 - struct curl_slist *headers = NULL; 17.178 - int n = 0; 17.179 17.180 - curl = curlinit(); 17.181 - if(!curl){ 17.182 - eprintf("> Could not init libcurl\n"); 17.183 - err = -ENOMEM; 17.184 + int fd = socket(AF_UNIX, SOCK_STREAM, 0); 17.185 + if(fd < 0){ 17.186 + err = -errno; 17.187 + perror("socket"); 17.188 + goto exit; 17.189 + } 17.190 + strcpy(addr_un.sun_path, xend_server_addr()); 17.191 + if(connect(fd, addr, addr_n) < 0){ 17.192 + err = -errno; 17.193 + perror("connect"); 17.194 goto exit; 17.195 } 17.196 - url_n -= 1; 17.197 - va_start(args, fmt); 17.198 - n = vsnprintf(url, url_n, fmt, args); 17.199 - va_end(args); 17.200 - if(n <= 0 || n >= url_n){ 17.201 - err = -ENOMEM; 17.202 - eprintf("> Out of memory in url\n"); 17.203 + exit: 17.204 + if(err && (fd >= 0)){ 17.205 + close(fd); 17.206 + } 17.207 + 17.208 + return (err ? err : fd); 17.209 +} 17.210 + 17.211 +/** Close a connection to the server. 17.212 + * 17.213 + * @param xend connection 17.214 +*/ 17.215 +void xend_close(Xend *xend){ 17.216 + if(!xend) return; 17.217 + close(xend->fd); 17.218 + Parser_free(xend->parser); 17.219 +} 17.220 + 17.221 +/** Open a connection to the server. 17.222 + * 17.223 + * @param xend result parameter for the connection 17.224 + * @return 0 on success, negative error code otherwise 17.225 + */ 17.226 +int xend_open(Xend **xend){ 17.227 + int err = 0; 17.228 + Xend *val = ALLOCATE(Xend); 17.229 + 17.230 + val->fd = xend_open_fd(); 17.231 + 17.232 + if(val->fd < 0){ 17.233 + err = val->fd; 17.234 goto exit; 17.235 } 17.236 - dprintf("> url=%s\n", url); 17.237 -#if DEBUG 17.238 - // Verbose. 17.239 - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); 17.240 - // Call the debug function on data received. 17.241 - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curldebug); 17.242 -#else 17.243 - // No progress meter. 17.244 - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); 17.245 - // Completely quiet. 17.246 - curl_easy_setopt(curl, CURLOPT_MUTE, 1); 17.247 -#endif 17.248 - // Set the URL. 17.249 - curl_easy_setopt(curl, CURLOPT_URL, url); 17.250 - 17.251 - headers = curl_slist_append(headers, "Expect:"); 17.252 - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 17.253 - 17.254 + val->io = fd_stream_new(val->fd); 17.255 + val->parser = Parser_new(); 17.256 exit: 17.257 - if(err && curl){ 17.258 - curl_easy_cleanup(curl); 17.259 - curl = NULL; 17.260 - } 17.261 - *pcurl = curl; 17.262 - if (pheaders) 17.263 - *pheaders = headers; 17.264 + if(err) xend_close(val); 17.265 + *xend = (err ? NULL : val); 17.266 return err; 17.267 } 17.268 17.269 -static void curlcleanup(CURL **pcurl, struct curl_slist **pheaders){ 17.270 - if (*pcurl) 17.271 - curl_easy_cleanup(*pcurl); 17.272 - if (*pheaders) 17.273 - curl_slist_free_all(*pheaders); 17.274 - *pcurl = NULL; 17.275 - *pheaders = NULL; 17.276 -} 17.277 -/** Make the http request stored in the curl handle and get 17.278 - * the result code from the curl code and the http return code. 17.279 - * 17.280 - * @param curl curl handle 17.281 - * @return 0 for success, error code otherwise 17.282 +/** Read a response from a server connection. 17.283 */ 17.284 -int curlresult(CURL *curl){ 17.285 +int xend_read_resp(Xend *xend, Sxpr *resp){ 17.286 int err = 0; 17.287 - CURLcode curlcode = 0; 17.288 - long httpcode = 0; 17.289 + Sxpr val = ONONE; 17.290 + char buf[1024]; 17.291 + int buf_n = sizeof(buf), n; 17.292 17.293 - curlcode = curl_easy_perform(curl); 17.294 - if(curlcode){ 17.295 - eprintf("> curlcode=%d\n", curlcode); 17.296 - err = -EINVAL; 17.297 - goto exit; 17.298 - } 17.299 - curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode); 17.300 - if(httpcode != HTTP_OK){ 17.301 - eprintf("> httpcode=%d\n", (int)httpcode); 17.302 - err = -EINVAL; 17.303 - goto exit; 17.304 + for( ; ; ){ 17.305 + if(Parser_ready(xend->parser)){ 17.306 + val = Parser_get_val(xend->parser); 17.307 + goto exit; 17.308 + } 17.309 + if(xend->seeneof){ 17.310 + err = -EIO; 17.311 + goto exit; 17.312 + } 17.313 + memset(buf, 0, buf_n); 17.314 + n = IOStream_read(xend->io, buf, 100); 17.315 + if(n <= 0){ 17.316 + xend->seeneof = 1; 17.317 + err = Parser_input_eof(xend->parser); 17.318 + } else { 17.319 + err = Parser_input(xend->parser, buf, n); 17.320 + } 17.321 } 17.322 exit: 17.323 + *resp = (err < 0 ? ONONE : val); 17.324 return err; 17.325 } 17.326 17.327 +/** Read a response from a server connection and decode the value. 17.328 + * 17.329 + * @param xend server connection 17.330 + * @param resp result parameter for the response value 17.331 + * @return 0 on success, negative error code otherwise 17.332 + */ 17.333 +int xend_read(Xend *xend, Sxpr *resp){ 17.334 + int err = 0; 17.335 + Sxpr val = ONONE; 17.336 + 17.337 + dprintf(">\n"); 17.338 + for( ; ; ){ 17.339 + err = xend_read_resp(xend, &val); 17.340 + if(err < 0) goto exit; 17.341 + 17.342 + if(sxpr_is(sxpr_name(val), "event")){ 17.343 + // We don't care about events, try again. 17.344 + err = 0; 17.345 + continue; 17.346 + } else if(sxpr_is(sxpr_name(val), "err")){ 17.347 + eprintf("> "); objprint(iostderr, val, 0); fprintf(stderr, "\n"); 17.348 + err = -EINVAL; 17.349 + break; 17.350 + } else { 17.351 + err = 0; 17.352 + val = sxpr_child0(val, ONULL); 17.353 + break; 17.354 + } 17.355 + } 17.356 +#ifdef DEBUG 17.357 + dprintf("> OK "); 17.358 + objprint(iostdout, val, 0); 17.359 + printf("\n"); 17.360 +#endif 17.361 + exit: 17.362 + if(resp){ 17.363 + *resp = (err < 0 ? ONONE : val); 17.364 + } 17.365 + dprintf("> err=%d\n", err); 17.366 + return err; 17.367 +} 17.368 + 17.369 +/** Send a request to the server and return the result value in resp. 17.370 + * 17.371 + * @param xend server connection 17.372 + * @param resp result parameter for the response value 17.373 + * @param format request format followed by args to print 17.374 + * @return 0 on success, negative error code otherwise 17.375 + */ 17.376 +int xend_call(Xend *xend, Sxpr *resp, char *format, ...){ 17.377 + va_list args; 17.378 + int err; 17.379 + 17.380 + dprintf("> "); 17.381 + va_start(args, format); 17.382 +#ifdef DEBUG 17.383 + vprintf(format, args); printf("\n"); 17.384 +#endif 17.385 + err = IOStream_vprint(xend->io, format, args); 17.386 + va_end(args); 17.387 + if(err < 0) goto exit; 17.388 + IOStream_flush(xend->io); 17.389 + err = xend_read(xend, resp); 17.390 + exit: 17.391 + dprintf("> err=%d\n", err); 17.392 + return (err < 0 ? err : 0); 17.393 +} 17.394 + 17.395 /** Get xend to list domains. 17.396 * We use this to force xend to refresh its domain list. 17.397 * 17.398 @@ -285,18 +284,12 @@ int curlresult(CURL *curl){ 17.399 */ 17.400 int xen_domain_ls(void){ 17.401 int err = 0; 17.402 - CURL *curl = NULL; 17.403 - struct curl_slist *headers = NULL; 17.404 - char url[128] = {}; 17.405 - int url_n = sizeof(url); 17.406 - 17.407 - dprintf(">\n"); 17.408 - err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain", XEND_PORT); 17.409 + Xend *xend = NULL; 17.410 + err = xend_open(&xend); 17.411 if(err) goto exit; 17.412 - err = curlresult(curl); 17.413 + err = xend_call(xend, NULL, "(domain.ls)"); 17.414 exit: 17.415 - curlcleanup(&curl, &headers); 17.416 - dprintf("< err=%d\n", err); 17.417 + xend_close(xend); 17.418 return err; 17.419 } 17.420 17.421 @@ -309,49 +302,18 @@ int xen_domain_ls(void){ 17.422 */ 17.423 int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){ 17.424 int err = 0; 17.425 - CURL *curl = NULL; 17.426 - struct curl_slist *headers = NULL; 17.427 - char url[128] = {}; 17.428 - int url_n = sizeof(url); 17.429 - struct curl_httppost *form = NULL, *last = NULL; 17.430 - CURLFORMcode formcode = 0; 17.431 - 17.432 + Xend *xend = NULL; 17.433 dprintf("> dom=%u\n", dom); 17.434 // List domains so that xend will update its domain list and notice the new domain. 17.435 xen_domain_ls(); 17.436 - 17.437 - err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom); 17.438 + // Now configure it. 17.439 + err = xend_open(&xend); 17.440 if(err) goto exit; 17.441 - 17.442 - // Config field - set from vmconfig. 17.443 - formcode = curl_formadd(&form, &last, 17.444 - CURLFORM_COPYNAME, "config", 17.445 - CURLFORM_BUFFER, "config", 17.446 - CURLFORM_BUFFERPTR, vmconfig, 17.447 - CURLFORM_BUFFERLENGTH, vmconfig_n, 17.448 - CURLFORM_CONTENTTYPE, "application/octet-stream", 17.449 - CURLFORM_END); 17.450 - if(formcode){ 17.451 - eprintf("> Error adding config field.\n"); 17.452 - goto exit; 17.453 - } 17.454 - // Op field. 17.455 - formcode = curl_formadd(&form, &last, 17.456 - CURLFORM_COPYNAME, "op", 17.457 - CURLFORM_COPYCONTENTS, "configure", 17.458 - CURLFORM_END); 17.459 - if(formcode){ 17.460 - eprintf("> Error adding op field.\n"); 17.461 - err = -EINVAL; 17.462 - goto exit; 17.463 - } 17.464 - // POST the form. 17.465 - curl_easy_setopt(curl, CURLOPT_HTTPPOST, form); 17.466 - err = curlresult(curl); 17.467 + err = xend_call(xend, NULL, "(domain.configure (dom %d) (config %*s))", 17.468 + dom, vmconfig_n, vmconfig); 17.469 exit: 17.470 - curlcleanup(&curl, &headers); 17.471 - if(form) curl_formfree(form); 17.472 dprintf("< err=%d\n", err); 17.473 + xend_close(xend); 17.474 return err; 17.475 } 17.476 17.477 @@ -362,34 +324,11 @@ int xen_domain_configure(uint32_t dom, c 17.478 */ 17.479 int xen_domain_unpause(uint32_t dom){ 17.480 int err = 0; 17.481 - CURL *curl = NULL; 17.482 - struct curl_slist *headers = NULL; 17.483 - char url[128] = {}; 17.484 - int url_n = sizeof(url); 17.485 - struct curl_httppost *form = NULL, *last = NULL; 17.486 - CURLFORMcode formcode = 0; 17.487 - 17.488 - dprintf("> dom=%u\n", dom); 17.489 - 17.490 - err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom); 17.491 + Xend *xend = NULL; 17.492 + err = xend_open(&xend); 17.493 if(err) goto exit; 17.494 - 17.495 - // Op field. 17.496 - formcode = curl_formadd(&form, &last, 17.497 - CURLFORM_COPYNAME, "op", 17.498 - CURLFORM_COPYCONTENTS, "unpause", 17.499 - CURLFORM_END); 17.500 - if(formcode){ 17.501 - eprintf("> Error adding op field.\n"); 17.502 - err = -EINVAL; 17.503 - goto exit; 17.504 - } 17.505 - // POST the form. 17.506 - curl_easy_setopt(curl, CURLOPT_HTTPPOST, form); 17.507 - err = curlresult(curl); 17.508 + err = xend_call(xend, NULL, "(domain.unpause (dom %d))", dom); 17.509 exit: 17.510 - curlcleanup(&curl, &headers); 17.511 - if(form) curl_formfree(form); 17.512 - dprintf("< err=%d\n", err); 17.513 + xend_close(xend); 17.514 return err; 17.515 }
18.1 --- a/tools/xfrd/xfrd.c Fri May 13 15:01:20 2005 +0000 18.2 +++ b/tools/xfrd/xfrd.c Fri May 13 15:08:29 2005 +0000 18.3 @@ -188,7 +188,6 @@ enum { 18.4 XFR_MAX 18.5 }; 18.6 18.7 -#ifndef SXPR_PARSER_MAIN 18.8 /** Short options. Options followed by ':' take an argument. */ 18.9 static char *short_opts = (char[]){ 18.10 OPT_PORT, ':', 18.11 @@ -213,7 +212,6 @@ static Args _args = {}; 18.12 18.13 /** Xfrd arguments. */ 18.14 static Args *args = &_args; 18.15 -#endif 18.16 18.17 /** Initialize an array element for a constant to its string name. */ 18.18 #define VALDEF(val) { val, #val } 18.19 @@ -782,7 +780,6 @@ int xfr_save(Args *args, XfrState *state 18.20 exit: 18.21 if(io){ 18.22 IOStream_close(io); 18.23 - IOStream_free(io); 18.24 } 18.25 if(err){ 18.26 unlink(file); 18.27 @@ -798,7 +795,7 @@ int xfr_save(Args *args, XfrState *state 18.28 int xfr_restore(Args *args, XfrState *state, Conn *xend, char *file){ 18.29 int err = 0; 18.30 IOStream *io = NULL; 18.31 - int configured=0; 18.32 + int configured = 0; 18.33 18.34 dprintf("> file=%s\n", file); 18.35 io = gzip_stream_fopen(file, "rb"); 18.36 @@ -820,7 +817,6 @@ int xfr_restore(Args *args, XfrState *st 18.37 exit: 18.38 if(io){ 18.39 IOStream_close(io); 18.40 - IOStream_free(io); 18.41 } 18.42 if(err){ 18.43 xfr_error(xend, err); 18.44 @@ -1215,7 +1211,6 @@ int xfrd_main(Args *args){ 18.45 return err; 18.46 } 18.47 18.48 -#ifndef SXPR_PARSER_MAIN 18.49 /** Parse command-line arguments and call the xfrd main program. 18.50 * 18.51 * @param arg argument count 18.52 @@ -1271,4 +1266,3 @@ int main(int argc, char *argv[]){ 18.53 } 18.54 return (err ? 1 : 0); 18.55 } 18.56 -#endif