home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!island!argv
- From: argv@island.uu.net (Dan Heller)
- Newsgroups: comp.sources.x
- Subject: v05i037: macro-string enhancement for Xterm, Part01/01
- Message-ID: <1232@island.uu.net>
- Date: 5 Dec 89 19:06:04 GMT
- Organization: Island Graphics, Marin County, California
- Lines: 1657
- Approved: island!argv@sun.com
-
- Submitted-by: uunet!zax!sci!jimmc (Jim McBeath)
- Posting-number: Volume 5, Issue 37
- Archive-name: macstr/part01
-
-
-
- #! /bin/sh
- ## This is a shell archive. Remove anything before this line, then unpack
- ## it by saving it into a file and typing "sh file". To overwrite existing
- ## files, type "sh file -c". You can also feed this as standard input via
- ## unshar, or by typing "sh <file". If this archive is complete, you will
- ## see the following message at the end:
- # "End of shell archive."
- # Contents: README.macrostr xterm.man.diff Imakefile.diff
- # Makefile.diff ptyx.h.diff charproc.c.diff macrostr.c
- # Wrapped by jimmc@zax on Mon Nov 13 17:14:21 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f README.macrostr -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README.macrostr\"
- else
- echo shar: Extracting \"README.macrostr\" \(553 characters\)
- sed "s/^X//" >README.macrostr <<'END_OF_README.macrostr'
- XThe macro string package is intended to allow xterm to generate the character
- Xsequences for button presses on just about any terminal you can think of.
- XIt is a general enough mechanism that you may find other uses for it as well.
- XInstallation requires the addition of one major new file (macrostr.c) and some
- Xone-line changes to a few other files. See the updated man pages for details
- Xon how the macro string capability is used. Copyright has been donated to
- XMIT using their standard copyright notice.
- X
- XJim McBeath 13.Nov.89
- Xsci!jimmc@decwrl.dec.com
- END_OF_README.macrostr
- if test 553 -ne `wc -c <README.macrostr`; then
- echo shar: \"README.macrostr\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f xterm.man.diff -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"xterm.man.diff\"
- else
- echo shar: Extracting \"xterm.man.diff\" \(14424 characters\)
- sed "s/^X//" >xterm.man.diff <<'END_OF_xterm.man.diff'
- X1c1
- X< .TH XTERM 1 "25 October 1988" "X Version 11"
- X---
- X> .TH XTERM 1 " 7 November 1989" "X Version 11"
- X222c222
- X< cause the window to be repositioned automatically in the normal postion at the
- X---
- X> cause the window to be repositioned automatically in the normal position at the
- X264c264
- X< This option indicates that a visual bell is prefered over an audible one.
- X---
- X> This option indicates that a visual bell is preferred over an audible one.
- X286c286
- X< This option specifies the prefered size and position of the Tektronix window.
- X---
- X> This option specifies the preferred size and position of the Tektronix window.
- X290c290
- X< This option specifies the prefered position of the icon window.
- X---
- X> This option specifies the preferred position of the icon window.
- X316c316
- X< instead of the user's shell. \fBThis option has been superceeded by the new
- X---
- X> instead of the user's shell. \fBThis option has been superceded by the new
- X358c358
- X< This option specifies the prefered size and position of the VT102 window;
- X---
- X> This option specifies the preferred size and position of the VT102 window;
- X376c376
- X< Specifies the prefered size and position of the application when iconified.
- X---
- X> Specifies the preferred size and position of the application when iconified.
- X457c457
- X< Specifies the prefered size and position of the VT102 window.
- X---
- X> Specifies the preferred size and position of the VT102 window.
- X460c460
- X< Specifies the prefered size and position of the Tektronix window.
- X---
- X> Specifies the preferred size and position of the Tektronix window.
- X713c713
- X< To distinquish a pointer button from a key, the high bit of the character is
- X---
- X> To distinguish a pointer button from a key, the high bit of the character is
- X785c785
- X< X environments differ in their security conciousness. The servers provided
- X---
- X> X environments differ in their security consciousness. The servers provided
- X911a912,919
- X> .B macro-string(\fImacro-string\fB)
- X> Rebinds the key or key sequence to the macro-string value.
- X> When this action is executed, the macro string is processed, which normally
- X> inserts a string into the input stream.
- X> This capability is useful for emulating the wide variety of character sequences
- X> that are produced by a button press on various terminals.
- X> For more details, see the section "MACRO STRINGS" below.
- X> .TP 15
- X994a1003,1368
- X> .SH "MACRO STRINGS"
- X> .PP
- X> Xterm includes a fairly general macro-string processing capability intended
- X> to allow emulation of the button-press sequences of just about any terminal
- X> type.
- X> The macro-string processor is a simple stack machine which interprets a
- X> macro string.
- X> The macro string can contain commands which access state information
- X> (such as the X and Y location of the mouse), manipulate the stack (such
- X> as doing arithmetic operations), and insert text into the terminal
- X> input buffer (which is the desired end result of the macro string).
- X> There are rudimentary programming commands (conditional execution,
- X> subroutine calls), built-in primitives and macro strings, and user-definable
- X> macro strings.
- X> .PP
- X> A macro string is interpreted one token at a time.
- X> Operations are expressed in RPN, i.e. operands first (which are placed onto
- X> the stack) followed by operation (which operates on the stack).
- X> White space in a macro string is ignored.
- X> If there is an error in processing a macro string, the Bell() function
- X> is called.
- X> .PP
- X> There are two data types: integer and string.
- X> Boolean operations result in an integer where FALSE is represented by
- X> 0 and TRUE is represented by 1.
- X> When interpreting an integer as a Boolean, 0 is considered
- X> FALSE and anything else is considered TRUE.
- X> When interpreting a string as a Boolean, NULL or the empty string is
- X> considered FALSE and anything else is considered TRUE.
- X> .PP
- X> In the descriptions below, the term TOS represents the value of the
- X> top item on the stack, TOS-1 is the next-to-top, etc.
- X> .PP
- X> The macro-string commands are as follows:
- X> .TP 15
- X> .B "\'string\'"
- X> Single-quoted string.
- X> Pushes the quoted string onto the stack.
- X> The string can contain any character except NULL and single quote.
- X> There is no backslash notation and no provision for including a single
- X> quote within a single-quoted string.
- X> You can use a double-quoted string if you need to include a single
- X> quote in your string.
- X> Note also that the various parsers used to load this string (i.e. the
- X> C compiler if it is a built-in macro string, or the resource manager if
- X> it is from a resource or default file) can handle backslash notation, so
- X> you can include control characters in a quoted string.
- X> .TP 15
- X> .ft 3
- X> "string"
- X> .}N
- X> Double-quoted string.
- X> Pushes the quoted string onto the stack.
- X> This behaves in exactly the same way as a single-quoted string, except that
- X> when using a double-quoted string you can include single quotes in the
- X> string but not double quotes.
- X> .TP 15
- X> .B "printf formatting"
- X> You can convert TOS to a string using standard printf formatting commands.
- X> For example, if TOS is the integer 123, then the command "%04d" would
- X> replace TOS with the string "0123", and the command "%X" would replace
- X> TOS with the string "7B".
- X> The formatting string is only a single "%" sequence, and only converts
- X> the top item on the stack to a string.
- X> .TP 15
- X> .B "+"
- X> Add or catenate.
- X> If TOS and TOS-1 are both integers,
- X> replaces TOS and TOS-1 with (TOS-1 + TOS).
- X> If TOS and TOS-1 are both strings, replaces TOS and TOS-1 with
- X> the catenation of TOS-1 and TOS.
- X> .TP 15
- X> .B "-"
- X> Subtract.
- X> Replaces TOS and TOS-1 with (TOS-1 - TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B "*"
- X> Multiply.
- X> Replaces TOS and TOS-1 with (TOS-1 * TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B "/"
- X> Integer divide.
- X> Replaces TOS and TOS-1 with (TOS-1 / TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B "<<"
- X> Left shift.
- X> Replaces TOS and TOS-1 with (TOS-1 << TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B ">>"
- X> Right shift.
- X> Replaces TOS and TOS-1 with (TOS-1 >> TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B "|"
- X> Bitwise OR.
- X> Replaces TOS and TOS-1 with (TOS-1 | TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B "||"
- X> Logical OR.
- X> Replaces TOS and TOS-1 with (TOS-1 || TOS).
- X> TOS and TOS-1 are independently considered as Booleans.
- X> .TP 15
- X> .B "&"
- X> Bitwise AND.
- X> Replaces TOS and TOS-1 with (TOS-1 & TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B "&&"
- X> Logical AND.
- X> Replaces TOS and TOS-1 with (TOS-1 && TOS).
- X> TOS and TOS-1 are independently considered as Booleans.
- X> .TP 15
- X> .B "^"
- X> Bitwise XOR.
- X> Replaces TOS and TOS-1 with (TOS-1 ^ TOS).
- X> TOS and TOS-1 must both be integers.
- X> .TP 15
- X> .B "^^"
- X> Logical XOR.
- X> Replaces TOS and TOS-1 with (TOS-1 ^^ TOS).
- X> TOS and TOS-1 are independently considered as Booleans.
- X> .TP 15
- X> .B "!"
- X> Logical NOT.
- X> Replaces TOS by the logical inverse of TOS when considered as a Boolean.
- X> .TP 15
- X> .B "~"
- X> Bitwise invert.
- X> Replaces TOS by the bitwise inversion of TOS.
- X> TOS must be an integer.
- X> .TP 15
- X> .B number
- X> Numbers can be entered in decimal, octal or hexadecimal radix.
- X> A simple string of digits, not starting with a 0, pushes a decimal
- X> value onto the stack.
- X> If the first digit in the string is 0 and the remainder of digits are
- X> between 0 and 7, the number is input as an octal number and pushed onto
- X> the stack.
- X> If the first digit in the string is 0 and it is immediately followed
- X> by x or X, the number is input as a hexadecimal number and pushed onto
- X> the stack.
- X> .TP 15
- X> .B b
- X> Pushes the button field from a button event onto the stack.
- X> .TP 15
- X> .B c
- X> Pushes the cursor column from a key or button event onto the stack.
- X> The leftmost column is column 0.
- X> .TP 15
- X> .B C
- X> Pushes the column width of the screen onto the stack.
- X> .TP 15
- X> .B h
- X> Pushes the pixel height of a character onto the stack.
- X> .TP 15
- X> .B H
- X> Pushes the pixel height of the screen onto the stack.
- X> .TP 15
- X> .B i
- X> Places TOS (must be a string) into the terminal input buffer
- X> and pops it off the stack.
- X> .TP 15
- X> .B k
- X> Pushes the keycode field from a key event onto the stack.
- X> .TP 15
- X> .B l
- X> Puts the results of XLookupString on a key event onto the stack.
- X> If XLookupString returns an error or no string, an empty string is
- X> pushed onto the stack.
- X> .TP 15
- X> .B M
- X> Pop TOS (which must be a string) and interpret the macro of that name.
- X> The macro may be either a primitive or built-in (both compiled into xterm)
- X> or a user-defined macro.
- X> User defined macros override built-in macros, but not primitives.
- X> The list of primitives and built-in macros is given below.
- X> .TP 15
- X> .B r
- X> Pushes the cursor row from a key or button event onto the stack.
- X> The topmost row is 0.
- X> .TP 15
- X> .B R
- X> Pushes the row height of the screen onto the stack.
- X> .TP 15
- X> .B s
- X> Pushes the state field from a key or button event onto the stack.
- X> .TP 15
- X> .B w
- X> Pushes the pixel width of a character onto the stack.
- X> .TP 15
- X> .B W
- X> Pushes the pixel width of the screen onto the stack.
- X> .TP 15
- X> .B x
- X> Pushes the x pixel value from a key or button event onto the stack.
- X> .TP 15
- X> .B X
- X> Pushes to x_root pixel value from a key or button event onto the stack.
- X> .TP 15
- X> .B y
- X> Pushes the y pixel value from a key or button event onto the stack.
- X> .TP 15
- X> .B Y
- X> Pushes the y_root pixel value from a key or button event onto the stack.
- X> .TP 15
- X> .B Z
- X> Conditionally returns from (terminates) a macro.
- X> Pops TOS and interprets it as a Bool; if TRUE, returns from the macro,
- X> else does nothing.
- X> .PP
- X> Primitive functions are compiled into Xterm and can not be overridden.
- X> The primitives are:
- X> .TP 15
- X> .B error
- X> Generates an error; calls Bell() and aborts all macro string processing.
- X> This is typically used with an "if" statement to abort a macro if
- X> an error condition occurs.
- X> .TP 15
- X> .B exch
- X> Exchanges TOS with TOS-1.
- X> .TP 15
- X> .B if
- X> Examines TOS-1 as a Boolean; if TRUE, executes the macro named at TOS,
- X> else does nothing.
- X> In either case, the two values are popped off the stack before the
- X> test is performed.
- X> .TP 15
- X> .B ifElse
- X> Examines TOS-2 as a Boolean; if TRUE, executes the macro named at TOS-1,
- X> else executes the macro named at TOS.
- X> In either case, the three values are popped off the stack before the
- X> test is performed.
- X> .TP 15
- X> .B limit
- X> Limits TOS-2 to be between TOS-1 and TOS.
- X> If TOS-2 is less than TOS-1, replaces it with TOS-1.
- X> If TOS-2 is greater than TOS, replaces it with TOS.
- X> All three items must be integers.
- X> Pops two items off the stack, leaving only the limited number.
- X> .TP 15
- X> .B ord
- X> Converts a one-character string at TOS to an integer with the
- X> equivalent integer value (essentially a "scanf %c").
- X> .TP 15
- X> .B pop
- X> Pops one item off the stack and discards it.
- X> .TP 15
- X> .B push
- X> Pushes the top item onto the stack again, duplicating it.
- X> .TP 15
- X> .B tekScale
- X> Pushes the tekScale field of the screen onto the stack.
- X> Useful for emulating the Tektronix mode buttons.
- X> .TP 15
- X> .B toBool
- X> Converts TOS to a Boolean (integer 0 or 1).
- X>
- X> .PP
- X> There are a number of built-in macros, which are simply macro strings
- X> which are compiled into xterm.
- X> These built-ins can be overridden by a user defined macro.
- X> The built-ins are listed below, with the definitions of some given
- X> as examples.
- X> .TP 15
- X> .B SeikoButton
- X> Generates the character sequence for button presses on a Seiko terminal.
- X> There are a number of associated built-ins that are a part of this package:
- X> SeikoGetX, SeikoGetY, SeikoSub1, SeikoEnd.
- X> To set up your xterm so that it generates Seiko character sequences for
- X> the buttons when the shift key is held down, you could add the following
- X> lines to your resource file:
- X> .sp
- X> .Ds
- X> *VT100.translations: #override \\n\\
- X> Shift <BtnDown> : macro-string("'SeikoButton'M") \\n\\
- X> Shift <BtnUp> : ignore()
- X> .De
- X> .TP 15
- X> .B X10Button
- X> Generates the character sequence that the X10 xterm generated for button
- X> pushes.
- X> This macro is implemented with this string:
- X> .sp
- X> .Ds
- X> '\\033[M'i31b+%ci33c+%ci33r+%ci
- X> .De
- X> .TP 15
- X> .B VT200ButtonPress
- X> Generates the character sequence for a VT200 button press.
- X> This macro is implemented with this string:
- X> .sp
- X> .Ds
- X> '\\033['iM31'VT200KeyState'M+b+%ci33c+%ci33r+%ci
- X> .De
- X> .TP 15
- X> .B VT200KeyState
- X> Called by the VT200ButtonPress macro.
- X> This macro is implemented with this string:
- X> .sp
- X> .Ds
- X> s5&s8&2>>+
- X> .De
- X> .TP 15
- X> .B TekButton
- X> Generates the character sequence for a Tektronix button press.
- X> Associated macros are TekGetBchar, TekGetlbchar, TekUcase, and TekSub1.
- X> .TP 15
- X> .B TestConst
- X> Generates a character string with a number of screen-dependent values,
- X> implemented with this string:
- X> .sp
- X> .Ds
- X> 'h='ih%di' w='iw%di' H='iH%di' W='iW%di' R='iR%di' C='iC%di'\\n'i
- X> .De
- X> .TP 15
- X> .B TestButton
- X> Generates a character string with a number of position-dependent values,
- X> suitable for binding to a button,
- X> implemented with this string:
- X> .sp
- X> .Ds
- X> 'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\\
- X> ' r='ir%di' c='ic%di' b='ib%di' s='is%xi'\\n'i
- X> .De
- X> .TP 15
- X> .B TestKey
- X> Generates a character string with a number of position-dependent values,
- X> suitable for binding to a key,
- X> implemented with this string:
- X> .sp
- X> .Ds
- X> 'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\\
- X> ' r='ir%di' c='ic%di' k='ik%di' s='is%xi' l=\\"'ili'\\"\\n'i
- X> .De
- X> .PP
- X> You could add the following bindings to execute the test macros to
- X> see how the values look:
- X> .sp
- X> .Ds
- X> *VT100.translations: #override \\n\\
- X> <Key>F5 : macro-string("'TestConst'M") \\n\\
- X> <Key>F6 : macro-string("'TestKey'M")
- X> .De
- X> .PP
- X> User defined macros can be specified in your resource or Xdefaults file.
- X> Macros are searched for as subresources of the xterm widget, where the
- X> subobject name is "macroString" and the subresource name is the macro name.
- X> For example, to define a macro named foo that prints out the string
- X> "button" and the button number, you could put this line in your resource file:
- X> .sp
- X> .Ds
- X> *VT100.macroString.foo: 'button 'i b%di
- X> .De
- X> .PP
- X> You could then bind this macro to a key with a line like:
- X> .sp
- X> .Ds
- X> *VT100.translations: #override \\n\\
- X> <Key>F7 : macro-string("'foo'M")
- X> .De
- X>
- X1125c1499
- X< Consortium), Dave Serisky (HP)
- X---
- X> Consortium), Dave Serisky (HP), Jim McBeath (Silicon Compilers)
- END_OF_xterm.man.diff
- if test 14424 -ne `wc -c <xterm.man.diff`; then
- echo shar: \"xterm.man.diff\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Imakefile.diff -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Imakefile.diff\"
- else
- echo shar: Extracting \"Imakefile.diff\" \(1173 characters\)
- sed "s/^X//" >Imakefile.diff <<'END_OF_Imakefile.diff'
- X*** Imakefile.orig Thu May 18 19:57:44 1989
- X--- Imakefile Fri Oct 27 13:44:02 1989
- X***************
- X*** 27,36 ****
- X /* add -DWTMP and -DLASTLOG if you want them */
- X DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy GettyProgram
- X SRCS1 = button.c charproc.c cursor.c data.c input.c \
- X! main.c menu.c misc.c screen.c scrollbar.c tabs.c \
- X TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
- X OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
- X! screen.o scrollbar.o button.o Tekproc.o misc.o \
- X VTPrsTbl.o TekPrsTbl.o data.o menu.o
- X SRCS2 = resize.c
- X OBJS2 = resize.o
- X--- 27,36 ----
- X /* add -DWTMP and -DLASTLOG if you want them */
- X DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy GettyProgram
- X SRCS1 = button.c charproc.c cursor.c data.c input.c \
- X! macrostr.c main.c menu.c misc.c screen.c scrollbar.c tabs.c \
- X TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
- X OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
- X! screen.o scrollbar.o button.o Tekproc.o misc.o macrostr.o \
- X VTPrsTbl.o TekPrsTbl.o data.o menu.o
- X SRCS2 = resize.c
- X OBJS2 = resize.o
- END_OF_Imakefile.diff
- if test 1173 -ne `wc -c <Imakefile.diff`; then
- echo shar: \"Imakefile.diff\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Makefile.diff -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile.diff\"
- else
- echo shar: Extracting \"Makefile.diff\" \(1055 characters\)
- sed "s/^X//" >Makefile.diff <<'END_OF_Makefile.diff'
- X*** Makefile.orig Fri Oct 27 12:58:09 1989
- X--- Makefile Fri Oct 27 15:39:17 1989
- X***************
- X*** 167,176 ****
- X
- X DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy
- X SRCS1 = button.c charproc.c cursor.c data.c input.c \
- X! main.c menu.c misc.c screen.c scrollbar.c tabs.c \
- X TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
- X OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
- X! screen.o scrollbar.o button.o Tekproc.o misc.o \
- X VTPrsTbl.o TekPrsTbl.o data.o menu.o
- X SRCS2 = resize.c
- X OBJS2 = resize.o
- X--- 167,176 ----
- X
- X DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy
- X SRCS1 = button.c charproc.c cursor.c data.c input.c \
- X! macrostr.c main.c menu.c misc.c screen.c scrollbar.c tabs.c \
- X TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
- X OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
- X! screen.o scrollbar.o button.o Tekproc.o misc.o macrostr.o \
- X VTPrsTbl.o TekPrsTbl.o data.o menu.o
- X SRCS2 = resize.c
- X OBJS2 = resize.o
- END_OF_Makefile.diff
- if test 1055 -ne `wc -c <Makefile.diff`; then
- echo shar: \"Makefile.diff\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f ptyx.h.diff -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"ptyx.h.diff\"
- else
- echo shar: Extracting \"ptyx.h.diff\" \(701 characters\)
- sed "s/^X//" >ptyx.h.diff <<'END_OF_ptyx.h.diff'
- X*** ptyx.h.orig Thu May 18 19:56:42 1989
- X--- ptyx.h Tue Nov 7 09:23:09 1989
- X***************
- X*** 191,196 ****
- X--- 191,202 ----
- X int height;
- X } BitmapBits;
- X
- X+ typedef struct _userMacro {
- X+ struct _userMacro *next;
- X+ String name;
- X+ String value;
- X+ } UserMacro;
- X+
- X #define SAVELINES 64 /* default # lines to save */
- X
- X typedef struct {
- X***************
- X*** 344,349 ****
- X--- 350,356 ----
- X Atom* selection_atoms; /* which selections we own */
- X Cardinal sel_atoms_size; /* how many atoms allocated */
- X Cardinal selection_count; /* how many atoms in use */
- X+ UserMacro *userMacros; /* list of user macro-strings */
- X } TScreen;
- X
- X /* meaning of bits in screen.select flag */
- END_OF_ptyx.h.diff
- if test 701 -ne `wc -c <ptyx.h.diff`; then
- echo shar: \"ptyx.h.diff\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f charproc.c.diff -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"charproc.c.diff\"
- else
- echo shar: Extracting \"charproc.c.diff\" \(741 characters\)
- sed "s/^X//" >charproc.c.diff <<'END_OF_charproc.c.diff'
- X*** charproc.c.orig Thu May 18 19:58:00 1989
- X--- charproc.c Fri Oct 27 13:45:47 1989
- X***************
- X*** 164,169 ****
- X--- 164,170 ----
- X extern void HandleLeaveWindow();
- X extern void HandleFocusChange();
- X void HandleKeymapChange();
- X+ extern void HandleMacroString();
- X extern void HandleModeMenu();
- X extern void HandleInsertSelection();
- X extern void HandleSelectStart();
- X***************
- X*** 210,215 ****
- X--- 211,217 ----
- X { "insert", HandleKeyPressed },
- X { "insert-selection", HandleInsertSelection },
- X { "keymap", HandleKeymapChange },
- X+ { "macro-string", HandleMacroString },
- X { "mode-menu", HandleModeMenu },
- X { "secure", HandleSecure },
- X { "select-start", HandleSelectStart },
- END_OF_charproc.c.diff
- if test 741 -ne `wc -c <charproc.c.diff`; then
- echo shar: \"charproc.c.diff\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f macrostr.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"macrostr.c\"
- else
- echo shar: Extracting \"macrostr.c\" \(24964 characters\)
- sed "s/^X//" >macrostr.c <<'END_OF_macrostr.c'
- X/* macrostr.c - handle macro string capability
- X *
- X * 26.Oct.89 Jim McBeath Initial definition
- X */
- X
- X/*
- X * Copyright 1989 Massachusetts Institute of Technology
- X *
- X * Permission to use, copy, modify, distribute, and sell this software and its
- X * documentation for any purpose is hereby granted without fee, provided that
- X * the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation, and that the name of M.I.T. not be used in advertising or
- X * publicity pertaining to distribution of the software without specific,
- X * written prior permission. M.I.T. makes no representations about the
- X * suitability of this software for any purpose. It is provided "as is"
- X * without express or implied warranty.
- X *
- X * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
- X * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- X * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- X * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- X *
- X * Author: Jim McBeath, Silicon Compiler Systems
- X * sci!jimmc@decwrl.dec.com
- X */
- X
- X#include <X11/Intrinsic.h>
- X#include <X11/StringDefs.h>
- X#include <ctype.h>
- X#include "ptyx.h"
- X
- X#define TOS (stackCount-1)
- X#define PUSHINT(n) if (!StackPushInt(n)) return FALSE
- X
- X/* inverse of CursorX and CursorY macros (except no topline used in Row) */
- X#define CursorRow(screen,Y) (((Y) - screen->border)/FontHeight(screen))
- X#define CursorCol(screen,X) (((X) - screen->scrollbar - screen->border) \
- X / FontWidth(screen))
- X
- Xextern char *malloc(), *realloc();
- X
- Xenum MacStackType { MacStackNull, MacStackInt, MacStackString };
- X
- Xtypedef struct _macstackentry {
- X enum MacStackType type;
- X union {
- X char *s;
- X int n;
- X } d;
- X} MacStackEntry;
- X
- X/* The static variables in this module have a lifetime which is limited
- X * to a single call to HandleMacroString.
- X */
- X
- Xstatic Widget stackWidget;
- Xstatic TScreen *stackScreen;
- Xstatic XEvent *stackEvent;
- X
- X/* The value stack used by all of the macro processing functions */
- Xstatic int stackAlloc;
- Xstatic int stackCount;
- Xstatic MacStackEntry *stack;
- X
- X/* A string buffer used by various parsing functions */
- Xstatic int stackQAlloc;
- Xstatic int stackQCount;
- Xstatic char *Qstr;
- X
- X/* forward references for PrimTab */
- Xextern int PrimToBool();
- Xextern int PrimNot();
- Xextern int PrimIfTrue();
- Xextern int PrimIfElse();
- Xextern int PrimPop();
- Xextern int PrimPush();
- Xextern int PrimExch();
- Xextern int PrimLimit();
- Xextern int PrimOrd();
- Xextern int PrimReturn();
- Xextern int PrimError();
- Xextern int PrimTekScale();
- X
- X/* Table of named primitive functions */
- Xstatic struct {
- X char *name; /* name of the primitive function */
- X int (*func)(); /* returns TRUE if all OK, FALSE if problem */
- X} PrimTab[] = {
- X {"error", PrimError},
- X {"exch", PrimExch},
- X {"if", PrimIfTrue},
- X {"ifElse", PrimIfElse},
- X {"limit", PrimLimit},
- X {"ord", PrimOrd},
- X {"pop", PrimPop},
- X {"push", PrimPush},
- X {"tekScale", PrimTekScale},
- X {"toBool", PrimToBool},
- X};
- X
- X/* Table of built-in macro strings */
- Xstatic struct {
- X char *name; /* name of the built-in macro string */
- X char *str; /* contents of the macro string */
- X} BuiltinTab[] = {
- X {"SeikoButton",
- X"'\033J'i'SeikoGetX'M'SeikoSub1'M'SeikoGetY'M'SeikoSub1'M'SeikoEnd'M"},
- X {"SeikoGetX", "x48*w/1890-"},
- X {"SeikoGetY", "1537y64*h/-"},
- X {"SeikoSub1",
- X"'push'M'push'M10>>037&0140|%ci5>>037&0100|%ci037&040|%ci"},
- X {"SeikoEnd", "' 'i31b3&+%ci'! !\r'i"},
- X {"X10Button", "'\033[M'i31b+%ci33c+%ci33r+%ci"},
- X {"VT200KeyState", "s5&s8&2>>+"},
- X {"VT200ButtonPress", "'\033['iM31'VT200KeyState'M+b+%ci33c+%ci33r+%ci"},
- X {"VT200ButtonOther", "'\033['iM32'VT200KeyState'M+3+%ci33c+%ci33r+%ci"},
- X {"TekButton", "'TekGetBchar'M%ci\
- Xx'tekScale'M/0 4096 1- 'limit'M'TekSu1'M \
- X3072 34+ y'tekScale'/- 0 3072 1- 'limit'M'TekSub1'M"},
- X {"TekGetBchar", "'TekGetlbchar'M s 1 & 'TekUcase' 'if'M 0x80 |"},
- X {"TekGetlbchar", "\
- X'r' 'ord'M b 1 == Z 'pop'M \
- X'm' 'ord'M b 2 == Z 'pop'M \
- X'l' 'ord'M b 3 == Z 'error'M"},
- X {"TekUcase", "32 -"},
- X {"TekSub1", "'push'M 7>>037&040|%ci 2>>037&040|%ci"},
- X {"TestConst",
- X"'h='ih%di' w='iw%di' H='iH%di' W='iW%di' R='iR%di' C='iC%di'\n'i"},
- X {"TestButton",
- X"'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\
- X' r='ir%di' c='ic%di' b='ib%di' s='is%xi'\n'i"},
- X {"TestKey",
- X"'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\
- X' r='ir%di' c='ic%di' k='ik%di' s='is%xi' l=\"'ili'\"\n'i"},
- X};
- X
- X
- Xstatic int
- Xishexalpha(c)
- Xchar c;
- X{
- X return (c>='a'&&c<='f' || c>='A'&&c<='F');
- X}
- X
- X/* Value stack manipulation functions */
- X
- Xstatic void
- XStackClear() /* clear the stack */
- X{
- X int i;
- X
- X for (i=0; i<stackCount; i++) { /* free all strings */
- X if (stack[i].type == MacStackString) {
- X if (stack[i].d.s)
- X free(stack[i].d.s);
- X }
- X }
- X stackCount = 0;
- X}
- X
- Xstatic void
- XStackPop(n)
- Xint n; /* pop N items off the top of the stack */
- X{
- X while (n>0 && stackCount>0) {
- X if (stack[TOS].type == MacStackString) {
- X if (stack[TOS].d.s)
- X free(stack[TOS].d.s);
- X }
- X n--;
- X stackCount--;
- X }
- X}
- X
- Xstatic Bool /* TRUE if successful, FALSE it not (no more memory) */
- XStackPush(e)
- XMacStackEntry *e;
- X{
- X int nbytes;
- X
- X if (stackCount>=stackAlloc) {
- X /* need more room */
- X if (stackAlloc)
- X stackAlloc *= 2;
- X else
- X stackAlloc = 15;
- X nbytes = stackAlloc * sizeof(stack[0]);
- X if (stack)
- X stack = (MacStackEntry *)realloc((char *)stack,nbytes);
- X else
- X stack = (MacStackEntry *)malloc(nbytes);
- X if (!stack)
- X return FALSE;
- X }
- X stack[stackCount] = *e; /* copy in structure */
- X /* note that we do not do any string copies here */
- X stackCount++;
- X return TRUE;
- X}
- X
- Xstatic Bool /* TRUE if successful, FALSE it not (no more memory) */
- XStackPushString(s)
- Xchar *s; /* the string becomes the property of the stack */
- X{
- X MacStackEntry e;
- X Bool t;
- X
- X e.type = MacStackString;
- X e.d.s = s;
- X t = StackPush(&e);
- X if (!t) {
- X free(s); /* it's our string - don't leak the memory */
- X }
- X return t;
- X}
- X
- Xstatic Bool /* TRUE if successful, FALSE it not (no more memory) */
- XStackPushStringCopy(s)
- Xchar *s; /* makes a copy of the string to put onto the stack */
- X{
- X char *newstr;
- X
- X newstr = malloc(strlen(s)+1);
- X if (!newstr)
- X return FALSE;
- X strcpy(newstr,s);
- X return (StackPushString(newstr));
- X}
- X
- Xstatic Bool /* TRUE if successful, FALSE it not (no more memory) */
- XStackPushInt(n)
- Xint n;
- X{
- X MacStackEntry e;
- X Bool t;
- X
- X e.type = MacStackInt;
- X e.d.n = n;
- X t = StackPush(&e);
- X return t;
- X}
- X
- X
- X/* String buffer manipulation functions */
- X
- Xstatic void
- XStackQclear()
- X{
- X stackQCount = 0;
- X}
- X
- Xstatic Bool /* TRUE is successful, FALSE if not (no more memory) */
- XStackQchar(c)
- Xchar c;
- X{
- X int nbytes;
- X
- X if (stackQCount>=stackQAlloc) {
- X /* need more room */
- X if (stackQAlloc)
- X stackQAlloc *= 2;
- X else
- X stackQAlloc = 120;
- X nbytes = stackQAlloc;
- X if (Qstr)
- X Qstr = realloc(Qstr,nbytes);
- X else
- X Qstr = malloc(nbytes);
- X if (!Qstr)
- X return FALSE;
- X }
- X Qstr[stackQCount++] = c;
- X return TRUE;
- X}
- X
- X/* handles quoted strings; parses string and pushes it onto the stack */
- X/* Note that we do NOT do any backslash processing */
- Xstatic char * /* returns pointer to the closing quote char or NULL on error */
- XStackQstr(p,stopchar)
- Xchar *p; /* pointer to first data char */
- Xchar stopchar; /* the character to stop on */
- X{
- X StackQclear();
- X while (*p && *p!=stopchar) {
- X if (!StackQchar(*p))
- X return NULL; /* no more memory */
- X p++;
- X }
- X if (!*p)
- X return NULL; /* no terminating quote */
- X if (!StackQchar(0))
- X return NULL;
- X if (!StackPushStringCopy(Qstr))
- X return NULL;
- X return p;
- X}
- X
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XStackToBool(n) /* converts stack item n to a bool (int 0/1) */
- Xint n;
- X{
- X int f;
- X
- X switch (stack[n].type) {
- X case MacStackInt:
- X stack[n].d.n = !!stack[n].d.n;
- X break;
- X case MacStackString:
- X if (stack[n].d.s && stack[n].d.s[0]) {
- X f = 1;
- X } else {
- X f = 0;
- X }
- X if (stack[n].d.s)
- X free(stack[n].d.s);
- X stack[n].type = MacStackInt;
- X stack[n].d.n = f;
- X break;
- X default:
- X return FALSE;
- X }
- X return TRUE;
- X}
- X
- X/* Primitives */
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimToBool() /* converts TOS to a bool (int 0/1) */
- X{
- X if (stackCount<1)
- X return FALSE;
- X return (StackToBool(TOS));
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimNot() /* converts TOS to Bool and then invert it */
- X{
- X int f;
- X
- X if (stackCount<1)
- X return FALSE;
- X switch (stack[TOS].type) {
- X case MacStackInt:
- X stack[TOS].d.n = !stack[TOS].d.n;
- X break;
- X case MacStackString:
- X if (stack[TOS].d.s && stack[TOS].d.s[0]) {
- X f = 0;
- X } else {
- X f = 1;
- X }
- X StackPop(1);
- X PUSHINT(f);
- X break;
- X default:
- X return FALSE;
- X }
- X return TRUE;
- X}
- X
- X/* The IfTrue primitive requires a macro name at TOS and a value at TOS-1.
- X * Both values are first removed from the stack.
- X * If the value is TRUE, then the macro is executed, otherwise nothing
- X * else happens.
- X */
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimIfTrue()
- X{
- X char *macroname;
- X int b,t;
- X
- X if (stackCount<2)
- X return FALSE;
- X if (stack[TOS].type!=MacStackString)
- X return FALSE;
- X macroname = stack[TOS].d.s;
- X stack[TOS].d.s = 0;
- X StackPop(1);
- X if (!PrimToBool())
- X return FALSE; /* error testing truth */
- X b = stack[TOS].d.n;
- X StackPop(1);
- X if (b)
- X t = StackDoNamedMacro(macroname);
- X else
- X t = TRUE;
- X free(macroname);
- X return t;
- X}
- X
- X/* The IfElse primitive requires a macro name at TOS,
- X * a macro name at TOS-1, and a condition value at TOS-2.
- X * All three items are first removed from the stack.
- X * If the condition is TRUE, then the macro is which was at TOS-1 is executed,
- X * otherwise the macro which was at TOS is executed.
- X * Thus, you first push the condition value, then the name of the TRUE macro,
- X * then the name of the FALSE macro, then "ifElse", then M.
- X */
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimIfElse()
- X{
- X char *truemacro, *falsemacro;
- X int b,t;
- X
- X if (stackCount<3)
- X return FALSE;
- X if (stack[TOS].type!=MacStackString ||
- X stack[TOS-1].type!=MacStackString)
- X return FALSE;
- X falsemacro = stack[TOS].d.s;
- X stack[TOS].d.s = 0;
- X truemacro = stack[TOS-1].d.s;
- X stack[TOS-1].d.s = 0;
- X StackPop(2);
- X if (!PrimToBool())
- X return FALSE; /* error testing truth */
- X b = stack[TOS].d.n;
- X StackPop(1);
- X if (b)
- X t = StackDoNamedMacro(truemacro);
- X else
- X t = StackDoNamedMacro(falsemacro);
- X free(truemacro);
- X free(falsemacro);
- X return t;
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimPop() /* throws away the top item on the stack */
- X{
- X if (stackCount<1)
- X return FALSE;
- X StackPop(1);
- X return TRUE;
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimPush() /* duplicates the top item on the stack by pushing a copy */
- X{
- X if (stackCount<1)
- X return FALSE;
- X switch (stack[TOS].type) {
- X case MacStackInt:
- X PUSHINT(stack[TOS].d.n);
- X break;
- X case MacStackString:
- X if (!StackPushStringCopy(stack[TOS].d.s))
- X return FALSE;
- X break;
- X default:
- X return FALSE;
- X }
- X return TRUE;
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimExch() /* exchanges the top two items on the stack */
- X{
- X MacStackEntry e;
- X
- X if (stackCount<2)
- X return FALSE;
- X e = stack[TOS]; /* structure copy */
- X stack[TOS] = stack[TOS-1];
- X stack[TOS-1] = e;
- X return TRUE;
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimLimit() /* limits TOS-2 to be between TOS-1 and TOS */
- X{
- X int high,low;
- X
- X if (stackCount<3)
- X return FALSE;
- X if (stack[TOS].type != MacStackInt ||
- X stack[TOS-1].type != MacStackInt ||
- X stack[TOS-2].type != MacStackInt)
- X return FALSE;
- X high = stack[TOS].d.n;
- X low = stack[TOS-1].d.n;
- X StackPop(2);
- X if (stack[TOS].d.n>high)
- X stack[TOS].d.n = high;
- X else if (stack[TOS].d.n<low)
- X stack[TOS].d.n = low;
- X return TRUE;
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimOrd() /* converts a char (string of len 1) to an int */
- X{
- X int ord;
- X
- X if (stackCount<1)
- X return FALSE;
- X if (stack[TOS].type != MacStackString ||
- X strlen(stack[TOS].d.s)!=1)
- X return FALSE;
- X ord = stack[TOS].d.s[0];
- X StackPop(1);
- X PUSHINT(ord);
- X return TRUE;
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimError() /* generates an error (aborts) */
- X{
- X return FALSE; /* simple enough */
- X}
- X
- Xstatic Bool /* returns TRUE if all OK, FALSE if any problems */
- XPrimTekScale() /* generates an error (aborts) */
- X{
- X PUSHINT(TekScale(stackScreen));
- X return TRUE;
- X}
- X
- X
- X/* Macro processing functions */
- X
- Xtypedef struct {
- X char *value;
- X} UmInfo, *UmInfoPtr;
- Xstatic XtResource umresource[] = {
- X { "", "", XtRString, sizeof(String),
- X XtOffset(UmInfoPtr,value),XtRString,NULL},
- X};
- X
- Xstatic String /* returns macro string or NULL if not found */
- XStackFindUserMacro(name)
- XString name;
- X{
- X UserMacro *umlist;
- X UmInfo uminfo;
- X
- X umlist = stackScreen->userMacros;
- X for (; umlist; umlist=umlist->next) {
- X if (strcmp(umlist->name,name)==0)
- X return(umlist->value);
- X }
- X /* not a macro that is already loaded, see if we can load it */
- X umresource[0].resource_name = name;
- X umresource[0].resource_class = name;
- X XtGetSubresources(stackWidget,(caddr_t)&uminfo,
- X "macroString","MacroString",
- X umresource,(Cardinal)1,(ArgList)NULL,(Cardinal)0);
- X if (!uminfo.value)
- X return NULL; /* can't find the macro */
- X umlist = (UserMacro *)malloc(sizeof(UserMacro));
- X if (!umlist)
- X return NULL; /* can't get memory */
- X umlist->name = malloc(strlen(name)+1);
- X if (!umlist->name) {
- X free((char *)umlist);
- X return NULL;
- X }
- X umlist->value = malloc(strlen(uminfo.value)+1);
- X if (!umlist->value) {
- X free(umlist->name);
- X free((char *)umlist);
- X return NULL;
- X }
- X strcpy(umlist->name,name);
- X strcpy(umlist->value,uminfo.value);
- X umlist->next = stackScreen->userMacros;
- X stackScreen->userMacros = umlist;
- X return(umlist->value);
- X}
- X
- X/* handles the "%" formatting; parses format string and operates on stack */
- Xstatic char * /* returns pointer to the last char of the fmt string or NULL */
- XStackFstr(p)
- Xchar *p; /* pointer to first char of formatting string */
- X{
- X static char *fmtchars="-+#*.0123456789";
- X char *buf;
- X
- X if (stackCount<1)
- X return NULL;
- X StackQclear();
- X if (!StackQchar('%'))
- X return NULL;
- X while (*p && (index(fmtchars,*p))) {
- X if (!StackQchar(*p))
- X return NULL;
- X p++;
- X }
- X if (!StackQchar(*p)) /* add the final formatting char */
- X return NULL;
- X if (!StackQchar(0)) /* null terminate the format string */
- X return NULL;
- X switch (*p) {
- X case 0:
- X return NULL;
- X case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': case 'c':
- X if (stack[TOS].type!=MacStackInt)
- X return NULL;
- X buf = malloc(100);
- X if (!buf)
- X return NULL;
- X sprintf(buf,Qstr,stack[TOS].d.n);
- X break;
- X case 's':
- X if (stack[TOS].type!=MacStackString)
- X return NULL;
- X buf = malloc(strlen(stack[TOS].d.s)+100);
- X if (!buf)
- X return NULL;
- X sprintf(buf,Qstr,stack[TOS].d.s);
- X break;
- X default:
- X return NULL;
- X }
- X StackPop(1); /* get rid of converted value */
- X if (!StackPushStringCopy(buf)) {
- X free(buf);
- X return NULL;
- X }
- X free(buf);
- X return p;
- X}
- X
- X/* handles primitives */
- XBool /* returns TRUE if OK, FALSE is any errors */
- XStackDoPrimitive(name)
- Xchar *name;
- X{
- X int i;
- X
- X for (i=0; i<XtNumber(PrimTab); i++) {
- X if (strcmp(PrimTab[i].name,name)==0) {
- X return (*PrimTab[i].func)();
- X }
- X }
- X return FALSE;
- X}
- X
- X/* handles built-in macro strings */
- XBool /* returns TRUE if OK, FALSE is any errors */
- XStackDoBuiltin(name)
- Xchar *name;
- X{
- X int i;
- X
- X for (i=0; i<XtNumber(BuiltinTab); i++) {
- X if (strcmp(BuiltinTab[i].name,name)==0) {
- X return ProcessMacroString(BuiltinTab[i].str);
- X }
- X }
- X return FALSE;
- X}
- X
- X/* handles user defined macro strings */
- XBool /* returns TRUE if OK, FALSE is any errors */
- XStackDoUserMacro(name)
- Xchar *name;
- X{
- X String macrostr;
- X
- X macrostr = StackFindUserMacro(name);
- X if (!macrostr)
- X return FALSE; /* no such macro */
- X return ProcessMacroString(macrostr);
- X}
- X
- X/* handles macro as named at TOS */
- XBool /* returns TRUE if OK, FALSE if any errors */
- XStackDoMacro()
- X{
- X char *macroname;
- X int t;
- X
- X if (stackCount<1 || stack[TOS].type!=MacStackString)
- X return FALSE; /* no macro name */
- X macroname = stack[TOS].d.s;
- X stack[TOS].d.s = 0;
- X StackPop(1); /* remove the macro name from the stack */
- X t = StackDoNamedMacro(macroname);
- X free(macroname);
- X return t;
- X}
- X
- X/* handles macros (primitives, built-in macros, or user macros) */
- XBool /* returns TRUE if OK, FALSE if any errors */
- XStackDoNamedMacro(macroname)
- XString macroname;
- X{
- X /* User macros can override builtin macro strings, but not primitives */
- X if (StackDoPrimitive(macroname) ||
- X StackDoUserMacro(macroname) ||
- X StackDoBuiltin(macroname)) {
- X return TRUE;
- X }
- X return FALSE; /* no such macro */
- X}
- X
- Xstatic int /* returns TRUE if all OK, FALSE if problem (syntax, no memory) */
- XProcessMacroString(macrostring)
- Xchar *macrostring;
- X{
- X char *p;
- X char *newstr;
- X int newnum;
- X int l;
- X int n;
- X Bool b;
- X int radix, hc;
- X KeySym ks;
- X char buf[100];
- X
- X for (p=macrostring;*p;p++) { /* process commands */
- X switch (*p) {
- X case ' ': /* ignore spaces */
- X break;
- X case '"': /* quoted string */
- X case '\'':
- X p = StackQstr(p+1,*p);
- X if (!p)
- X return FALSE; /* error */
- X break;
- X case '%': /* formatted print onto TOS */
- X p = StackFstr(p+1);
- X if (!p)
- X return FALSE; /* error */
- X break;
- X case '+': /* add two numbers or cat two strings */
- X if (stackCount<2)
- X return FALSE;
- X if (stack[TOS].type == MacStackString &&
- X stack[TOS-1].type == MacStackString) {
- X l = strlen(stack[TOS].d.s) +
- X strlen(stack[TOS-1].d.s) + 1;
- X newstr = malloc(l);
- X if (!newstr)
- X return FALSE;
- X strcpy(newstr,stack[TOS-1].d.s);
- X strcat(newstr,stack[TOS].d.s);
- X StackPop(1);
- X free(stack[TOS].d.s);
- X stack[TOS].d.s = newstr;
- X }
- X else if (stack[TOS].type == MacStackInt ||
- X stack[TOS-1].type == MacStackInt) {
- X newnum = stack[TOS-1].d.n + stack[TOS].d.n;
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X }
- X else
- X return FALSE;
- X break;
- X case '-': /* subtract two numbers */
- X if (stackCount<2)
- X return FALSE;
- X if (stack[TOS].type == MacStackInt ||
- X stack[TOS-1].type == MacStackInt) {
- X newnum = stack[TOS-1].d.n - stack[TOS].d.n;
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X }
- X else
- X return FALSE;
- X break;
- X case '*': /* multiply two numbers */
- X if (stackCount<2)
- X return FALSE;
- X if (stack[TOS].type == MacStackInt ||
- X stack[TOS-1].type == MacStackInt) {
- X newnum = stack[TOS-1].d.n * stack[TOS].d.n;
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X }
- X else
- X return FALSE;
- X break;
- X case '/': /* divide two numbers */
- X if (stackCount<2)
- X return FALSE;
- X if (stack[TOS].type == MacStackInt ||
- X stack[TOS-1].type == MacStackInt) {
- X newnum = stack[TOS-1].d.n / stack[TOS].d.n;
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X }
- X else
- X return FALSE;
- X break;
- X case '<': /* left shift (<<) */
- X if ((*(++p))!='<')
- X return FALSE;
- X if (stackCount<2)
- X return FALSE;
- X if (stack[TOS].type == MacStackInt &&
- X stack[TOS-1].type == MacStackInt) {
- X newnum = stack[TOS-1].d.n << stack[TOS].d.n;
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X }
- X else
- X return FALSE;
- X break;
- X case '>': /* right shift (>>) */
- X if ((*(++p))!='>')
- X return FALSE;
- X if (stackCount<2)
- X return FALSE;
- X if (stack[TOS].type == MacStackInt &&
- X stack[TOS-1].type == MacStackInt) {
- X newnum = stack[TOS-1].d.n >> stack[TOS].d.n;
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X }
- X else
- X return FALSE;
- X break;
- X case '|': /* logical or bitwise OR */
- X if (stackCount<2)
- X return FALSE;
- X if (p[1]=='|') { /* logical */
- X p++;
- X if (!(StackToBool(TOS) && StackToBool(TOS-1)))
- X return FALSE;
- X newnum = stack[TOS-1].d.n || stack[TOS].d.n;
- X } else { /* bitwise */
- X if (stack[TOS].type != MacStackInt ||
- X stack[TOS-1].type != MacStackInt)
- X return FALSE;
- X newnum = stack[TOS-1].d.n | stack[TOS].d.n;
- X }
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X break;
- X case '&': /* logical or bitwise AND */
- X if (stackCount<2)
- X return FALSE;
- X if (p[1]=='&') { /* logical */
- X p++;
- X if (!(StackToBool(TOS) && StackToBool(TOS-1)))
- X return FALSE;
- X newnum = stack[TOS-1].d.n && stack[TOS].d.n;
- X } else { /* bitwise */
- X if (stack[TOS].type != MacStackInt ||
- X stack[TOS-1].type != MacStackInt)
- X return FALSE;
- X newnum = stack[TOS-1].d.n & stack[TOS].d.n;
- X }
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X break;
- X case '^': /* logical or bitwise XOR */
- X if (stackCount<2)
- X return FALSE;
- X if (p[1]=='^') { /* logical */
- X p++;
- X if (!(StackToBool(TOS) && StackToBool(TOS-1)))
- X return FALSE;
- X newnum = stack[TOS-1].d.n ^ stack[TOS].d.n;
- X } else { /* bitwise */
- X if (stack[TOS].type != MacStackInt ||
- X stack[TOS-1].type != MacStackInt)
- X return FALSE;
- X newnum = stack[TOS-1].d.n ^ stack[TOS].d.n;
- X }
- X StackPop(1);
- X stack[TOS].d.n = newnum;
- X break;
- X case '!': /* logical not */
- X if (!PrimNot())
- X return FALSE;
- X break;
- X case '~': /* bitwise invert */
- X if (stackCount<1)
- X return FALSE;
- X if (stack[TOS].type == MacStackInt) {
- X newnum = ~stack[TOS-1].d.n;
- X stack[TOS].d.n = newnum;
- X }
- X else
- X return FALSE;
- X break;
- X case '0': case '1': case '2': case '3': case '4':
- X case '5': case '6': case '7': case '8': case '9':
- X newnum = 0;
- X if ((*p)=='0') {
- X if (p[1]=='x' || p[1]=='X') {
- X radix = 16;
- X p+=2;
- X }
- X else
- X radix = 8;
- X }
- X else
- X radix = 10;
- X while (isdigit(*p) || (radix==16&&ishexalpha(*p))) {
- X newnum *= radix;
- X if (radix==16&&ishexalpha(*p)) {
- X hc = *p;
- X if (islower(hc))
- X hc = toupper(hc);
- X newnum += hc - 'A' + 10;
- X }
- X else
- X newnum += *p - '0';
- X p++;
- X }
- X --p; /* have to leave it pointing to last char */
- X PUSHINT(newnum);
- X break;
- X case 'b': /* put button field from event onto stack */
- X PUSHINT(stackEvent->xbutton.button);
- X break;
- X case 'c': /* put cursor col onto stack (0 is leftmost) */
- X PUSHINT(CursorCol(stackScreen,stackEvent->xbutton.x));
- X break;
- X case 'C': /* put number of cols on screen onto stack */
- X PUSHINT(stackScreen->max_col+1);
- X break;
- X case 'h': /* put pixel height of a char on stack */
- X PUSHINT(FontHeight(stackScreen));
- X break;
- X case 'H': /* put pixel height of screen on stack */
- X PUSHINT(stackScreen->fullVwin.height);
- X break;
- X case 'i': /* send TOS as input */
- X if (stackCount<1)
- X return FALSE;
- X if (stack[TOS].type == MacStackString)
- X StringInput(stackScreen,stack[TOS].d.s);
- X else
- X return FALSE;
- X StackPop(1);
- X break;
- X case 'k': /* put keycode field from event onto stack */
- X PUSHINT(stackEvent->xkey.keycode);
- X break;
- X case 'l': /* put results of XLookupString on stack */
- X n = XLookupString(stackEvent,buf,sizeof(buf)-1,&ks,0);
- X if (n>0) {
- X newstr = malloc(n+1);
- X if (!newstr)
- X return FALSE;
- X strcpy(newstr,buf);
- X if (!StackPushString(newstr))
- X return FALSE;
- X } else { /* no translation, use null string */
- X if (!StackPushStringCopy(""))
- X return FALSE;
- X }
- X break;
- X case 'M': /* execute macro */
- X if (!StackDoMacro())
- X return FALSE;
- X break;
- X case 'r': /* put cursor row onto stack (0 is topmost) */
- X PUSHINT(CursorRow(stackScreen,stackEvent->xbutton.y));
- X break;
- X case 'R': /* put number of rows on screen onto stack */
- X PUSHINT(stackScreen->max_row+1);
- X break;
- X case 's': /* put state field from event onto stack */
- X PUSHINT(stackEvent->xbutton.state);
- X break;
- X case 'w': /* put pixel width of a char on stack */
- X PUSHINT(FontWidth(stackScreen));
- X break;
- X case 'W': /* put pixel width of screen on stack */
- X PUSHINT(stackScreen->fullVwin.width);
- X break;
- X case 'x': /* put x pixel value of cursor on stack */
- X PUSHINT(stackEvent->xbutton.x - stackScreen->border -
- X stackScreen->scrollbar);
- X break;
- X case 'y': /* put y pixel value of cursor on stack */
- X PUSHINT(stackEvent->xbutton.y - stackScreen->border);
- X break;
- X case 'X': /* put x_root pixel value of cursor on stack */
- X PUSHINT(stackEvent->xbutton.x_root);
- X break;
- X case 'Y': /* put y_root pixel value of cursor on stack */
- X PUSHINT(stackEvent->xbutton.y_root);
- X break;
- X case 'Z': /* conditional return/end of macro */
- X if (stackCount<1)
- X return FALSE; /* error */
- X if (!PrimToBool())
- X return FALSE; /* error testing truth */
- X b = stack[TOS].d.n;
- X StackPop(1);
- X if (b)
- X return TRUE; /* if true, end of this macro */
- X /* else do nothing */
- X break;
- X default:
- X return FALSE;
- X }
- X }
- X return TRUE; /* finished without errors */
- X}
- X
- X/* This is the action function called from the translation table */
- Xvoid
- XHandleMacroString(w,event,params,param_count)
- XWidget w;
- XXEvent *event;
- XString *params;
- Xint *param_count;
- X{
- X
- X if (*param_count != 1)
- X return;
- X StackClear(); /* clear the stack machine */
- X stackScreen = &((XtermWidget)w)->screen;
- X stackWidget = w;
- X stackEvent = event;
- X if (!ProcessMacroString(params[0])) {
- X Bell(); /* some sort of error */
- X }
- X}
- X
- X/* end */
- END_OF_macrostr.c
- if test 24964 -ne `wc -c <macrostr.c`; then
- echo shar: \"macrostr.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-