Mercurial > hg > xemacs-beta
diff lisp/tooltalk/tooltalk-util.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ec9a17fef872 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/tooltalk/tooltalk-util.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,268 @@ +;;; -*- Mode: Emacs-Lisp -*- +;;; +;;; Emacs Tooltalk Utility Functions +;;; +;;; @(#)tooltalk-util.el 1.7 93/12/07 + + +(defun initialize-tooltalk-message-arg (msg n mode value vtype) + "Initialize the Nth tooltalk message argument of MSG. +A new argument is created if necessary. No attempt to distinguish +between strings that contain binary data and ordinary strings is made; +all non integer argument values are converted to a string (if not a +string already) and loaded with tt_message_arg_val_set(). +Applications that need to put binary data into a ToolTalk message +argument should initialize the argument with: + + (set-tooltalk-message-attribute bin-string msg 'arg_bval arg-n)" + (let ((n-args-needed + (- (1+ n) (get-tooltalk-message-attribute msg 'args_count)))) + (while (> n-args-needed 0) + (add-tooltalk-message-arg msg mode vtype) + (setq n-args-needed (1- n-args-needed)))) + + (cond + ((integerp value) + (set-tooltalk-message-attribute value msg 'arg_ival n)) + ((stringp value) + (set-tooltalk-message-attribute value msg 'arg_val n)) + (t + (error "The value specified for msg %s argument %d, %s, must be a string or an integer" + (prin1-to-string msg) + n + (prin1-to-string value))))) + + + +(defconst tooltalk-arg-mode-ids + (list 'TT_IN 'TT_OUT 'TT_INOUT TT_IN TT_OUT TT_INOUT)) + +(defun initialize-tooltalk-message/pattern-args (initfn msg args) + "Apply INITFN to each the position mode value and type of +each argument in the list. The value of INITFN should be either +'initialize-tooltalk-message-arg or 'initialize-tooltalk-pattern-arg. +See `make-tooltalk-message' for a description of how arguments are specified. +We distinguish the short form for arguments, e.g. \"just-a-value\", +from the long form by checking to see if the argument is a list whose +car is one of the ToolTalk mode values like TT_INOUT." + (let ((n 0)) + (while args + (let* ((arg (car args)) + (long-form + (and (consp arg) + (member (car arg) tooltalk-arg-mode-ids))) + (mode + (if long-form (car arg) TT_IN)) + (value + (cond + ((not long-form) arg) + ((cdr arg) (car (cdr arg))) + (t ""))) + (type + (cond + ((and long-form + (cdr (cdr arg)) + (stringp (car (cdr (cdr arg))))) + (car (cdr (cdr arg)))) + ((integerp value) "int") + (t "string")))) + (funcall initfn msg n mode value type)) + (setq args (cdr args)) + (setq n (1+ n))))) + + +(defun initialize-tooltalk-message-attributes (msg attributes) + "Initialize the tooltalk message attributes. The value of +attributes must be a property list in the same form as for +make-tooltalk-message. This function can be used to reset +an existing message or to initailize a new one. See +initialize-tooltalk-message-args for a description of how +arguments are initialized." + (let ((args attributes) + (initfn 'initialize-tooltalk-message-arg)) + (while (and args (cdr args)) + (let ((indicator (car args)) + (value (car (cdr args)))) + (if (eq indicator 'args) + (initialize-tooltalk-message/pattern-args initfn msg value) + (set-tooltalk-message-attribute value msg indicator))) + (setq args (cdr (cdr args)))))) + + +(defun make-tooltalk-message (attributes &optional no-callback) + "Create a tooltalk message and initialize its attributes. +The value of attributes must be a list of alternating keyword/values, +where keywords are symbols that name valid message attributes. +For example: + + (make-tooltalk-message + '(class TT_NOTICE + scope TT_SESSION + address TT_PROCEDURE + op \"do-something\" + args (\"arg1\" 12345 (TT_INOUT \"arg3\" \"string\")))) + +Values must always be strings, integers, or symbols that +represent Tooltalk constants. Attribute names are the same as +those supported by set-tooltalk-message-attribute, plus 'args. + +The value of args should be a list of message arguments where +each message argument has the following form: + + (mode [value [type]]) or just value + +Where mode is one of TT_IN, TT_OUT, TT_INOUT and type is a string. +If type isn't specified then \"int\" is used if the value is a +number otherwise \"string\" is used. If only a value is specified +then mode defaults to TT_IN. If mode is TT_OUT then value and +type don't need to be specified. You can find out more about the +semantics and uses of ToolTalk message arguments in chapter 4 of the +Tooltalk Programmer's Guide. + +The no-callback arg is a hack to prevent the registration of the +C-level callback. This hack is needed by the current SPARCworks +tool startup mechanism. Yuchho." + (let ((msg (create-tooltalk-message no-callback))) + (initialize-tooltalk-message-attributes msg attributes) + msg)) + + +(defun describe-tooltalk-message (msg &optional stream) + "Print tooltalk message MSG's attributes and arguments to STREAM. +This is often useful for debugging." + (let ((attrs + '(address + class + disposition + file + gid + handler + handler_ptype + object + op + opnum + otype + scope + sender + sender_ptype + session + state + status + status_string + uid + callback))) + (terpri stream) + (while attrs + (princ (car attrs) stream) + (princ " " stream) + (prin1 (get-tooltalk-message-attribute msg (car attrs)) stream) + (terpri stream) + (setq attrs (cdr attrs)))) + + (let ((n (get-tooltalk-message-attribute msg 'args_count)) + (i 0)) + (while (< i n) + (princ "Argument " stream) + (princ i stream) + (princ " " stream) + (let ((type (get-tooltalk-message-attribute msg 'arg_type i))) + (princ + (prin1-to-string + (list + (get-tooltalk-message-attribute msg 'arg_mode i) + (if (equal type "int") + (get-tooltalk-message-attribute msg 'arg_ival i) + (get-tooltalk-message-attribute msg 'arg_val i)) + type)) + stream)) + (terpri stream) + (setq i (1+ i))))) + + +(defun initialize-tooltalk-pattern-arg (pat n mode value vtype) + "Add one argument to tooltalk pattern PAT. +No support for specifying pattern arguments whose value is a vector +of binary data is provided." + (let ((converted-value + (if (or (integerp value) (stringp value)) + value + (prin1-to-string value)))) + (add-tooltalk-pattern-arg pat mode vtype converted-value))) + + +(defun initialize-tooltalk-pattern-attributes (pat attributes) + "Initialize tooltalk pattern PAT's attributes. +ATTRIBUTES must be a property list in the same form as for +`make-tooltalk-pattern'. The value of each attribute (except 'category) +can either be a single value or a list of values. If a list of +values is provided then the pattern will match messages with +a corresponding attribute that matches any member of the list. + +This function can be used to add attribute values to an existing +pattern or to initiallize a new one. See +`initialize-tooltalk-message/pattern-args' for a description of how +arguments are initialized." + (let ((args attributes) + (initfn 'initialize-tooltalk-pattern-arg)) + (while (and args (cdr args)) + (let ((indicator (car args)) + (value (car (cdr args)))) + (cond + ((eq indicator 'args) + (initialize-tooltalk-message/pattern-args initfn pat value)) + ((eq indicator 'plist) + (let ((values value)) + (while values + (let ((prop (car values)) + (propval (car (cdr values)))) + (tooltalk-pattern-prop-set pat prop propval)) + (setq values (cdr (cdr values)))))) + ((consp value) + (let ((values value)) + (while values + (add-tooltalk-pattern-attribute (car values) pat indicator) + (setq values (cdr values))))) + (t + (add-tooltalk-pattern-attribute value pat indicator)))) + (setq args (cdr (cdr args)))))) + + + +(defun make-tooltalk-pattern (attributes) + "Create a tooltalk pattern and initialize its attributes. +The value of attributes must be a list of alternating keyword/values, +where keywords are symbols that name valid pattern attributes +or lists of valid attributes. For example: + + (make-tooltalk-pattern + '(category TT_OBSERVE + scope TT_SESSION + op (\"operation1\" \"operation2\") + args (\"arg1\" 12345 (TT_INOUT \"arg3\" \"string\")))) + + +Values must always be strings, integers, or symbols that +represent Tooltalk constants or lists of same. When a list +of values is provided all of the list elements are added to +the attribute. In the example above, messages whose op +attribute is \"operation1\" or \"operation2\" would match the pattern. + +The value of args should be a list of pattern arguments where +each pattern argument has the following form: + + (mode [value [type]]) or just value + +Where mode is one of TT_IN, TT_OUT, TT_INOUT and type is a string. +If type isn't specified then \"int\" is used if the value is a +number otherwise \"string\" is used. If only a value is specified +then mode defaults to TT_IN. If mode is TT_OUT then value and type +don't need to be specified. You can find out more about the semantics +and uses of ToolTalk pattern arguments in chapter 3 of the Tooltalk +Programmers Guide. +" + (let ((pat (create-tooltalk-pattern))) + (initialize-tooltalk-pattern-attributes pat attributes) + pat)) + + +