home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume5 / macstr / part01 next >
Encoding:
Internet Message Format  |  1989-12-06  |  47.8 KB

  1. Path: uunet!island!argv
  2. From: argv@island.uu.net (Dan Heller)
  3. Newsgroups: comp.sources.x
  4. Subject: v05i037: macro-string enhancement for Xterm, Part01/01
  5. Message-ID: <1232@island.uu.net>
  6. Date: 5 Dec 89 19:06:04 GMT
  7. Organization: Island Graphics, Marin County, California
  8. Lines: 1657
  9. Approved: island!argv@sun.com
  10.  
  11. Submitted-by: uunet!zax!sci!jimmc (Jim McBeath)
  12. Posting-number: Volume 5, Issue 37
  13. Archive-name: macstr/part01
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. ##  This is a shell archive.  Remove anything before this line, then unpack
  19. ##  it by saving it into a file and typing "sh file".  To overwrite existing
  20. ##  files, type "sh file -c".  You can also feed this as standard input via
  21. ##  unshar, or by typing "sh <file".  If this archive is complete, you will
  22. ##  see the following message at the end:
  23. #        "End of shell archive."
  24. # Contents:  README.macrostr xterm.man.diff Imakefile.diff
  25. #   Makefile.diff ptyx.h.diff charproc.c.diff macrostr.c
  26. # Wrapped by jimmc@zax on Mon Nov 13 17:14:21 1989
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f README.macrostr -a "${1}" != "-c" ; then 
  29.   echo shar: Will not over-write existing file \"README.macrostr\"
  30. else
  31. echo shar: Extracting \"README.macrostr\" \(553 characters\)
  32. sed "s/^X//" >README.macrostr <<'END_OF_README.macrostr'
  33. XThe macro string package is intended to allow xterm to generate the character
  34. Xsequences for button presses on just about any terminal you can think of.
  35. XIt is a general enough mechanism that you may find other uses for it as well.
  36. XInstallation requires the addition of one major new file (macrostr.c) and some
  37. Xone-line changes to a few other files.  See the updated man pages for details
  38. Xon how the macro string capability is used.  Copyright has been donated to
  39. XMIT using their standard copyright notice.
  40. X
  41. XJim McBeath    13.Nov.89
  42. Xsci!jimmc@decwrl.dec.com
  43. END_OF_README.macrostr
  44. if test 553 -ne `wc -c <README.macrostr`; then
  45.     echo shar: \"README.macrostr\" unpacked with wrong size!
  46. fi
  47. # end of overwriting check
  48. fi
  49. if test -f xterm.man.diff -a "${1}" != "-c" ; then 
  50.   echo shar: Will not over-write existing file \"xterm.man.diff\"
  51. else
  52. echo shar: Extracting \"xterm.man.diff\" \(14424 characters\)
  53. sed "s/^X//" >xterm.man.diff <<'END_OF_xterm.man.diff'
  54. X1c1
  55. X< .TH XTERM 1 "25 October 1988" "X Version 11"
  56. X---
  57. X> .TH XTERM 1 " 7 November 1989" "X Version 11"
  58. X222c222
  59. X< cause the window to be repositioned automatically in the normal postion at the
  60. X---
  61. X> cause the window to be repositioned automatically in the normal position at the
  62. X264c264
  63. X< This option indicates that a visual bell is prefered over an audible one.
  64. X---
  65. X> This option indicates that a visual bell is preferred over an audible one.
  66. X286c286
  67. X< This option specifies the prefered size and position of the Tektronix window.
  68. X---
  69. X> This option specifies the preferred size and position of the Tektronix window.
  70. X290c290
  71. X< This option specifies the prefered position of the icon window.
  72. X---
  73. X> This option specifies the preferred position of the icon window.
  74. X316c316
  75. X< instead of the user's shell.  \fBThis option has been superceeded by the new
  76. X---
  77. X> instead of the user's shell.  \fBThis option has been superceded by the new
  78. X358c358
  79. X< This option specifies the prefered size and position of the VT102 window;
  80. X---
  81. X> This option specifies the preferred size and position of the VT102 window;
  82. X376c376
  83. X< Specifies the prefered size and position of the application when iconified.
  84. X---
  85. X> Specifies the preferred size and position of the application when iconified.
  86. X457c457
  87. X< Specifies the prefered size and position of the VT102 window.
  88. X---
  89. X> Specifies the preferred size and position of the VT102 window.
  90. X460c460
  91. X< Specifies the prefered size and position of the Tektronix window.
  92. X---
  93. X> Specifies the preferred size and position of the Tektronix window.
  94. X713c713
  95. X< To distinquish a pointer button from a key, the high bit of the character is
  96. X---
  97. X> To distinguish a pointer button from a key, the high bit of the character is
  98. X785c785
  99. X< X environments differ in their security conciousness.  The servers provided
  100. X---
  101. X> X environments differ in their security consciousness.  The servers provided
  102. X911a912,919
  103. X> .B macro-string(\fImacro-string\fB)
  104. X> Rebinds the key or key sequence to the macro-string value.
  105. X> When this action is executed, the macro string is processed, which normally
  106. X> inserts a string into the input stream.
  107. X> This capability is useful for emulating the wide variety of character sequences
  108. X> that are produced by a button press on various terminals.
  109. X> For more details, see the section "MACRO STRINGS" below.
  110. X> .TP 15
  111. X994a1003,1368
  112. X> .SH "MACRO STRINGS"
  113. X> .PP
  114. X> Xterm includes a fairly general macro-string processing capability intended
  115. X> to allow emulation of the button-press sequences of just about any terminal
  116. X> type.
  117. X> The macro-string processor is a simple stack machine which interprets a
  118. X> macro string.
  119. X> The macro string can contain commands which access state information
  120. X> (such as the X and Y location of the mouse), manipulate the stack (such
  121. X> as doing arithmetic operations), and insert text into the terminal
  122. X> input buffer (which is the desired end result of the macro string).
  123. X> There are rudimentary programming commands (conditional execution,
  124. X> subroutine calls), built-in primitives and macro strings, and user-definable
  125. X> macro strings.
  126. X> .PP
  127. X> A macro string is interpreted one token at a time.
  128. X> Operations are expressed in RPN, i.e. operands first (which are placed onto
  129. X> the stack) followed by operation (which operates on the stack).
  130. X> White space in a macro string is ignored.
  131. X> If there is an error in processing a macro string, the Bell() function
  132. X> is called.
  133. X> .PP
  134. X> There are two data types: integer and string.
  135. X> Boolean operations result in an integer where FALSE is represented by
  136. X> 0 and TRUE is represented by 1.
  137. X> When interpreting an integer as a Boolean, 0 is considered
  138. X> FALSE and anything else is considered TRUE.
  139. X> When interpreting a string as a Boolean, NULL or the empty string is
  140. X> considered FALSE and anything else is considered TRUE.
  141. X> .PP
  142. X> In the descriptions below, the term TOS represents the value of the
  143. X> top item on the stack, TOS-1 is the next-to-top, etc.
  144. X> .PP
  145. X> The macro-string commands are as follows:
  146. X> .TP 15
  147. X> .B "\'string\'"
  148. X> Single-quoted string.
  149. X> Pushes the quoted string onto the stack.
  150. X> The string can contain any character except NULL and single quote.
  151. X> There is no backslash notation and no provision for including a single
  152. X> quote within a single-quoted string.
  153. X> You can use a double-quoted string if you need to include a single
  154. X> quote in your string.
  155. X> Note also that the various parsers used to load this string (i.e. the
  156. X> C compiler if it is a built-in macro string, or the resource manager if
  157. X> it is from a resource or default file) can handle backslash notation, so
  158. X> you can include control characters in a quoted string.
  159. X> .TP 15
  160. X> .ft 3
  161. X> "string"
  162. X> .}N
  163. X> Double-quoted string.
  164. X> Pushes the quoted string onto the stack.
  165. X> This behaves in exactly the same way as a single-quoted string, except that
  166. X> when using a double-quoted string you can include single quotes in the
  167. X> string but not double quotes.
  168. X> .TP 15
  169. X> .B "printf formatting"
  170. X> You can convert TOS to a string using standard printf formatting commands.
  171. X> For example, if TOS is the integer 123, then the command "%04d" would
  172. X> replace TOS with the string "0123", and the command "%X" would replace
  173. X> TOS with the string "7B".
  174. X> The formatting string is only a single "%" sequence, and only converts
  175. X> the top item on the stack to a string.
  176. X> .TP 15
  177. X> .B "+"
  178. X> Add or catenate.
  179. X> If TOS and TOS-1 are both integers,
  180. X> replaces TOS and TOS-1 with (TOS-1 + TOS).
  181. X> If TOS and TOS-1 are both strings, replaces TOS and TOS-1 with
  182. X> the catenation of TOS-1 and TOS.
  183. X> .TP 15
  184. X> .B "-"
  185. X> Subtract.
  186. X> Replaces TOS and TOS-1 with (TOS-1 - TOS).
  187. X> TOS and TOS-1 must both be integers.
  188. X> .TP 15
  189. X> .B "*"
  190. X> Multiply.
  191. X> Replaces TOS and TOS-1 with (TOS-1 * TOS).
  192. X> TOS and TOS-1 must both be integers.
  193. X> .TP 15
  194. X> .B "/"
  195. X> Integer divide.
  196. X> Replaces TOS and TOS-1 with (TOS-1 / TOS).
  197. X> TOS and TOS-1 must both be integers.
  198. X> .TP 15
  199. X> .B "<<"
  200. X> Left shift.
  201. X> Replaces TOS and TOS-1 with (TOS-1 << TOS).
  202. X> TOS and TOS-1 must both be integers.
  203. X> .TP 15
  204. X> .B ">>"
  205. X> Right shift.
  206. X> Replaces TOS and TOS-1 with (TOS-1 >> TOS).
  207. X> TOS and TOS-1 must both be integers.
  208. X> .TP 15
  209. X> .B "|"
  210. X> Bitwise OR.
  211. X> Replaces TOS and TOS-1 with (TOS-1 | TOS).
  212. X> TOS and TOS-1 must both be integers.
  213. X> .TP 15
  214. X> .B "||"
  215. X> Logical OR.
  216. X> Replaces TOS and TOS-1 with (TOS-1 || TOS).
  217. X> TOS and TOS-1 are independently considered as Booleans.
  218. X> .TP 15
  219. X> .B "&"
  220. X> Bitwise AND.
  221. X> Replaces TOS and TOS-1 with (TOS-1 & TOS).
  222. X> TOS and TOS-1 must both be integers.
  223. X> .TP 15
  224. X> .B "&&"
  225. X> Logical AND.
  226. X> Replaces TOS and TOS-1 with (TOS-1 && TOS).
  227. X> TOS and TOS-1 are independently considered as Booleans.
  228. X> .TP 15
  229. X> .B "^"
  230. X> Bitwise XOR.
  231. X> Replaces TOS and TOS-1 with (TOS-1 ^ TOS).
  232. X> TOS and TOS-1 must both be integers.
  233. X> .TP 15
  234. X> .B "^^"
  235. X> Logical XOR.
  236. X> Replaces TOS and TOS-1 with (TOS-1 ^^ TOS).
  237. X> TOS and TOS-1 are independently considered as Booleans.
  238. X> .TP 15
  239. X> .B "!"
  240. X> Logical NOT.
  241. X> Replaces TOS by the logical inverse of TOS when considered as a Boolean.
  242. X> .TP 15
  243. X> .B "~"
  244. X> Bitwise invert.
  245. X> Replaces TOS by the bitwise inversion of TOS.
  246. X> TOS must be an integer.
  247. X> .TP 15
  248. X> .B number
  249. X> Numbers can be entered in decimal, octal or hexadecimal radix.
  250. X> A simple string of digits, not starting with a 0, pushes a decimal
  251. X> value onto the stack.
  252. X> If the first digit in the string is 0 and the remainder of digits are
  253. X> between 0 and 7, the number is input as an octal number and pushed onto
  254. X> the stack.
  255. X> If the first digit in the string is 0 and it is immediately followed
  256. X> by x or X, the number is input as a hexadecimal number and pushed onto
  257. X> the stack.
  258. X> .TP 15
  259. X> .B b
  260. X> Pushes the button field from a button event onto the stack.
  261. X> .TP 15
  262. X> .B c
  263. X> Pushes the cursor column from a key or button event onto the stack.
  264. X> The leftmost column is column 0.
  265. X> .TP 15
  266. X> .B C
  267. X> Pushes the column width of the screen onto the stack.
  268. X> .TP 15
  269. X> .B h
  270. X> Pushes the pixel height of a character onto the stack.
  271. X> .TP 15
  272. X> .B H
  273. X> Pushes the pixel height of the screen onto the stack.
  274. X> .TP 15
  275. X> .B i
  276. X> Places TOS (must be a string) into the terminal input buffer
  277. X> and pops it off the stack.
  278. X> .TP 15
  279. X> .B k
  280. X> Pushes the keycode field from a key event onto the stack.
  281. X> .TP 15
  282. X> .B l
  283. X> Puts the results of XLookupString on a key event onto the stack.
  284. X> If XLookupString returns an error or no string, an empty string is
  285. X> pushed onto the stack.
  286. X> .TP 15
  287. X> .B M
  288. X> Pop TOS (which must be a string) and interpret the macro of that name.
  289. X> The macro may be either a primitive or built-in (both compiled into xterm)
  290. X> or a user-defined macro.
  291. X> User defined macros override built-in macros, but not primitives.
  292. X> The list of primitives and built-in macros is given below.
  293. X> .TP 15
  294. X> .B r
  295. X> Pushes the cursor row from a key or button event onto the stack.
  296. X> The topmost row is 0.
  297. X> .TP 15
  298. X> .B R
  299. X> Pushes the row height of the screen onto the stack.
  300. X> .TP 15
  301. X> .B s
  302. X> Pushes the state field from a key or button event onto the stack.
  303. X> .TP 15
  304. X> .B w
  305. X> Pushes the pixel width of a character onto the stack.
  306. X> .TP 15
  307. X> .B W
  308. X> Pushes the pixel width of the screen onto the stack.
  309. X> .TP 15
  310. X> .B x
  311. X> Pushes the x pixel value from a key or button event onto the stack.
  312. X> .TP 15
  313. X> .B X
  314. X> Pushes to x_root pixel value from a key or button event onto the stack.
  315. X> .TP 15
  316. X> .B y
  317. X> Pushes the y pixel value from a key or button event onto the stack.
  318. X> .TP 15
  319. X> .B Y
  320. X> Pushes the y_root pixel value from a key or button event onto the stack.
  321. X> .TP 15
  322. X> .B Z
  323. X> Conditionally returns from (terminates) a macro.
  324. X> Pops TOS and interprets it as a Bool; if TRUE, returns from the macro,
  325. X> else does nothing.
  326. X> .PP
  327. X> Primitive functions are compiled into Xterm and can not be overridden.
  328. X> The primitives are:
  329. X> .TP 15
  330. X> .B error
  331. X> Generates an error; calls Bell() and aborts all macro string processing.
  332. X> This is typically used with an "if" statement to abort a macro if
  333. X> an error condition occurs.
  334. X> .TP 15
  335. X> .B exch
  336. X> Exchanges TOS with TOS-1.
  337. X> .TP 15
  338. X> .B if
  339. X> Examines TOS-1 as a Boolean; if TRUE, executes the macro named at TOS,
  340. X> else does nothing.
  341. X> In either case, the two values are popped off the stack before the
  342. X> test is performed.
  343. X> .TP 15
  344. X> .B ifElse
  345. X> Examines TOS-2 as a Boolean; if TRUE, executes the macro named at TOS-1,
  346. X> else executes the macro named at TOS.
  347. X> In either case, the three values are popped off the stack before the
  348. X> test is performed.
  349. X> .TP 15
  350. X> .B limit
  351. X> Limits TOS-2 to be between TOS-1 and TOS.
  352. X> If TOS-2 is less than TOS-1, replaces it with TOS-1.
  353. X> If TOS-2 is greater than TOS, replaces it with TOS.
  354. X> All three items must be integers.
  355. X> Pops two items off the stack, leaving only the limited number.
  356. X> .TP 15
  357. X> .B ord
  358. X> Converts a one-character string at TOS to an integer with the
  359. X> equivalent integer value (essentially a "scanf %c").
  360. X> .TP 15
  361. X> .B pop
  362. X> Pops one item off the stack and discards it.
  363. X> .TP 15
  364. X> .B push
  365. X> Pushes the top item onto the stack again, duplicating it.
  366. X> .TP 15
  367. X> .B tekScale
  368. X> Pushes the tekScale field of the screen onto the stack.
  369. X> Useful for emulating the Tektronix mode buttons.
  370. X> .TP 15
  371. X> .B toBool
  372. X> Converts TOS to a Boolean (integer 0 or 1).
  373. X> 
  374. X> .PP
  375. X> There are a number of built-in macros, which are simply macro strings
  376. X> which are compiled into xterm.
  377. X> These built-ins can be overridden by a user defined macro.
  378. X> The built-ins are listed below, with the definitions of some given
  379. X> as examples.
  380. X> .TP 15
  381. X> .B SeikoButton
  382. X> Generates the character sequence for button presses on a Seiko terminal.
  383. X> There are a number of associated built-ins that are a part of this package:
  384. X> SeikoGetX, SeikoGetY, SeikoSub1, SeikoEnd.
  385. X> To set up your xterm so that it generates Seiko character sequences for
  386. X> the buttons when the shift key is held down, you could add the following
  387. X> lines to your resource file:
  388. X> .sp
  389. X> .Ds
  390. X>  *VT100.translations: #override \\n\\
  391. X>     Shift <BtnDown> : macro-string("'SeikoButton'M") \\n\\
  392. X>     Shift <BtnUp> : ignore()
  393. X> .De
  394. X> .TP 15
  395. X> .B X10Button
  396. X> Generates the character sequence that the X10 xterm generated for button
  397. X> pushes.
  398. X> This macro is implemented with this string:
  399. X> .sp
  400. X> .Ds
  401. X>  '\\033[M'i31b+%ci33c+%ci33r+%ci
  402. X> .De
  403. X> .TP 15
  404. X> .B VT200ButtonPress
  405. X> Generates the character sequence for a VT200 button press.
  406. X> This macro is implemented with this string:
  407. X> .sp
  408. X> .Ds
  409. X>  '\\033['iM31'VT200KeyState'M+b+%ci33c+%ci33r+%ci
  410. X> .De
  411. X> .TP 15
  412. X> .B VT200KeyState
  413. X> Called by the VT200ButtonPress macro.
  414. X> This macro is implemented with this string:
  415. X> .sp
  416. X> .Ds
  417. X>  s5&s8&2>>+
  418. X> .De
  419. X> .TP 15
  420. X> .B TekButton
  421. X> Generates the character sequence for a Tektronix button press.
  422. X> Associated macros are TekGetBchar, TekGetlbchar, TekUcase, and TekSub1.
  423. X> .TP 15
  424. X> .B TestConst
  425. X> Generates a character string with a number of screen-dependent values,
  426. X> implemented with this string:
  427. X> .sp
  428. X> .Ds
  429. X>  'h='ih%di' w='iw%di' H='iH%di' W='iW%di' R='iR%di' C='iC%di'\\n'i
  430. X> .De
  431. X> .TP 15
  432. X> .B TestButton
  433. X> Generates a character string with a number of position-dependent values,
  434. X> suitable for binding to a button,
  435. X> implemented with this string:
  436. X> .sp
  437. X> .Ds
  438. X>  'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\\
  439. X>  ' r='ir%di' c='ic%di' b='ib%di' s='is%xi'\\n'i
  440. X> .De
  441. X> .TP 15
  442. X> .B TestKey
  443. X> Generates a character string with a number of position-dependent values,
  444. X> suitable for binding to a key,
  445. X> implemented with this string:
  446. X> .sp
  447. X> .Ds
  448. X>  'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\\
  449. X>  ' r='ir%di' c='ic%di' k='ik%di' s='is%xi' l=\\"'ili'\\"\\n'i
  450. X> .De
  451. X> .PP
  452. X> You could add the following bindings to execute the test macros to
  453. X> see how the values look:
  454. X> .sp
  455. X> .Ds
  456. X>  *VT100.translations: #override \\n\\
  457. X>     <Key>F5 : macro-string("'TestConst'M") \\n\\
  458. X>     <Key>F6 : macro-string("'TestKey'M")
  459. X> .De
  460. X> .PP
  461. X> User defined macros can be specified in your resource or Xdefaults file.
  462. X> Macros are searched for as subresources of the xterm widget, where the
  463. X> subobject name is "macroString" and the subresource name is the macro name.
  464. X> For example, to define a macro named foo that prints out the string
  465. X> "button" and the button number, you could put this line in your resource file:
  466. X> .sp
  467. X> .Ds
  468. X>  *VT100.macroString.foo: 'button 'i b%di
  469. X> .De
  470. X> .PP
  471. X> You could then bind this macro to a key with a line like:
  472. X> .sp
  473. X> .Ds
  474. X>  *VT100.translations: #override \\n\\
  475. X>     <Key>F7 : macro-string("'foo'M")
  476. X> .De
  477. X> 
  478. X1125c1499
  479. X< Consortium), Dave Serisky (HP)
  480. X---
  481. X> Consortium), Dave Serisky (HP), Jim McBeath (Silicon Compilers)
  482. END_OF_xterm.man.diff
  483. if test 14424 -ne `wc -c <xterm.man.diff`; then
  484.     echo shar: \"xterm.man.diff\" unpacked with wrong size!
  485. fi
  486. # end of overwriting check
  487. fi
  488. if test -f Imakefile.diff -a "${1}" != "-c" ; then 
  489.   echo shar: Will not over-write existing file \"Imakefile.diff\"
  490. else
  491. echo shar: Extracting \"Imakefile.diff\" \(1173 characters\)
  492. sed "s/^X//" >Imakefile.diff <<'END_OF_Imakefile.diff'
  493. X*** Imakefile.orig    Thu May 18 19:57:44 1989
  494. X--- Imakefile    Fri Oct 27 13:44:02 1989
  495. X***************
  496. X*** 27,36 ****
  497. X  /* add -DWTMP and -DLASTLOG if you want them */
  498. X          DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy GettyProgram
  499. X            SRCS1 = button.c charproc.c cursor.c data.c input.c \
  500. X!           main.c menu.c misc.c screen.c scrollbar.c tabs.c \
  501. X            TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
  502. X            OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
  503. X!           screen.o scrollbar.o button.o Tekproc.o misc.o \
  504. X            VTPrsTbl.o TekPrsTbl.o data.o menu.o
  505. X            SRCS2 = resize.c
  506. X            OBJS2 = resize.o
  507. X--- 27,36 ----
  508. X  /* add -DWTMP and -DLASTLOG if you want them */
  509. X          DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy GettyProgram
  510. X            SRCS1 = button.c charproc.c cursor.c data.c input.c \
  511. X!           macrostr.c main.c menu.c misc.c screen.c scrollbar.c tabs.c \
  512. X            TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
  513. X            OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
  514. X!           screen.o scrollbar.o button.o Tekproc.o misc.o macrostr.o \
  515. X            VTPrsTbl.o TekPrsTbl.o data.o menu.o
  516. X            SRCS2 = resize.c
  517. X            OBJS2 = resize.o
  518. END_OF_Imakefile.diff
  519. if test 1173 -ne `wc -c <Imakefile.diff`; then
  520.     echo shar: \"Imakefile.diff\" unpacked with wrong size!
  521. fi
  522. # end of overwriting check
  523. fi
  524. if test -f Makefile.diff -a "${1}" != "-c" ; then 
  525.   echo shar: Will not over-write existing file \"Makefile.diff\"
  526. else
  527. echo shar: Extracting \"Makefile.diff\" \(1055 characters\)
  528. sed "s/^X//" >Makefile.diff <<'END_OF_Makefile.diff'
  529. X*** Makefile.orig    Fri Oct 27 12:58:09 1989
  530. X--- Makefile    Fri Oct 27 15:39:17 1989
  531. X***************
  532. X*** 167,176 ****
  533. X  
  534. X          DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy
  535. X            SRCS1 = button.c charproc.c cursor.c data.c input.c \
  536. X!           main.c menu.c misc.c screen.c scrollbar.c tabs.c \
  537. X            TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
  538. X            OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
  539. X!           screen.o scrollbar.o button.o Tekproc.o misc.o \
  540. X            VTPrsTbl.o TekPrsTbl.o data.o menu.o
  541. X            SRCS2 = resize.c
  542. X            OBJS2 = resize.o
  543. X--- 167,176 ----
  544. X  
  545. X          DEFINES = -DMODEMENU -DUTMP -DBcopy=bcopy
  546. X            SRCS1 = button.c charproc.c cursor.c data.c input.c \
  547. X!           macrostr.c main.c menu.c misc.c screen.c scrollbar.c tabs.c \
  548. X            TekPrsTbl.c Tekproc.c util.c VTPrsTbl.c
  549. X            OBJS1 = main.o input.o charproc.o cursor.o util.o tabs.o \
  550. X!           screen.o scrollbar.o button.o Tekproc.o misc.o macrostr.o \
  551. X            VTPrsTbl.o TekPrsTbl.o data.o menu.o
  552. X            SRCS2 = resize.c
  553. X            OBJS2 = resize.o
  554. END_OF_Makefile.diff
  555. if test 1055 -ne `wc -c <Makefile.diff`; then
  556.     echo shar: \"Makefile.diff\" unpacked with wrong size!
  557. fi
  558. # end of overwriting check
  559. fi
  560. if test -f ptyx.h.diff -a "${1}" != "-c" ; then 
  561.   echo shar: Will not over-write existing file \"ptyx.h.diff\"
  562. else
  563. echo shar: Extracting \"ptyx.h.diff\" \(701 characters\)
  564. sed "s/^X//" >ptyx.h.diff <<'END_OF_ptyx.h.diff'
  565. X*** ptyx.h.orig    Thu May 18 19:56:42 1989
  566. X--- ptyx.h    Tue Nov  7 09:23:09 1989
  567. X***************
  568. X*** 191,196 ****
  569. X--- 191,202 ----
  570. X      int height;
  571. X  } BitmapBits;
  572. X  
  573. X+ typedef struct _userMacro {
  574. X+     struct _userMacro *next;
  575. X+     String name;
  576. X+     String value;
  577. X+ } UserMacro;
  578. X+ 
  579. X  #define    SAVELINES        64      /* default # lines to save      */
  580. X  
  581. X  typedef struct {
  582. X***************
  583. X*** 344,349 ****
  584. X--- 350,356 ----
  585. X      Atom*        selection_atoms; /* which selections we own */
  586. X      Cardinal    sel_atoms_size;    /*  how many atoms allocated */
  587. X      Cardinal    selection_count; /* how many atoms in use */
  588. X+     UserMacro    *userMacros;    /* list of user macro-strings */
  589. X  } TScreen;
  590. X  
  591. X  /* meaning of bits in screen.select flag */
  592. END_OF_ptyx.h.diff
  593. if test 701 -ne `wc -c <ptyx.h.diff`; then
  594.     echo shar: \"ptyx.h.diff\" unpacked with wrong size!
  595. fi
  596. # end of overwriting check
  597. fi
  598. if test -f charproc.c.diff -a "${1}" != "-c" ; then 
  599.   echo shar: Will not over-write existing file \"charproc.c.diff\"
  600. else
  601. echo shar: Extracting \"charproc.c.diff\" \(741 characters\)
  602. sed "s/^X//" >charproc.c.diff <<'END_OF_charproc.c.diff'
  603. X*** charproc.c.orig    Thu May 18 19:58:00 1989
  604. X--- charproc.c    Fri Oct 27 13:45:47 1989
  605. X***************
  606. X*** 164,169 ****
  607. X--- 164,170 ----
  608. X  extern void HandleLeaveWindow();
  609. X  extern void HandleFocusChange();
  610. X         void HandleKeymapChange();
  611. X+ extern void HandleMacroString();
  612. X  extern void HandleModeMenu();
  613. X  extern void HandleInsertSelection();
  614. X  extern void HandleSelectStart();
  615. X***************
  616. X*** 210,215 ****
  617. X--- 211,217 ----
  618. X      { "insert",          HandleKeyPressed },
  619. X      { "insert-selection", HandleInsertSelection },
  620. X      { "keymap",       HandleKeymapChange },
  621. X+     { "macro-string",      HandleMacroString },
  622. X      { "mode-menu",      HandleModeMenu },
  623. X      { "secure",          HandleSecure },
  624. X      { "select-start",      HandleSelectStart },
  625. END_OF_charproc.c.diff
  626. if test 741 -ne `wc -c <charproc.c.diff`; then
  627.     echo shar: \"charproc.c.diff\" unpacked with wrong size!
  628. fi
  629. # end of overwriting check
  630. fi
  631. if test -f macrostr.c -a "${1}" != "-c" ; then 
  632.   echo shar: Will not over-write existing file \"macrostr.c\"
  633. else
  634. echo shar: Extracting \"macrostr.c\" \(24964 characters\)
  635. sed "s/^X//" >macrostr.c <<'END_OF_macrostr.c'
  636. X/* macrostr.c - handle macro string capability
  637. X *
  638. X * 26.Oct.89  Jim McBeath    Initial definition
  639. X */
  640. X
  641. X/*
  642. X * Copyright 1989 Massachusetts Institute of Technology
  643. X *
  644. X * Permission to use, copy, modify, distribute, and sell this software and its
  645. X * documentation for any purpose is hereby granted without fee, provided that
  646. X * the above copyright notice appear in all copies and that both that
  647. X * copyright notice and this permission notice appear in supporting
  648. X * documentation, and that the name of M.I.T. not be used in advertising or
  649. X * publicity pertaining to distribution of the software without specific,
  650. X * written prior permission.  M.I.T. makes no representations about the
  651. X * suitability of this software for any purpose.  It is provided "as is"
  652. X * without express or implied warranty.
  653. X *
  654. X * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  655. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  656. X * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  657. X * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  658. X * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  659. X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  660. X *
  661. X * Author:  Jim McBeath, Silicon Compiler Systems
  662. X *          sci!jimmc@decwrl.dec.com
  663. X */
  664. X
  665. X#include <X11/Intrinsic.h>
  666. X#include <X11/StringDefs.h>
  667. X#include <ctype.h>
  668. X#include "ptyx.h"
  669. X
  670. X#define TOS (stackCount-1)
  671. X#define PUSHINT(n) if (!StackPushInt(n)) return FALSE
  672. X
  673. X/* inverse of CursorX and CursorY macros (except no topline used in Row) */
  674. X#define CursorRow(screen,Y) (((Y) - screen->border)/FontHeight(screen))
  675. X#define CursorCol(screen,X) (((X) - screen->scrollbar - screen->border) \
  676. X    / FontWidth(screen))
  677. X
  678. Xextern char *malloc(), *realloc();
  679. X
  680. Xenum MacStackType { MacStackNull, MacStackInt, MacStackString };
  681. X
  682. Xtypedef struct _macstackentry {
  683. X    enum MacStackType type;
  684. X    union {
  685. X        char *s;
  686. X        int n;
  687. X    } d;
  688. X} MacStackEntry;
  689. X
  690. X/* The static variables in this module have a lifetime which is limited
  691. X * to a single call to HandleMacroString.
  692. X */
  693. X
  694. Xstatic Widget stackWidget;
  695. Xstatic TScreen *stackScreen;
  696. Xstatic XEvent *stackEvent;
  697. X
  698. X/* The value stack used by all of the macro processing functions */
  699. Xstatic int stackAlloc;
  700. Xstatic int stackCount;
  701. Xstatic MacStackEntry *stack;
  702. X
  703. X/* A string buffer used by various parsing functions */
  704. Xstatic int stackQAlloc;
  705. Xstatic int stackQCount;
  706. Xstatic char *Qstr;
  707. X
  708. X/* forward references for PrimTab */
  709. Xextern int PrimToBool();
  710. Xextern int PrimNot();
  711. Xextern int PrimIfTrue();
  712. Xextern int PrimIfElse();
  713. Xextern int PrimPop();
  714. Xextern int PrimPush();
  715. Xextern int PrimExch();
  716. Xextern int PrimLimit();
  717. Xextern int PrimOrd();
  718. Xextern int PrimReturn();
  719. Xextern int PrimError();
  720. Xextern int PrimTekScale();
  721. X
  722. X/* Table of named primitive functions */
  723. Xstatic struct {
  724. X    char *name;    /* name of the primitive function */
  725. X    int (*func)();    /* returns TRUE if all OK, FALSE if problem */
  726. X} PrimTab[] = {
  727. X    {"error",    PrimError},
  728. X    {"exch",    PrimExch},
  729. X    {"if",        PrimIfTrue},
  730. X    {"ifElse",    PrimIfElse},
  731. X    {"limit",    PrimLimit},
  732. X    {"ord",        PrimOrd},
  733. X    {"pop",        PrimPop},
  734. X    {"push",    PrimPush},
  735. X    {"tekScale",    PrimTekScale},
  736. X    {"toBool",    PrimToBool},
  737. X};
  738. X
  739. X/* Table of built-in macro strings */
  740. Xstatic struct {
  741. X    char *name;    /* name of the built-in macro string */
  742. X    char *str;    /* contents of the macro string */
  743. X} BuiltinTab[] = {
  744. X    {"SeikoButton",
  745. X"'\033J'i'SeikoGetX'M'SeikoSub1'M'SeikoGetY'M'SeikoSub1'M'SeikoEnd'M"},
  746. X    {"SeikoGetX",    "x48*w/1890-"},
  747. X    {"SeikoGetY",    "1537y64*h/-"},
  748. X    {"SeikoSub1",
  749. X"'push'M'push'M10>>037&0140|%ci5>>037&0100|%ci037&040|%ci"},
  750. X    {"SeikoEnd",    "' 'i31b3&+%ci'! !\r'i"},
  751. X    {"X10Button",    "'\033[M'i31b+%ci33c+%ci33r+%ci"},
  752. X    {"VT200KeyState",    "s5&s8&2>>+"},
  753. X    {"VT200ButtonPress", "'\033['iM31'VT200KeyState'M+b+%ci33c+%ci33r+%ci"},
  754. X    {"VT200ButtonOther", "'\033['iM32'VT200KeyState'M+3+%ci33c+%ci33r+%ci"},
  755. X    {"TekButton",    "'TekGetBchar'M%ci\
  756. Xx'tekScale'M/0 4096 1- 'limit'M'TekSu1'M \
  757. X3072 34+ y'tekScale'/- 0 3072 1- 'limit'M'TekSub1'M"},
  758. X    {"TekGetBchar",    "'TekGetlbchar'M s 1 & 'TekUcase' 'if'M 0x80 |"},
  759. X    {"TekGetlbchar", "\
  760. X'r' 'ord'M b 1 == Z 'pop'M \
  761. X'm' 'ord'M b 2 == Z 'pop'M \
  762. X'l' 'ord'M b 3 == Z 'error'M"},
  763. X    {"TekUcase",    "32 -"},
  764. X    {"TekSub1",    "'push'M 7>>037&040|%ci 2>>037&040|%ci"},
  765. X    {"TestConst",
  766. X"'h='ih%di' w='iw%di' H='iH%di' W='iW%di' R='iR%di' C='iC%di'\n'i"},
  767. X    {"TestButton",
  768. X"'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\
  769. X' r='ir%di' c='ic%di' b='ib%di' s='is%xi'\n'i"},
  770. X    {"TestKey",
  771. X"'x='ix%di' y='iy%di' X='iX%di' Y='iY%di\
  772. X' r='ir%di' c='ic%di' k='ik%di' s='is%xi' l=\"'ili'\"\n'i"},
  773. X};
  774. X
  775. X
  776. Xstatic int
  777. Xishexalpha(c)
  778. Xchar c;
  779. X{
  780. X    return (c>='a'&&c<='f' || c>='A'&&c<='F');
  781. X}
  782. X
  783. X/* Value stack manipulation functions */
  784. X
  785. Xstatic void
  786. XStackClear()    /* clear the stack */
  787. X{
  788. X    int i;
  789. X
  790. X    for (i=0; i<stackCount; i++) {        /* free all strings */
  791. X        if (stack[i].type == MacStackString) {
  792. X            if (stack[i].d.s)
  793. X                free(stack[i].d.s);
  794. X        }
  795. X    }
  796. X    stackCount = 0;
  797. X}
  798. X
  799. Xstatic void
  800. XStackPop(n)
  801. Xint n;        /* pop N items off the top of the stack */
  802. X{
  803. X    while (n>0 && stackCount>0) {
  804. X        if (stack[TOS].type == MacStackString) {
  805. X            if (stack[TOS].d.s)
  806. X                free(stack[TOS].d.s);
  807. X        }
  808. X        n--;
  809. X        stackCount--;
  810. X    }
  811. X}
  812. X
  813. Xstatic Bool    /* TRUE if successful, FALSE it not (no more memory) */
  814. XStackPush(e)
  815. XMacStackEntry *e;
  816. X{
  817. X    int nbytes;
  818. X
  819. X    if (stackCount>=stackAlloc) {
  820. X        /* need more room */
  821. X        if (stackAlloc)
  822. X            stackAlloc *= 2;
  823. X        else
  824. X            stackAlloc = 15;
  825. X        nbytes = stackAlloc * sizeof(stack[0]);
  826. X        if (stack)
  827. X            stack = (MacStackEntry *)realloc((char *)stack,nbytes);
  828. X        else
  829. X            stack = (MacStackEntry *)malloc(nbytes);
  830. X        if (!stack)
  831. X            return FALSE;
  832. X    }
  833. X    stack[stackCount] = *e;    /* copy in structure */
  834. X        /* note that we do not do any string copies here */
  835. X    stackCount++;
  836. X    return TRUE;
  837. X}
  838. X
  839. Xstatic Bool    /* TRUE if successful, FALSE it not (no more memory) */
  840. XStackPushString(s)
  841. Xchar *s;    /* the string becomes the property of the stack */
  842. X{
  843. X    MacStackEntry e;
  844. X    Bool t;
  845. X
  846. X    e.type = MacStackString;
  847. X    e.d.s = s;
  848. X    t = StackPush(&e);
  849. X    if (!t) {
  850. X        free(s);    /* it's our string - don't leak the memory */
  851. X    }
  852. X    return t;
  853. X}
  854. X
  855. Xstatic Bool    /* TRUE if successful, FALSE it not (no more memory) */
  856. XStackPushStringCopy(s)
  857. Xchar *s;    /* makes a copy of the string to put onto the stack */
  858. X{
  859. X    char *newstr;
  860. X
  861. X    newstr = malloc(strlen(s)+1);
  862. X    if (!newstr)
  863. X        return FALSE;
  864. X    strcpy(newstr,s);
  865. X    return (StackPushString(newstr));
  866. X}
  867. X
  868. Xstatic Bool    /* TRUE if successful, FALSE it not (no more memory) */
  869. XStackPushInt(n)
  870. Xint n;
  871. X{
  872. X    MacStackEntry e;
  873. X    Bool t;
  874. X
  875. X    e.type = MacStackInt;
  876. X    e.d.n = n;
  877. X    t = StackPush(&e);
  878. X    return t;
  879. X}
  880. X
  881. X
  882. X/* String buffer manipulation functions */
  883. X
  884. Xstatic void
  885. XStackQclear()
  886. X{
  887. X    stackQCount = 0;
  888. X}
  889. X
  890. Xstatic Bool    /* TRUE is successful, FALSE if not (no more memory) */
  891. XStackQchar(c)
  892. Xchar c;
  893. X{
  894. X    int nbytes;
  895. X
  896. X    if (stackQCount>=stackQAlloc) {
  897. X        /* need more room */
  898. X        if (stackQAlloc)
  899. X            stackQAlloc *= 2;
  900. X        else
  901. X            stackQAlloc = 120;
  902. X        nbytes = stackQAlloc;
  903. X        if (Qstr)
  904. X            Qstr = realloc(Qstr,nbytes);
  905. X        else
  906. X            Qstr = malloc(nbytes);
  907. X        if (!Qstr)
  908. X            return FALSE;
  909. X    }
  910. X    Qstr[stackQCount++] = c;
  911. X    return TRUE;
  912. X}
  913. X
  914. X/* handles quoted strings; parses string and pushes it onto the stack */
  915. X/* Note that we do NOT do any backslash processing */
  916. Xstatic char *    /* returns pointer to the closing quote char or NULL on error */
  917. XStackQstr(p,stopchar)
  918. Xchar *p;    /* pointer to first data char */
  919. Xchar stopchar;    /* the character to stop on */
  920. X{
  921. X    StackQclear();
  922. X    while (*p && *p!=stopchar) {
  923. X        if (!StackQchar(*p))
  924. X            return NULL;    /* no more memory */
  925. X        p++;
  926. X    }
  927. X    if (!*p)
  928. X        return NULL;    /* no terminating quote */
  929. X    if (!StackQchar(0))
  930. X        return NULL;
  931. X    if (!StackPushStringCopy(Qstr))
  932. X        return NULL;
  933. X    return p;
  934. X}
  935. X
  936. X
  937. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  938. XStackToBool(n)    /* converts stack item n to a bool (int 0/1) */
  939. Xint n;
  940. X{
  941. X    int f;
  942. X
  943. X    switch (stack[n].type) {
  944. X    case MacStackInt:
  945. X        stack[n].d.n = !!stack[n].d.n;
  946. X        break;
  947. X    case MacStackString:
  948. X        if (stack[n].d.s && stack[n].d.s[0]) {
  949. X            f = 1;
  950. X        } else {
  951. X            f = 0;
  952. X        }
  953. X        if (stack[n].d.s)
  954. X            free(stack[n].d.s);
  955. X        stack[n].type = MacStackInt;
  956. X        stack[n].d.n = f;
  957. X        break;
  958. X    default:
  959. X        return FALSE;
  960. X    }
  961. X    return TRUE;
  962. X}
  963. X
  964. X/* Primitives */
  965. X
  966. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  967. XPrimToBool()    /* converts TOS to a bool (int 0/1) */
  968. X{
  969. X    if (stackCount<1)
  970. X        return FALSE;
  971. X    return (StackToBool(TOS));
  972. X}
  973. X
  974. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  975. XPrimNot()    /* converts TOS to Bool and then invert it */
  976. X{
  977. X    int f;
  978. X
  979. X    if (stackCount<1)
  980. X        return FALSE;
  981. X    switch (stack[TOS].type) {
  982. X    case MacStackInt:
  983. X        stack[TOS].d.n = !stack[TOS].d.n;
  984. X        break;
  985. X    case MacStackString:
  986. X        if (stack[TOS].d.s && stack[TOS].d.s[0]) {
  987. X            f = 0;
  988. X        } else {
  989. X            f = 1;
  990. X        }
  991. X        StackPop(1);
  992. X        PUSHINT(f);
  993. X        break;
  994. X    default:
  995. X        return FALSE;
  996. X    }
  997. X    return TRUE;
  998. X}
  999. X
  1000. X/* The IfTrue primitive requires a macro name at TOS and a value at TOS-1.
  1001. X * Both values are first removed from the stack.
  1002. X * If the value is TRUE, then the macro is executed, otherwise nothing
  1003. X * else happens.
  1004. X */
  1005. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1006. XPrimIfTrue()
  1007. X{
  1008. X    char *macroname;
  1009. X    int b,t;
  1010. X
  1011. X    if (stackCount<2)
  1012. X        return FALSE;
  1013. X    if (stack[TOS].type!=MacStackString)
  1014. X        return FALSE;
  1015. X    macroname = stack[TOS].d.s;
  1016. X    stack[TOS].d.s = 0;
  1017. X    StackPop(1);
  1018. X    if (!PrimToBool())
  1019. X        return FALSE;    /* error testing truth */
  1020. X    b = stack[TOS].d.n;
  1021. X    StackPop(1);
  1022. X    if (b)
  1023. X        t = StackDoNamedMacro(macroname);
  1024. X    else
  1025. X        t = TRUE;
  1026. X    free(macroname);
  1027. X    return t;
  1028. X}
  1029. X
  1030. X/* The IfElse primitive requires a macro name at TOS,
  1031. X * a macro name at TOS-1, and a condition value at TOS-2.
  1032. X * All three items are first removed from the stack.
  1033. X * If the condition is TRUE, then the macro is which was at TOS-1 is executed,
  1034. X * otherwise the macro which was at TOS is executed.
  1035. X * Thus, you first push the condition value, then the name of the TRUE macro,
  1036. X * then the name of the FALSE macro, then "ifElse", then M.
  1037. X */
  1038. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1039. XPrimIfElse()
  1040. X{
  1041. X    char *truemacro, *falsemacro;
  1042. X    int b,t;
  1043. X
  1044. X    if (stackCount<3)
  1045. X        return FALSE;
  1046. X    if (stack[TOS].type!=MacStackString ||
  1047. X        stack[TOS-1].type!=MacStackString)
  1048. X        return FALSE;
  1049. X    falsemacro = stack[TOS].d.s;
  1050. X    stack[TOS].d.s = 0;
  1051. X    truemacro = stack[TOS-1].d.s;
  1052. X    stack[TOS-1].d.s = 0;
  1053. X    StackPop(2);
  1054. X    if (!PrimToBool())
  1055. X        return FALSE;    /* error testing truth */
  1056. X    b = stack[TOS].d.n;
  1057. X    StackPop(1);
  1058. X    if (b)
  1059. X        t = StackDoNamedMacro(truemacro);
  1060. X    else
  1061. X        t = StackDoNamedMacro(falsemacro);
  1062. X    free(truemacro);
  1063. X    free(falsemacro);
  1064. X    return t;
  1065. X}
  1066. X
  1067. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1068. XPrimPop()    /* throws away the top item on the stack */
  1069. X{
  1070. X    if (stackCount<1)
  1071. X        return FALSE;
  1072. X    StackPop(1);
  1073. X    return TRUE;
  1074. X}
  1075. X
  1076. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1077. XPrimPush()    /* duplicates the top item on the stack by pushing a copy */
  1078. X{
  1079. X    if (stackCount<1)
  1080. X        return FALSE;
  1081. X    switch (stack[TOS].type) {
  1082. X    case MacStackInt:
  1083. X        PUSHINT(stack[TOS].d.n);
  1084. X        break;
  1085. X    case MacStackString:
  1086. X        if (!StackPushStringCopy(stack[TOS].d.s))
  1087. X            return FALSE;
  1088. X        break;
  1089. X    default:
  1090. X        return FALSE;
  1091. X    }
  1092. X    return TRUE;
  1093. X}
  1094. X
  1095. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1096. XPrimExch()    /* exchanges the top two items on the stack */
  1097. X{
  1098. X    MacStackEntry e;
  1099. X
  1100. X    if (stackCount<2)
  1101. X        return FALSE;
  1102. X    e = stack[TOS];        /* structure copy */
  1103. X    stack[TOS] = stack[TOS-1];
  1104. X    stack[TOS-1] = e;
  1105. X    return TRUE;
  1106. X}
  1107. X
  1108. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1109. XPrimLimit()    /* limits TOS-2 to be between TOS-1 and TOS */
  1110. X{
  1111. X    int high,low;
  1112. X
  1113. X    if (stackCount<3)
  1114. X        return FALSE;
  1115. X    if (stack[TOS].type != MacStackInt ||
  1116. X        stack[TOS-1].type != MacStackInt ||
  1117. X        stack[TOS-2].type != MacStackInt)
  1118. X        return FALSE;
  1119. X    high = stack[TOS].d.n;
  1120. X    low = stack[TOS-1].d.n;
  1121. X    StackPop(2);
  1122. X    if (stack[TOS].d.n>high)
  1123. X        stack[TOS].d.n = high;
  1124. X    else if (stack[TOS].d.n<low)
  1125. X        stack[TOS].d.n = low;
  1126. X    return TRUE;
  1127. X}
  1128. X
  1129. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1130. XPrimOrd()    /* converts a char (string of len 1) to an int */
  1131. X{
  1132. X    int ord;
  1133. X
  1134. X    if (stackCount<1)
  1135. X        return FALSE;
  1136. X    if (stack[TOS].type != MacStackString ||
  1137. X        strlen(stack[TOS].d.s)!=1)
  1138. X        return FALSE;
  1139. X    ord = stack[TOS].d.s[0];
  1140. X    StackPop(1);
  1141. X    PUSHINT(ord);
  1142. X    return TRUE;
  1143. X}
  1144. X
  1145. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1146. XPrimError()    /* generates an error (aborts) */
  1147. X{
  1148. X    return FALSE;    /* simple enough */
  1149. X}
  1150. X
  1151. Xstatic Bool    /* returns TRUE if all OK, FALSE if any problems */
  1152. XPrimTekScale()    /* generates an error (aborts) */
  1153. X{
  1154. X    PUSHINT(TekScale(stackScreen));
  1155. X    return TRUE;
  1156. X}
  1157. X
  1158. X
  1159. X/* Macro processing functions */
  1160. X
  1161. Xtypedef struct {
  1162. X    char *value;
  1163. X} UmInfo, *UmInfoPtr;
  1164. Xstatic XtResource umresource[] = {
  1165. X    { "", "", XtRString, sizeof(String),
  1166. X        XtOffset(UmInfoPtr,value),XtRString,NULL},
  1167. X};
  1168. X
  1169. Xstatic String        /* returns macro string or NULL if not found */
  1170. XStackFindUserMacro(name)
  1171. XString name;
  1172. X{
  1173. X    UserMacro *umlist;
  1174. X    UmInfo uminfo;
  1175. X
  1176. X    umlist = stackScreen->userMacros;
  1177. X    for (; umlist; umlist=umlist->next) {
  1178. X        if (strcmp(umlist->name,name)==0)
  1179. X            return(umlist->value);
  1180. X    }
  1181. X    /* not a macro that is already loaded, see if we can load it */
  1182. X    umresource[0].resource_name = name;
  1183. X    umresource[0].resource_class = name;
  1184. X    XtGetSubresources(stackWidget,(caddr_t)&uminfo,
  1185. X        "macroString","MacroString",
  1186. X        umresource,(Cardinal)1,(ArgList)NULL,(Cardinal)0);
  1187. X    if (!uminfo.value)
  1188. X        return NULL;    /* can't find the macro */
  1189. X    umlist = (UserMacro *)malloc(sizeof(UserMacro));
  1190. X    if (!umlist)
  1191. X        return NULL;    /* can't get memory */
  1192. X    umlist->name = malloc(strlen(name)+1);
  1193. X    if (!umlist->name) {
  1194. X        free((char *)umlist);
  1195. X        return NULL;
  1196. X    }
  1197. X    umlist->value = malloc(strlen(uminfo.value)+1);
  1198. X    if (!umlist->value) {
  1199. X        free(umlist->name);
  1200. X        free((char *)umlist);
  1201. X        return NULL;
  1202. X    }
  1203. X    strcpy(umlist->name,name);
  1204. X    strcpy(umlist->value,uminfo.value);
  1205. X    umlist->next = stackScreen->userMacros;
  1206. X    stackScreen->userMacros = umlist;
  1207. X    return(umlist->value);
  1208. X}
  1209. X
  1210. X/* handles the "%" formatting; parses format string and operates on stack */
  1211. Xstatic char *    /* returns pointer to the last char of the fmt string or NULL */
  1212. XStackFstr(p)
  1213. Xchar *p;    /* pointer to first char of formatting string */
  1214. X{
  1215. X    static char *fmtchars="-+#*.0123456789";
  1216. X    char *buf;
  1217. X
  1218. X    if (stackCount<1)
  1219. X        return NULL;
  1220. X    StackQclear();
  1221. X    if (!StackQchar('%'))
  1222. X        return NULL;
  1223. X    while (*p && (index(fmtchars,*p))) {
  1224. X        if (!StackQchar(*p))
  1225. X            return NULL;
  1226. X        p++;
  1227. X    }
  1228. X    if (!StackQchar(*p))    /* add the final formatting char */
  1229. X        return NULL;
  1230. X    if (!StackQchar(0))    /* null terminate the format string */
  1231. X        return NULL;
  1232. X    switch (*p) {
  1233. X    case 0:
  1234. X        return NULL;
  1235. X    case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': case 'c':
  1236. X        if (stack[TOS].type!=MacStackInt)
  1237. X            return NULL;
  1238. X        buf = malloc(100);
  1239. X        if (!buf)
  1240. X            return NULL;
  1241. X        sprintf(buf,Qstr,stack[TOS].d.n);
  1242. X        break;
  1243. X    case 's':
  1244. X        if (stack[TOS].type!=MacStackString)
  1245. X            return NULL;
  1246. X        buf = malloc(strlen(stack[TOS].d.s)+100);
  1247. X        if (!buf)
  1248. X            return NULL;
  1249. X        sprintf(buf,Qstr,stack[TOS].d.s);
  1250. X        break;
  1251. X    default:
  1252. X        return NULL;
  1253. X    }
  1254. X    StackPop(1);    /* get rid of converted value */
  1255. X    if (!StackPushStringCopy(buf)) {
  1256. X        free(buf);
  1257. X        return NULL;
  1258. X    }
  1259. X    free(buf);
  1260. X    return p;
  1261. X}
  1262. X
  1263. X/* handles primitives */
  1264. XBool        /* returns TRUE if OK, FALSE is any errors */
  1265. XStackDoPrimitive(name)
  1266. Xchar *name;
  1267. X{
  1268. X    int i;
  1269. X
  1270. X    for (i=0; i<XtNumber(PrimTab); i++) {
  1271. X        if (strcmp(PrimTab[i].name,name)==0) {
  1272. X            return (*PrimTab[i].func)();
  1273. X        }
  1274. X    }
  1275. X    return FALSE;
  1276. X}
  1277. X
  1278. X/* handles built-in macro strings */
  1279. XBool        /* returns TRUE if OK, FALSE is any errors */
  1280. XStackDoBuiltin(name)
  1281. Xchar *name;
  1282. X{
  1283. X    int i;
  1284. X
  1285. X    for (i=0; i<XtNumber(BuiltinTab); i++) {
  1286. X        if (strcmp(BuiltinTab[i].name,name)==0) {
  1287. X            return ProcessMacroString(BuiltinTab[i].str);
  1288. X        }
  1289. X    }
  1290. X    return FALSE;
  1291. X}
  1292. X
  1293. X/* handles user defined macro strings */
  1294. XBool        /* returns TRUE if OK, FALSE is any errors */
  1295. XStackDoUserMacro(name)
  1296. Xchar *name;
  1297. X{
  1298. X    String macrostr;
  1299. X
  1300. X    macrostr = StackFindUserMacro(name);
  1301. X    if (!macrostr)
  1302. X        return FALSE;    /* no such macro */
  1303. X    return ProcessMacroString(macrostr);
  1304. X}
  1305. X
  1306. X/* handles macro as named at TOS */
  1307. XBool        /* returns TRUE if OK, FALSE if any errors */
  1308. XStackDoMacro()
  1309. X{
  1310. X    char *macroname;
  1311. X    int t;
  1312. X
  1313. X    if (stackCount<1 || stack[TOS].type!=MacStackString)
  1314. X        return FALSE;    /* no macro name */
  1315. X    macroname = stack[TOS].d.s;
  1316. X    stack[TOS].d.s = 0;
  1317. X    StackPop(1);    /* remove the macro name from the stack */
  1318. X    t = StackDoNamedMacro(macroname);
  1319. X    free(macroname);
  1320. X    return t;
  1321. X}
  1322. X
  1323. X/* handles macros (primitives, built-in macros, or user macros) */
  1324. XBool        /* returns TRUE if OK, FALSE if any errors */
  1325. XStackDoNamedMacro(macroname)
  1326. XString macroname;
  1327. X{
  1328. X    /* User macros can override builtin macro strings, but not primitives */
  1329. X    if (StackDoPrimitive(macroname) ||
  1330. X        StackDoUserMacro(macroname) ||
  1331. X        StackDoBuiltin(macroname)) {
  1332. X        return TRUE;
  1333. X    }
  1334. X    return FALSE;    /* no such macro */
  1335. X}
  1336. X
  1337. Xstatic int    /* returns TRUE if all OK, FALSE if problem (syntax, no memory) */
  1338. XProcessMacroString(macrostring)
  1339. Xchar *macrostring;
  1340. X{
  1341. X    char *p;
  1342. X    char *newstr;
  1343. X    int newnum;
  1344. X    int l;
  1345. X    int n;
  1346. X    Bool b;
  1347. X    int radix, hc;
  1348. X    KeySym ks;
  1349. X    char buf[100];
  1350. X
  1351. X    for (p=macrostring;*p;p++) {    /* process commands */
  1352. X        switch (*p) {
  1353. X        case ' ':    /* ignore spaces */
  1354. X            break;
  1355. X        case '"':    /* quoted string */
  1356. X        case '\'':
  1357. X            p = StackQstr(p+1,*p);
  1358. X            if (!p)
  1359. X                return FALSE;        /* error */
  1360. X            break;
  1361. X        case '%':    /* formatted print onto TOS */
  1362. X            p = StackFstr(p+1);
  1363. X            if (!p)
  1364. X                return FALSE;        /* error */
  1365. X            break;
  1366. X        case '+':    /* add two numbers or cat two strings */
  1367. X            if (stackCount<2)
  1368. X                return FALSE;
  1369. X            if (stack[TOS].type == MacStackString &&
  1370. X                stack[TOS-1].type == MacStackString) {
  1371. X                l = strlen(stack[TOS].d.s) +
  1372. X                    strlen(stack[TOS-1].d.s) + 1;
  1373. X                newstr = malloc(l);
  1374. X                if (!newstr)
  1375. X                    return FALSE;
  1376. X                strcpy(newstr,stack[TOS-1].d.s);
  1377. X                strcat(newstr,stack[TOS].d.s);
  1378. X                StackPop(1);
  1379. X                free(stack[TOS].d.s);
  1380. X                stack[TOS].d.s = newstr;
  1381. X            }
  1382. X            else if (stack[TOS].type == MacStackInt ||
  1383. X                 stack[TOS-1].type == MacStackInt) {
  1384. X                newnum = stack[TOS-1].d.n + stack[TOS].d.n;
  1385. X                StackPop(1);
  1386. X                stack[TOS].d.n = newnum;
  1387. X            }
  1388. X            else
  1389. X                return FALSE;
  1390. X            break;
  1391. X        case '-':    /* subtract two numbers */
  1392. X            if (stackCount<2)
  1393. X                return FALSE;
  1394. X            if (stack[TOS].type == MacStackInt ||
  1395. X                 stack[TOS-1].type == MacStackInt) {
  1396. X                newnum = stack[TOS-1].d.n - stack[TOS].d.n;
  1397. X                StackPop(1);
  1398. X                stack[TOS].d.n = newnum;
  1399. X            }
  1400. X            else
  1401. X                return FALSE;
  1402. X            break;
  1403. X        case '*':    /* multiply two numbers */
  1404. X            if (stackCount<2)
  1405. X                return FALSE;
  1406. X            if (stack[TOS].type == MacStackInt ||
  1407. X                 stack[TOS-1].type == MacStackInt) {
  1408. X                newnum = stack[TOS-1].d.n * stack[TOS].d.n;
  1409. X                StackPop(1);
  1410. X                stack[TOS].d.n = newnum;
  1411. X            }
  1412. X            else
  1413. X                return FALSE;
  1414. X            break;
  1415. X        case '/':    /* divide two numbers */
  1416. X            if (stackCount<2)
  1417. X                return FALSE;
  1418. X            if (stack[TOS].type == MacStackInt ||
  1419. X                 stack[TOS-1].type == MacStackInt) {
  1420. X                newnum = stack[TOS-1].d.n / stack[TOS].d.n;
  1421. X                StackPop(1);
  1422. X                stack[TOS].d.n = newnum;
  1423. X            }
  1424. X            else
  1425. X                return FALSE;
  1426. X            break;
  1427. X        case '<':    /* left shift (<<) */
  1428. X            if ((*(++p))!='<')
  1429. X                return FALSE;
  1430. X            if (stackCount<2)
  1431. X                return FALSE;
  1432. X            if (stack[TOS].type == MacStackInt &&
  1433. X                 stack[TOS-1].type == MacStackInt) {
  1434. X                newnum = stack[TOS-1].d.n << stack[TOS].d.n;
  1435. X                StackPop(1);
  1436. X                stack[TOS].d.n = newnum;
  1437. X            }
  1438. X            else
  1439. X                return FALSE;
  1440. X            break;
  1441. X        case '>':    /* right shift (>>) */
  1442. X            if ((*(++p))!='>')
  1443. X                return FALSE;
  1444. X            if (stackCount<2)
  1445. X                return FALSE;
  1446. X            if (stack[TOS].type == MacStackInt &&
  1447. X                 stack[TOS-1].type == MacStackInt) {
  1448. X                newnum = stack[TOS-1].d.n >> stack[TOS].d.n;
  1449. X                StackPop(1);
  1450. X                stack[TOS].d.n = newnum;
  1451. X            }
  1452. X            else
  1453. X                return FALSE;
  1454. X            break;
  1455. X        case '|':    /* logical or bitwise OR */
  1456. X            if (stackCount<2)
  1457. X                return FALSE;
  1458. X            if (p[1]=='|') {    /* logical */
  1459. X                p++;
  1460. X                if (!(StackToBool(TOS) && StackToBool(TOS-1)))
  1461. X                    return FALSE;
  1462. X                newnum = stack[TOS-1].d.n || stack[TOS].d.n;
  1463. X            } else {        /* bitwise */
  1464. X                if (stack[TOS].type != MacStackInt ||
  1465. X                    stack[TOS-1].type != MacStackInt)
  1466. X                    return FALSE;
  1467. X                newnum = stack[TOS-1].d.n | stack[TOS].d.n;
  1468. X            }
  1469. X            StackPop(1);
  1470. X            stack[TOS].d.n = newnum;
  1471. X            break;
  1472. X        case '&':    /* logical or bitwise AND */
  1473. X            if (stackCount<2)
  1474. X                return FALSE;
  1475. X            if (p[1]=='&') {    /* logical */
  1476. X                p++;
  1477. X                if (!(StackToBool(TOS) && StackToBool(TOS-1)))
  1478. X                    return FALSE;
  1479. X                newnum = stack[TOS-1].d.n && stack[TOS].d.n;
  1480. X            } else {        /* bitwise */
  1481. X                if (stack[TOS].type != MacStackInt ||
  1482. X                    stack[TOS-1].type != MacStackInt)
  1483. X                    return FALSE;
  1484. X                newnum = stack[TOS-1].d.n & stack[TOS].d.n;
  1485. X            }
  1486. X            StackPop(1);
  1487. X            stack[TOS].d.n = newnum;
  1488. X            break;
  1489. X        case '^':    /* logical or bitwise XOR */
  1490. X            if (stackCount<2)
  1491. X                return FALSE;
  1492. X            if (p[1]=='^') {    /* logical */
  1493. X                p++;
  1494. X                if (!(StackToBool(TOS) && StackToBool(TOS-1)))
  1495. X                    return FALSE;
  1496. X                newnum = stack[TOS-1].d.n ^ stack[TOS].d.n;
  1497. X            } else {        /* bitwise */
  1498. X                if (stack[TOS].type != MacStackInt ||
  1499. X                    stack[TOS-1].type != MacStackInt)
  1500. X                    return FALSE;
  1501. X                newnum = stack[TOS-1].d.n ^ stack[TOS].d.n;
  1502. X            }
  1503. X            StackPop(1);
  1504. X            stack[TOS].d.n = newnum;
  1505. X            break;
  1506. X        case '!':    /* logical not */
  1507. X            if (!PrimNot())
  1508. X                return FALSE;
  1509. X            break;
  1510. X        case '~':    /* bitwise invert */
  1511. X            if (stackCount<1)
  1512. X                return FALSE;
  1513. X            if (stack[TOS].type == MacStackInt) {
  1514. X                newnum = ~stack[TOS-1].d.n;
  1515. X                stack[TOS].d.n = newnum;
  1516. X            }
  1517. X            else
  1518. X                return FALSE;
  1519. X            break;
  1520. X        case '0': case '1': case '2': case '3': case '4':
  1521. X        case '5': case '6': case '7': case '8': case '9':
  1522. X            newnum = 0;
  1523. X            if ((*p)=='0') {
  1524. X                if (p[1]=='x' || p[1]=='X') {
  1525. X                    radix = 16;
  1526. X                    p+=2;
  1527. X                }
  1528. X                else
  1529. X                    radix = 8;
  1530. X            }
  1531. X            else
  1532. X                radix = 10;
  1533. X            while (isdigit(*p) || (radix==16&&ishexalpha(*p))) {
  1534. X                newnum *= radix;
  1535. X                if (radix==16&&ishexalpha(*p)) {
  1536. X                    hc = *p;
  1537. X                    if (islower(hc))
  1538. X                        hc = toupper(hc);
  1539. X                    newnum += hc - 'A' + 10;
  1540. X                }
  1541. X                else
  1542. X                    newnum += *p - '0';
  1543. X                p++;
  1544. X            }
  1545. X            --p;    /* have to leave it pointing to last char */
  1546. X            PUSHINT(newnum);
  1547. X            break;
  1548. X        case 'b':    /* put button field from event onto stack */
  1549. X            PUSHINT(stackEvent->xbutton.button);
  1550. X            break;
  1551. X        case 'c':    /* put cursor col onto stack (0 is leftmost) */
  1552. X            PUSHINT(CursorCol(stackScreen,stackEvent->xbutton.x));
  1553. X            break;
  1554. X        case 'C':    /* put number of cols on screen onto stack */
  1555. X            PUSHINT(stackScreen->max_col+1);
  1556. X            break;
  1557. X        case 'h':    /* put pixel height of a char on stack */
  1558. X            PUSHINT(FontHeight(stackScreen));
  1559. X            break;
  1560. X        case 'H':    /* put pixel height of screen on stack */
  1561. X            PUSHINT(stackScreen->fullVwin.height);
  1562. X            break;
  1563. X        case 'i':    /* send TOS as input */
  1564. X            if (stackCount<1)
  1565. X                return FALSE;
  1566. X            if (stack[TOS].type == MacStackString)
  1567. X                StringInput(stackScreen,stack[TOS].d.s);
  1568. X            else
  1569. X                return FALSE;
  1570. X            StackPop(1);
  1571. X            break;
  1572. X        case 'k':    /* put keycode field from event onto stack */
  1573. X            PUSHINT(stackEvent->xkey.keycode);
  1574. X            break;
  1575. X        case 'l':    /* put results of XLookupString on stack */
  1576. X            n = XLookupString(stackEvent,buf,sizeof(buf)-1,&ks,0);
  1577. X            if (n>0) {
  1578. X                newstr = malloc(n+1);
  1579. X                if (!newstr)
  1580. X                    return FALSE;
  1581. X                strcpy(newstr,buf);
  1582. X                if (!StackPushString(newstr))
  1583. X                    return FALSE;
  1584. X            } else {    /* no translation, use null string */
  1585. X                if (!StackPushStringCopy(""))
  1586. X                    return FALSE;
  1587. X            }
  1588. X            break;
  1589. X        case 'M':    /* execute macro */
  1590. X            if (!StackDoMacro())
  1591. X                return FALSE;
  1592. X            break;
  1593. X        case 'r':    /* put cursor row onto stack (0 is topmost) */
  1594. X            PUSHINT(CursorRow(stackScreen,stackEvent->xbutton.y));
  1595. X            break;
  1596. X        case 'R':    /* put number of rows on screen onto stack */
  1597. X            PUSHINT(stackScreen->max_row+1);
  1598. X            break;
  1599. X        case 's':    /* put state field from event onto stack */
  1600. X            PUSHINT(stackEvent->xbutton.state);
  1601. X            break;
  1602. X        case 'w':    /* put pixel width of a char on stack */
  1603. X            PUSHINT(FontWidth(stackScreen));
  1604. X            break;
  1605. X        case 'W':    /* put pixel width of screen on stack */
  1606. X            PUSHINT(stackScreen->fullVwin.width);
  1607. X            break;
  1608. X        case 'x':    /* put x pixel value of cursor on stack */
  1609. X            PUSHINT(stackEvent->xbutton.x - stackScreen->border - 
  1610. X                        stackScreen->scrollbar);
  1611. X            break;
  1612. X        case 'y':    /* put y pixel value of cursor on stack */
  1613. X            PUSHINT(stackEvent->xbutton.y - stackScreen->border);
  1614. X            break;
  1615. X        case 'X':    /* put x_root pixel value of cursor on stack */
  1616. X            PUSHINT(stackEvent->xbutton.x_root);
  1617. X            break;
  1618. X        case 'Y':    /* put y_root pixel value of cursor on stack */
  1619. X            PUSHINT(stackEvent->xbutton.y_root);
  1620. X            break;
  1621. X        case 'Z':    /* conditional return/end of macro */
  1622. X            if (stackCount<1)
  1623. X                return FALSE;    /* error */
  1624. X            if (!PrimToBool())
  1625. X                return FALSE;    /* error testing truth */
  1626. X            b = stack[TOS].d.n;
  1627. X            StackPop(1);
  1628. X            if (b)
  1629. X                return TRUE;    /* if true, end of this macro */
  1630. X            /* else do nothing */
  1631. X            break;
  1632. X        default:
  1633. X            return FALSE;
  1634. X        }
  1635. X    }
  1636. X    return TRUE;    /* finished without errors */
  1637. X}
  1638. X
  1639. X/* This is the action function called from the translation table */
  1640. Xvoid
  1641. XHandleMacroString(w,event,params,param_count)
  1642. XWidget w;
  1643. XXEvent *event;
  1644. XString *params;
  1645. Xint *param_count;
  1646. X{
  1647. X
  1648. X    if (*param_count != 1)
  1649. X        return;
  1650. X    StackClear();        /* clear the stack machine */
  1651. X    stackScreen = &((XtermWidget)w)->screen;
  1652. X    stackWidget = w;
  1653. X    stackEvent = event;
  1654. X    if (!ProcessMacroString(params[0])) {
  1655. X        Bell();        /* some sort of error */
  1656. X    }
  1657. X}
  1658. X
  1659. X/* end */
  1660. END_OF_macrostr.c
  1661. if test 24964 -ne `wc -c <macrostr.c`; then
  1662.     echo shar: \"macrostr.c\" unpacked with wrong size!
  1663. fi
  1664. # end of overwriting check
  1665. fi
  1666. echo shar: End of shell archive.
  1667. exit 0
  1668.