home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rs960115.zip / rexxsrc.INF (.txt)
OS/2 Help File  |  1996-01-15  |  174KB  |  5,735 lines

  1.  
  2. ΓòÉΓòÉΓòÉ 1. About the REXX Sourcebook ΓòÉΓòÉΓòÉ
  3.  
  4. The REXX Sourcebook is a collection of REXX information gotten from various 
  5. places on the Internet and turned into an OS/2 .inf document. Except as noted, 
  6. I have not contributed any of the factual information contained herein. So, if 
  7. you have questions about the contents, you should address the authors of the 
  8. various documents. If there is a problem with this file, please let me know. 
  9. Also, if you have some REXX documentation or REXX programs that you think 
  10. should be included, please contact me. 
  11.  
  12. Dirk Terrell 
  13. terrell@astro.ufl.edu 
  14.  
  15.  
  16. ΓòÉΓòÉΓòÉ 2. The REXX FAQ ΓòÉΓòÉΓòÉ
  17.  
  18.  
  19. Frequently Asked Questions About REXX
  20.  
  21. Last Revised:  August 12, 1994
  22.  
  23. Eric Giguere
  24. giguere@watcom.on.ca
  25.  
  26.  
  27. ΓòÉΓòÉΓòÉ 2.1. Copyright Information ΓòÉΓòÉΓòÉ
  28.  
  29. This document is Copyright 1993, 1994 by Eric Giguere. Permission is granted to 
  30. reproduce and distribute all or part of this document for non-commercial 
  31. purposes only.  All other uses must first be cleared with the author.  The 
  32. author may be contacted on the Internet at the address giguere@watcom.on.ca or 
  33. on paper by writing to Watcom International, 415 Phillip Street, Waterloo, 
  34. Ontario, Canada, N2L 3X2.  Please note, however, that this document is not 
  35. published or endorsed by Watcom. 
  36.  
  37.  
  38. ΓòÉΓòÉΓòÉ 2.2. Introduction ΓòÉΓòÉΓòÉ
  39.  
  40. This document is intended to serve as a useful reference for REXX-related 
  41. information.  It aims for breadth as opposed to depth, and references to other 
  42. material are given where appropriate.  Suggestions and updates should be sent 
  43. to the author in an attempt to keep this document relevant and up- to-date. 
  44.  
  45. Readers will notice the prevalence of OS/2-related materials in this document. 
  46. Most of the REXX-related activity at this time is occurring on the OS/2 
  47. platform.  This document is not intended to be OS/2-specific.  The author is 
  48. quite happy to include information on other platforms if you pass it on to him. 
  49.  
  50. More information on REXX can also be had from the REXX Language Association. 
  51. See below for details. 
  52.  
  53.  
  54. ΓòÉΓòÉΓòÉ 2.3. What Is REXX? ΓòÉΓòÉΓòÉ
  55.  
  56. REXX is a programming language designed by Michael Cowlishaw of IBM UK 
  57. Laboratories. In his own words: "REXX is a procedural language that allows 
  58. programs and algorithms to be written in a clear and structured way." REXX 
  59. doesn't look that different from any other procedural language. Here's a simple 
  60. REXX program: 
  61.  
  62.  
  63. /* Count some numbers */
  64.  
  65. say "Counting..."
  66. do i = 1 to 10
  67. say "Number" i
  68. end
  69.  
  70. What makes REXX different from most other languages is that it is also designed 
  71. to be used as a macro language by arbitrary application programs. The idea is 
  72. that application developers don't have to design their own macro languages and 
  73. interpreters. Instead they use REXX as the macro language and support the REXX 
  74. programming interface. If a REXX macro comes across an expression or function 
  75. call that it cannot resolve, it can ask the application to handle it instead. 
  76. The application only has to support the features that are specific to it, 
  77. freeing the developer from handling the mundane (and time-consuming) task of 
  78. writing a language interpreter. And if all applications use REXX as their macro 
  79. language, the user only has to learn one language instead of a dozen. 
  80.  
  81.  
  82. ΓòÉΓòÉΓòÉ 2.4. REXX and the Internet ΓòÉΓòÉΓòÉ
  83.  
  84. Networks connect computers in various ways for the exchange of data. The 
  85. terminology is a bit confusing to the new user. Here are the definitions this 
  86. document uses: 
  87.  
  88.  Usenet    Not really a network, just the set of machines that exchange network 
  89.            news. Network news is really an extended form of electronic mail 
  90.            that groups messages from individuals into newsgroups that users can 
  91.            read using special newsreaders. 
  92.  
  93.  Internet  The worldwide network based on TCP/IP protocols. Besides being able 
  94.            to receive mail and newsgroups, these machines can use programs like 
  95.            ftp and telnet to communicate with other machines in real time. Most 
  96.            Internet machines are Unix-based. 
  97.  
  98.  BITNET    The worldwide network that connects many IBM mainframes. BITNET 
  99.            users can also transfer files using methods that are incompatible 
  100.            with those of the Internet. 
  101.  
  102.  
  103. ΓòÉΓòÉΓòÉ 2.4.1. Newsgroups ΓòÉΓòÉΓòÉ
  104.  
  105. The Usenet group comp.lang.rexx exists for discussion of REXX in all its 
  106. variations. Anything posted to this newsgroup also gets sent to the REXXLIST 
  107. mailing list (see below) and vice-versa. 
  108.  
  109. Other newsgroups of interest are machine-specific. Recommended groups are 
  110. comp.os.os2.programmer and comp.sys.amiga.programmer. 
  111.  
  112.  
  113. ΓòÉΓòÉΓòÉ 2.4.2. FTP Sites of Interest ΓòÉΓòÉΓòÉ
  114.  
  115.  FTP is a file transmission protocol used on the Internet to transfer files 
  116. between machines. The transfers are done in real time and usually require that 
  117. the user have an account on both machines. However, many machines on the 
  118. Internet support what is known as anonymous FTP, which allows users on other 
  119. machines access to a limited set of files without requiring an account. Some of 
  120. the more interesting sites that offer this service are: 
  121.  
  122.  rexx.uwaterloo.ca General repository for REXX-related information, including 
  123.            free REXX interpreters for Unix and DOS. An XEDIT clone for Unix and 
  124.            OS/2 may also be found here. Look under /pub/rexx. 
  125.  
  126.  flipper.pvv.unit.no The official home of Regina, one of the free Unix 
  127.            interpreters. An archive of the messages in comp.lang.rexx is also 
  128.            maintained here. Check under /pub/rexx. 
  129.  
  130.  ftp-os2.cdrom.com, ftp.luth.se General OS/2 archives. 
  131.  
  132.  wuarchive.wustl.edu General Amiga archive. Look under /pub/aminet. 
  133.  
  134.  
  135. ΓòÉΓòÉΓòÉ 2.4.3. Mailing Lists ΓòÉΓòÉΓòÉ
  136.  
  137.  Mailing lists are similar to newsgroups but use normal electronic mail to 
  138. deliver the messages. The following mailing lists are mostly BITNET-based but 
  139. are accessible from the Internet as well: 
  140.  
  141.  
  142.        List name     BITNET      Internet           Discusses
  143.                       Node        Address
  144.        REXXLIST      UCF1VM    ucf1vm.cc.ucf.edu    REXX in general
  145.         AREXX-L      UCF1VM    ucf1vm.cc.ucf.edu    Amiga REXX
  146.         PC-REXX      UCF1VM    ucf1vm.cc.ucf.edu    Personal REXX
  147.        REXXCOMP      UCF1VM    ucf1vm.cc.ucf.edu    IBM's REXX compiler
  148.        TSO-REXX      UCF1VM    ucf1vm.cc.ucf.edu    TSO REXX
  149.         VM-REXX      UCF1VM    ucf1vm.cc.ucf.edu    VM/SP REXX
  150.         UREXX-L      (none)    liverpool.ac.ak      Unix REXX
  151.  
  152. To subscribe to any of these lists, send a one-line message to the address 
  153. LISTSERV@node, where node is the BITNET node or Internet address for the list 
  154. you wish to join. In the body of your message should be the line 
  155.  
  156.  
  157. SUBSCRIBE list-name your--full-name
  158.  
  159.  as in 
  160.  
  161.  
  162. SUBSCRIBE UREXX-L Eric Giguere
  163.  
  164.  You will then be subscribed to the list and messages will start arriving in 
  165. your mailbox. To send a message to the list, simply mail it to listname@node, 
  166. as in UREXX- L@liverpool.ac.uk. Note the distinction between the LISTSERV 
  167. address and the listname address. You can receive help by sending a HELP 
  168. message to the LISTSERV address. Note that some of these mailing lists may be 
  169. available on Usenet in the form of newsgroups with names starting with 
  170. "bit.listserv". Ask your system administrator if you're not sure. 
  171.  
  172. Thanks to Scott Ophof for providing this summary. 
  173.  
  174.  
  175. ΓòÉΓòÉΓòÉ 2.4.4. Gopher Service ΓòÉΓòÉΓòÉ
  176.  
  177.  Gopher clients may find REXX-related information at the site 
  178. gopher.pvv.unit.no (Europe) and index.almaden.ibm.com (N. America). 
  179.  
  180.  
  181. ΓòÉΓòÉΓòÉ 2.5. Free REXX Products ΓòÉΓòÉΓòÉ
  182.  
  183. This sections contains information on some free REXX products. 
  184.  
  185.  
  186. ΓòÉΓòÉΓòÉ 2.5.1. Interpreters ΓòÉΓòÉΓòÉ
  187.  
  188.  There are at least three REXX interpreters available for free on the Internet. 
  189. The first two are Unix based and are well-supported by their authors. The third 
  190. is an MS-DOS interpreter. 
  191.  
  192. Regina is Anders Christensen's REXX interpreter for various flavours of Unix 
  193. and VMS. It is fairly complete and Anders even has an API for developers. It 
  194. also apparently can be ported to OS/2. Anders can be reached at 
  195. anders@pvv.unit.no. Regina's official home is ftp.pvv.unit.no. 
  196.  
  197. REXX/imc is Ian Collier's REXX interpreter for SunOS, though it has also been 
  198. ported to other Unix systems. Ian can be reached at imc@prg.ox.ac.uk. 
  199.  
  200. BREXX is Bill Vlachoudis' REXX interpreter for MS-DOS. The interpreter is not 
  201. complete but is quite small. Bill can be reached at 
  202. bill@donoussa.physics.auth.gr. 
  203.  
  204. All three interpreters are available for anonymous FTP on rexx.uwaterloo.ca in 
  205. the /pub/freerexx directory, each interpreter in its own subdirectory. Regina 
  206. and REXX/imc are in source form, BREXX is only available as binary. 
  207.  
  208.  
  209. ΓòÉΓòÉΓòÉ 2.5.2. REXX-Aware Text Editors ΓòÉΓòÉΓòÉ
  210.  
  211.  Also on rexx.uwaterloo.ca in the /pub/editors directory is the text editor THE 
  212. by Mark Hessling (mark@snark.itc.gu.edu.au). THE is a full-featured XEDIT/KEDIT 
  213. clone (by XEDIT here we mean the IBM mainframe text editor, not the X Windows 
  214. editor xedit) with REXX support. THE is available in versions for OS/2 and 
  215. Unix. THE's official home is on ftp.gu.edu.au in /src/THE. 
  216.  
  217.  
  218. ΓòÉΓòÉΓòÉ 2.6. Commercial REXX Products ΓòÉΓòÉΓòÉ
  219.  
  220. This Section contains information on some commercial REXX products. 
  221.  
  222.  
  223. ΓòÉΓòÉΓòÉ 2.6.1. Interpreters ΓòÉΓòÉΓòÉ
  224.  
  225.  REXX interpreters are available commercially for a wide variety of systems and 
  226. come standard on some operating platforms such as the Amiga, OS/2 and the IBM 
  227. mainframes. The following vendors sell REXX interpreters: 
  228.  
  229.  
  230. The Workstation Group [Various UNIX platforms, also VMS]
  231. 6300 River Road
  232. Rosemont, IL 60018
  233. (800) 228-0255 (US only)
  234. sales@wrkgrp.com
  235.  
  236. Quercus Systems          [DOS, Windows, Windows NT, OS/2]
  237. P.O. Box 2157
  238. Saratoga, CA  95070
  239. (408) 867-7399
  240. (800) 440-5944 (US & Canada)
  241. 75300.2450@compuserve.com
  242.  
  243. Simware                  [Novell Netware]
  244. 2 Gurdwara Road
  245. Ottawa, Ontario
  246. Canada  K2E 1A2
  247. (613) 727-1779
  248.  
  249. IBM also sells REXX interpreters for AIX and Netware.
  250.  
  251.  
  252. ΓòÉΓòÉΓòÉ 2.6.2. Compilers ΓòÉΓòÉΓòÉ
  253.  
  254.  Although REXX is usually thought of as an interpreted language, it can also be 
  255. compiled. The following vendors all sell REXX compilers: 
  256.  
  257.  
  258. Dineen Edwards Group [Amiga]
  259. 19785 West 12 Mile Road, Suite 305
  260. Southfield, MI 48076-2553
  261. (313) 352-4288
  262.  
  263. IBM [MVS/TSO and VM/CMS]
  264. Contact your local representative
  265.  
  266. Systems Center [VM/CMS]
  267. 1800 Alexander Bell Drive
  268. Reston, VA 22091
  269.  
  270.  
  271. ΓòÉΓòÉΓòÉ 2.6.3. Visual Development Environments ΓòÉΓòÉΓòÉ
  272.  
  273.  There are three REXX-based visual development environments available for OS/2: 
  274.  
  275.  
  276. VX-REXX WATCOM International
  277. 415 Phillip Street
  278. Waterloo, Ontario
  279. Canada N2L 3X2
  280. Phone: (519) 886-3700
  281. Fax: (519) 747-4971
  282.  
  283. VisPro/REXX HockWare
  284. 315 N. Academy St., Suite 100
  285. Cary, NC 27513
  286. Phone: (919) 380-0616
  287. Fax: (919) 380-0757
  288.  
  289. GpfRexx Gpf Systems
  290. 10 Falls Road
  291. Moodus, Conn.  06469
  292. Phone: (203) 873-3300
  293. Fax: (203) 873-3302
  294.  
  295.  
  296. ΓòÉΓòÉΓòÉ 2.6.4. REXX-Aware Text Editors ΓòÉΓòÉΓòÉ
  297.  
  298.  Clones of the popular XEDIT editor are available for Unix from the Workstation 
  299. Group (see address above) and for DOS and OS/2 from Mansfield Software.  Tritus 
  300. sells an ISPF/PDF text editor with REXX support for OS/2.  One Up sells 
  301. SourceLink, an integrated development environment for OS/2 with REXX macro 
  302. capabilities.  Command Technology sells the SPF/PC editor. 
  303.  
  304.  
  305. Mansfield Software
  306. P.O. Box 532
  307. Storrs, CT 06268
  308. Phone: (203) 429-8402
  309. Fax: (203) 487-1185
  310.  
  311. Tritus
  312. 3300 Bee Caves Road, Suite 650
  313. Austin, Texas  78746
  314. Phone: (512) 794-5800
  315. Fax: (512) 7940-3833
  316.  
  317. One Up
  318. 1603 LBJ Freeway, Suite 200
  319. Dallas, Texas  75243
  320. Phone: (800) 678-0187
  321.  
  322. Command Technology
  323. 1040 Marina Village Parkway
  324. Alameda, CA  94501
  325. Phone: (800) 336-3320
  326.  
  327. The OS/2 Enhanced Editor (EPM.EXE), which is bundled with OS/2, also has REXX 
  328. support. Use its online help and search for the 'rx' command. 
  329.  
  330.  
  331. ΓòÉΓòÉΓòÉ 2.6.5. REXX Extensions ΓòÉΓòÉΓòÉ
  332.  
  333. A number of vendors sell extensions to REXX: 
  334.  
  335.      Quercus Systems sells REXXLIB (a collection of over 150 REXX extension 
  336.       functions), REXXCOMM (a function package for accessing serial ports from 
  337.       REXX) and REXXTERM (a full-featured asynchronous communications program). 
  338.  
  339.      SofTouch Systems sells the GammaTech REXX SuperSet/2, a collection of 
  340.       over 300 REXX extension functions for OS/2. 
  341.  
  342.      dSoft Development sells the dbfREXX function library that lets you read 
  343.       and write dBASE files from OS/2 REXX. 
  344.  
  345.   Quercus Systems
  346.   P.O. Box 2157
  347.   Saratoga, CA  95070
  348.   (408) 867-7399
  349.   (800) 440-5944 (US & Canada)
  350.   75300.2450@compuserve.com
  351.  
  352.   SofTouch Systems
  353.   1300 S. Meridian, Suite 600
  354.   Oklahoma City, Okla.  73108-1751
  355.   Phone: (405) 947-8080
  356.   Fax: (405) 632-6537
  357.  
  358.   dSoft Development
  359.   4710 Innsbruk Drive
  360.   Houston, Texas  77066
  361.   Phone: (405) 360-3045
  362.   Fax: (713) 537-0318
  363.  
  364.  
  365. ΓòÉΓòÉΓòÉ 2.7. REXX and ANSI ΓòÉΓòÉΓòÉ
  366.  
  367. The American National Standards Institute (ANSI) sets national standards for 
  368. various things in the United States, including programming languages. The X3J18 
  369. REXX Standards Committee is currently defining a formal standard for the REXX 
  370. language, using Mike Cowlishaw's book as its base document. The Committee meets 
  371. 3 or 4 times a year and holds ongoing discussions throughout the year by 
  372. electronic mail. Mgopher.pvv.unit.noembers of X3J18 are mostly REXX 
  373. implementors, but anyone can participate. The Committee intends to release a 
  374. draft standard next year. More information can be had from the vice-chair, Neil 
  375. Milsted at nfnm@wrkgrp.com. Note that public ANSI documents relating to X3J18 
  376. can be had using the LISTSERV service at PSUVM on BITNET or by Gopher to 
  377. gopher.pvv.unit.no on the Internet. 
  378.  
  379.  
  380. ΓòÉΓòÉΓòÉ 2.8. The REXX Language Association ΓòÉΓòÉΓòÉ
  381.  
  382. The REXX Language Association is an independent organization dedicated to 
  383. promoting the use of the REXX programming language.  Activities of the RexxLA 
  384. include: 
  385.  
  386.      Maintaining an electronic mail server where members share information. 
  387.  
  388.      Distributing a quarterly newsletter. 
  389.  
  390.      Providing electronic resources for access to language expertise, hints 
  391.       and tips, example programs, product sources, and other valuable 
  392.       information. 
  393.  
  394.      Developing resource guides, both printed and electronic, for 
  395.       publications, products, training and language experts. 
  396.  
  397.      Developing educational, guest speaker, and publicity programs to promote 
  398.       the use of REXX. 
  399.  
  400.      Participating in the work of standards bodies. 
  401.  
  402.      Promoting integration of REXX into all operating systems and as the 
  403.       common scripting language for a wide array of software. 
  404.  
  405.      Cooperating with the REXX Symposium in providing an annual conference 
  406.       forum. 
  407.  
  408.  Join today and start reaping the benefits available from an international 
  409.  consortium of individuals, corporations, vendors, authors and experts. 
  410.  
  411.  For more information, contact the REXX Language Association by mail or fax: 
  412.  
  413.       RexxLA Membership
  414.       6300 North River Road, Suite 501
  415.       Rosemont, Illinois  60018
  416.       Fax: (708) 696-2277
  417.  
  418.  Or by electronic mail at rexxla@wrkgrp.com. 
  419.  
  420.  
  421. ΓòÉΓòÉΓòÉ 2.9. The REXX Symposium ΓòÉΓòÉΓòÉ
  422.  
  423. The REXX Symposium is an annual conference devoted to REXX, attended both by 
  424. users and vendors, held at the beginning of May. It is sponsored by the 
  425. Stanford Linear Accelerator, with the cooperation of the RexxLA. 
  426.  
  427.  
  428. ΓòÉΓòÉΓòÉ 2.10. REXX Bibliography ΓòÉΓòÉΓòÉ
  429.  
  430. Mike Cowlishaw and Linda Green have kindly provided the following partial 
  431. bibliography of REXX books. 
  432.  
  433.  
  434. The REXX Language -- M.F. Cowlishaw
  435.      English:       ISBN 0-13-780735-X  Prentice-Hall, 1985
  436.                ISBN 0-13-780651-5  2nd edition, 1990
  437.      German:   ISBN 3-446-15195-8  Carl Hanser Verlag, 1988
  438.                ISBN 0-13-780784-8  P-H International, 1988
  439.      Japanese: ISBN 4-7649-0136-6  Kindai-kagaku-sha, 1988
  440.  
  441. The REXX Reference Summary Handbook -- Dick Goran
  442.     ISBN 0-9639854-1-8, CFS Nevada Inc., 1994
  443.  
  444. Modern Programming Using REXX -- Robert P. O'Hara and
  445.      David R. Gomberg
  446.      English:  ISBN 0-13-597311-2  Prentice-Hall, 1985
  447.                ISBN 0-13-579329-5  2nd edition, 1988
  448.  
  449. REXX in the TSO Environment -- Gabriel F. Gargiulo
  450.      ISBN 0-89435-354-3, QED Information Systems Inc.
  451.      320 pages, 1990
  452.  
  453. Using OS/2 REXX -- Gabriel F. Gargiulo
  454.     ISBN 0-894-35449-3, QED Publishing Group
  455.  
  456. Practical Usage of REXX -- Anthony S. Rudd
  457.      ISBN 0-13-682790-X, Ellis Horwood (Simon & Schuster), 1990
  458.  
  459. Using ARexx on the Amiga -- Chris Zamara and Nick Sullivan
  460.      ISBN 1-55755-114-6, Abacus Books, 1991
  461.  
  462. The REXX Handbook -- Edited by Gabe Goldberg and Phil Smith III
  463.      ISBN 0-07-023682-8, McGraw-Hill, 1991
  464.  
  465. Programming in REXX -- Charles Daney
  466.      ISBN 0-07-015305-1, McGraw-Hill, 1992
  467.  
  468. Command Language Cookbook -- Hallett German
  469.      ISBN 0-442-00801-5, Van Nostrand Reinhold, 1992
  470.  
  471. OS/2 2.1 REXX Handbook -- Hallett German
  472.      ISBN 0-442-01734-0, Van Nostrand Reinhold, 1994
  473.  
  474. OS/2 REXX: From Bark to Byte -- Inter. Technical Supp. Org. (IBM)
  475.      IBM Document Number GG24-4199-00, 1993
  476.  
  477. REXX: Advanced Techniques for Programmers -- Peter Kiesel
  478.      ISBN 0-07-034600-3, McGraw Hill, 1992
  479.  
  480. REXX Tools and Techniques -- Barry Nirmal
  481.      ISBN 0-89435-417-5, QED Publishing Group, 1993
  482.  
  483. The ARexx Cookbook -- Merrill Callaway
  484.      ISBN 0-96-327730-8, Whitestone, 1992
  485.  
  486. Writing OS/2 REXX Programs -- Ronny Richardson
  487.      ISBN 0-07-052372, McGraw Hill, 1992
  488.  
  489. Writing VX-REXX Programs -- Ronny Richardson
  490.      ISBN 0-07-9111911-5, McGraw Hill, 1994
  491.  
  492.  
  493. ΓòÉΓòÉΓòÉ 2.11. Common REXX Coding Errors ΓòÉΓòÉΓòÉ
  494.  
  495. The following list of common REXX coding errors is derived from a list included 
  496. in the online documentation for Watcom VX-REXX. 
  497.  
  498.  
  499. ΓòÉΓòÉΓòÉ 2.11.1. Blank space where it does not belong ΓòÉΓòÉΓòÉ
  500.  
  501. In REXX expressions, blank space is interpreted as an implicit concatenation 
  502. operator -- the terms are concatenated with a blank in between.  As a result, 
  503. REXX will interpret many mistyped statements as an expression involving the 
  504. blank concatenation operator. 
  505.  
  506. For example, inserting a blank after a function name in a function call changes 
  507. the meaning of the expression from: 
  508.  
  509.     text_upper = translate( text )
  510. to: 
  511.  
  512.     text_upper = "TRANSLATE" || " " || text
  513.  
  514. Blank space also plays a special role in the PARSE instruction.  Compare the 
  515. following: 
  516.  
  517.     parse arg a b c
  518.     parse arg a, b, c
  519.  
  520. The first line parses the first argument passed to the routine into three 
  521. parts, while the second line sets the three variables to the value of the first 
  522. three arguments passed to the routine. 
  523.  
  524.  
  525. ΓòÉΓòÉΓòÉ 2.11.2. Function calls versus the CALL statement ΓòÉΓòÉΓòÉ
  526.  
  527. When you call a routine that returns a result, you must enclose the parameters 
  528. in parentheses: 
  529.  
  530.     text = VRGet( "EF_1", "Value" )
  531.  
  532. Always assign the value of a function to a variable, or use the CALL statement 
  533. as described below. 
  534.  
  535. Otherwise REXX will pass the return value to the default host environment, 
  536. leading to strange and possibly damaging behaviour on some systems. 
  537.  
  538. If you are calling a routine that does not return a value, or you wish to 
  539. ignore the return value, you should use the CALL instruction: 
  540.  
  541.     call VRSet "EF_1", "BackColor", "Blue"
  542.  
  543. Note that there is no comma between the name of the routine and the first 
  544. parameter.  Note also that parentheses are not used when using the CALL 
  545. instruction. 
  546.  
  547.  
  548. ΓòÉΓòÉΓòÉ 2.11.3. Line continuation ΓòÉΓòÉΓòÉ
  549.  
  550. The comma is used in REXX to split clauses across two or more lines. For 
  551. example: 
  552.  
  553.     call foo a, b, c
  554.  
  555. can also be written as: 
  556.  
  557.     call foo a, ,
  558.              b, ,
  559.              c
  560.  
  561. It's easy to forget the second comma when breaking a line in the middle of a 
  562. function parameter list. 
  563.  
  564.  
  565. ΓòÉΓòÉΓòÉ 2.11.4. Omitted arguments ΓòÉΓòÉΓòÉ
  566.  
  567. REXX allows arguments to be omitted.  Be careful not to omit arguments by 
  568. accident, such as including an unnecessary comma: 
  569.  
  570.     call foo , a, b, c
  571.  
  572.  
  573. ΓòÉΓòÉΓòÉ 2.11.5. Undefined variables ΓòÉΓòÉΓòÉ
  574.  
  575. It is not a syntax error to use undefined variables in REXX. Undefined 
  576. variables are defined to have their own name translated to uppercase as their 
  577. value.  As a result it is often difficult to find programming errors that are a 
  578. result of using undefined variables. 
  579.  
  580. Some tips: 
  581.  
  582.      Add a SIGNAL ON NOVALUE statement to the main section of your programs. 
  583.       This will cause the system to issue a syntax error if you use an 
  584.       undefined variable. 
  585.  
  586.      Be careful to include the period when referring to stems. The variables 
  587.       "A" and "A." are unrelated. 
  588.  
  589.      Misspelled commands will often be interpreted as undefined variables. The 
  590.       line: 
  591.  
  592.                 sy 'hello'
  593.  
  594.       (which should be "say 'hello'") will be interpreted as: 
  595.  
  596.                 "SY" || " " || 'hello'
  597.  
  598.       and will be send to the default command host for execution. 
  599.  
  600.  
  601. ΓòÉΓòÉΓòÉ 2.11.6. Using expressions in the tail of a compound symbol ΓòÉΓòÉΓòÉ
  602.  
  603. The tail of a compound symbol can only be a simple variable, as in: 
  604.  
  605.     ok = A.I
  606.  
  607. Literals are not allowed.  For example, the following is interpreted as a 
  608. concatenation between "A." and "name": 
  609.  
  610.     bad = A."name"
  611.  
  612. Expressions are also not allowed.  You must first assign the value of the 
  613. expression to a symbol and then use that symbol: 
  614.  
  615.     J = I - 1
  616.     ok = A.J
  617.  
  618.  
  619. ΓòÉΓòÉΓòÉ 2.12. Frequently Asked Questions ΓòÉΓòÉΓòÉ
  620.  
  621. Frequently asked questions about REXX. 
  622.  
  623.  
  624. ΓòÉΓòÉΓòÉ 2.12.1. Is REXX better than <some other language>? ΓòÉΓòÉΓòÉ
  625.  
  626.  Short answer: Yes. No. Maybe. Does it matter? 
  627.  
  628. Long answer: This question wastes a lot of bandwidth in comp.lang.rexx and 
  629. other newsgroups. Every language has its good points and its bad points. Some 
  630. people love REXX, some people hate it. Use a language that suits your needs. 
  631.  
  632. (Editorial digression: Programming languages are like sexual positions -- some 
  633. are more exciting than others, some are more difficult, some are unusual, few 
  634. have tried them all, and everyone has a favorite.) 
  635.  
  636.  
  637. ΓòÉΓòÉΓòÉ 2.12.2. Why does my OS/2 REXX program run more quickly the second time? ΓòÉΓòÉΓòÉ
  638.  
  639.  When you run a REXX CMD file for the first time, a tokenized version will be 
  640. stored on disk using the OS/2 extended file attributes. (You can see how big 
  641. the tokenized version is by using the /N option on the DIR command.) If a 
  642. tokenized version exists AND the file has not been modified, CMD.EXE will use 
  643. the tokenized version instead of parsing the source. 
  644.  
  645. Note that there is a 64K limit on the size of an extended attribute entry, so 
  646. very large REXX programs do not benefit from this automatic tokenization. 
  647.  
  648.  
  649. ΓòÉΓòÉΓòÉ 2.12.3. How can I return multiple values from a function? ΓòÉΓòÉΓòÉ
  650.  
  651. REXX does not provide any support for returning more than a single value from a 
  652. function.  If you wish to return multiple values, you must devise an alternate 
  653. scheme.  A simple solution is to concatenate the values together into a single 
  654. string and on return from the function use the PARSE instruction or the various 
  655. string functions to split the string back into its elements.  Don't forget that 
  656. you can use non-printable characters (such as '00'x) to separate the data -- 
  657. REXX will correctly handle such strings. There may also be other alternatives 
  658. available to you if you are using an external function library that lets you 
  659. store data in separate memory pools or in disk files. 
  660.  
  661.  
  662. ΓòÉΓòÉΓòÉ 2.12.4. Why does linein, lineout, charin or charout fail? ΓòÉΓòÉΓòÉ
  663.  
  664. Most versions of REXX (ARexx is an exception) use implicit file opening.  That 
  665. is, each time you reference a file in a LINEIN, LINEOUT, CHARIN or CHAROUT 
  666. function, REXX will open the file for reading or writing if the file is not 
  667. already open.  However, some operating systems like DOS and OS/2 impose limits 
  668. on the number of files that can be open simultaneously, usually around 20 or 
  669. so.  After the limit has been reached, any further attempts to open another 
  670. file will fail.  That is why it is always good practice to close a file when 
  671. you're done with it.  In OS/2 this is done using the STREAM function, as 
  672. follows: 
  673.  
  674.     call stream "c:\foo.out", "command", "close"
  675.  
  676. The STREAM function can also be used to open files, query their sizes and seek 
  677. into the file.  Consult your REXX documentation for specific instructions for 
  678. your interpreter. 
  679.  
  680.  
  681. ΓòÉΓòÉΓòÉ 2.12.5. How do I iterate over all the tails in a stem variable? ΓòÉΓòÉΓòÉ
  682.  
  683. One of the features REXX lacks is a function to return a list of defined tails. 
  684. There are external libraries that provide functions to do so, but if that is 
  685. not an option then the only solution is to maintain your own list of tails in a 
  686. string and use the PARSE instruction or the WORDS function to traverse the 
  687. list. 
  688.  
  689.  
  690. ΓòÉΓòÉΓòÉ 2.12.6. How do I REXX-enable my application? ΓòÉΓòÉΓòÉ
  691.  
  692. REXX-enabling an application means being able to run REXX macros within an 
  693. application.  This information is very system-specific, so the best place to 
  694. start is with the documentation provided with the REXX interpreter. 
  695.  
  696. For OS/2, there are several sources of information.  The most basic information 
  697. is found in the OS/2 Toolkit, which includes the REXXSAA.H header file and the 
  698. REXX Reference online document.  The REXX Report (see above) includes a couple 
  699. of articles on the subject. Sample source code comes with the OS/2 Toolkit and 
  700. is also available on rexx.uwaterloo.ca in the directory /pub/os2/vxrexx as 
  701. VX-REXX Tech Notes #1 and #7 (vxtech01.zip, vxtech07.zip -- neither tech note 
  702. requires that you own VX-REXX). OS/2 technical conferences such as ColoradOS/2 
  703. or the IBM Technical Interchanges often includes sessions on this topic. For 
  704. ARexx, a book was available from Commodore, but with the latter's demise it is 
  705. unclear whether the book is still available. 
  706.  
  707.  
  708. ΓòÉΓòÉΓòÉ 2.12.7. How do I do inter-process communication in REXX? ΓòÉΓòÉΓòÉ
  709.  
  710. Again, this is system-specific.  The ARexx interpreter is built on a messaging 
  711. model, making it very simple to do inter-process communication, but the OS/2 
  712. REXX interpreter has no such features, though in some cases queues can be used 
  713. to achieve the desired effect. 
  714.  
  715.  
  716. ΓòÉΓòÉΓòÉ 2.12.8. How do I use global variables in my REXX programs? ΓòÉΓòÉΓòÉ
  717.  
  718. The scope of variables is controlled by the PROCEDURE instruction. If a routine 
  719. is declared with the PROCEDURE instruction, only those variables exposed using 
  720. the EXPOSE instruction are available to the routine.  If no PROCEDURE 
  721. instruction is used, all of the caller's variables are available to the callee. 
  722. Here is a simple example: 
  723.  
  724. a = 10
  725. b = 20
  726. call first
  727. call second
  728. call third
  729. exit
  730.  
  731. first:
  732.     say "first -- a is" a "b is" b
  733.     return
  734.  
  735. second: procedure
  736.     say "second -- a is" a "b is" b
  737.     return
  738.  
  739. third: procedure expose a
  740.     say "third -- a is" a "b is" b
  741.     b = 30
  742.     call first
  743.     return
  744.  
  745. Running this program yields the following output: 
  746.  
  747. first -- a is 10 b is 20
  748. second -- a is A b is B
  749. third -- a is 10 b is B
  750. first -- a is 10 b is 30
  751.  
  752. Use the PROCEDURE instruction to keep variables local to a procedure, using 
  753. EXPOSE to explicitly expose any "global" variables.  The only catch is that you 
  754. have to make sure you expose the variables inside every procedure. One way to 
  755. define and use global variables is to use a stem called "Globals." and define 
  756. all your procedures like this: 
  757.  
  758. Foo: procedure expose Globals.
  759.  
  760. Then at the top of you program initialize the Globals stem and assign 
  761. appropriate values to your global variables: 
  762.  
  763. Globals. = ''
  764. Globals.!NeedToSave = 0
  765. Globals.!TmpDir = "D:\TMP"
  766.  
  767. The tail names in this example are all prefixed with '!', though you could also 
  768. use an underscore ('_'). This is just a convention used to avoid this kind of 
  769. problem: 
  770.  
  771. Globals.TmpDir = "D:\TMP"
  772. call Foo
  773. say Globals.TmpDir
  774. exit
  775.  
  776. Foo: procedure expose Globals.
  777.     tmpdir = "foo"
  778.     Globals.TmpDir = tmpdir
  779.     return
  780.  
  781. It's a subtle bug that has to do with how REXX interprets stem tails. 
  782.  
  783.  
  784. ΓòÉΓòÉΓòÉ 3. The REXX Tutorial for Complete Beginners ΓòÉΓòÉΓòÉ
  785.  
  786. This document is being ported from a UNIX version for IMC Unix. It was written 
  787. by Ian Collier. If you find any mistakes or unixisms in it, please contact Paul 
  788. Prescod: papresco@undergrad.math.uwaterloo.ca. 
  789.  
  790. The OS/2 .inf version of this tutorial was done by Dirk Terrell: 
  791. terrell@astro.ufl.edu 
  792.  
  793.  
  794. ΓòÉΓòÉΓòÉ 3.1. Creating a Rexx program ΓòÉΓòÉΓòÉ
  795.  
  796. Many programmers start by writing a program which displays the message "Hello 
  797. world!". Here is how to do that in Rexx... 
  798.  
  799. Write a file called "hello.cmd" containing the following text. Use any text 
  800. editor, e, edit, or epm will do. To do this in the WorkPlace shell, just go to 
  801. the templates folder and drag a data file object out of it. Bring up its 
  802. settings and rename it to "hello.cmd." The text, as with all example text in 
  803. this guide, starts at the first indented line and ends at the last. The four 
  804. spaces at the start of each line of text should not be entered (this is very 
  805. important!): 
  806.  
  807.  
  808. /* This program says "Hello world!" */
  809. say "Hello world!"
  810.  
  811. This program consists of a comment saying what the program does, and an 
  812. instruction which does it. "say" is the Rexx instruction which displays data on 
  813. the terminal. 
  814.  
  815. The method of executing a Rexx program varies greatly between implementations. 
  816. On OS/2, you would just type "hello.cmd" in that file's directory, or double 
  817. click on its icon in the WorkPlace Shell. 
  818.  
  819. When you execute your first Rexx program using the method detailed above, you 
  820. should see the message "Hello world!" appear on the screen. 
  821.  
  822.  
  823. ΓòÉΓòÉΓòÉ 3.2. Doing arithmetic ΓòÉΓòÉΓòÉ
  824.  
  825. Rexx has a wide range of arithmetic operators, which can deal with very high 
  826. precision numbers. Here is an example of a program which does arithmetic. Make 
  827. a file called "arith.cmd" containing the following: 
  828.  
  829.  
  830. /* This program inputs a number and does some calculations on it */
  831. pull a
  832. b=a*a
  833. c=1/a
  834. d=3+a
  835. e=2**(a-1)
  836. say 'Results are:' a b c d e
  837.  
  838. in a positive integer. Here is a sample run: 
  839.  
  840. input: 5 output: Results are: 5 25 0.2 8 16 
  841.  
  842. The results you see are the original number (5), its square (25), its 
  843. reciprocal (0.2), the number plus three (8) and two to the power of one less 
  844. than the number (16). 
  845.  
  846. This example illustrates several things: 
  847.  
  848.      variables: in this example a, b, c, d and e are variables. You can assign 
  849.       a value to a variable by typing its name, "=", and a value, and you can 
  850.       use its value in an expression simply by typing its name. 
  851.  
  852.      input: by typing "pull a" you tell the interpreter to ask the user for 
  853.       input and to store it in the variable a. 
  854.  
  855.      arithmetic: the usual symbols (+ - * /) as well as ** (to-power) were 
  856.       used to perform calculations. Parentheses (or "brackets") were used to 
  857.       group together an expression, as they are in mathematics. 
  858.  
  859.      string expressions: the last line of the program displays the results by 
  860.       saying the string expression 'Results are:' a b c d e This has six 
  861.       components: the string constant 'Results are:' and the five variables. 
  862.       These components are attached together with spaces into one string 
  863.       expression, which the "say" command then displays on the terminal. A 
  864.       string constant is any sequence of characters which starts and ends with 
  865.       a quotation mark - that is, either " or ' (it makes no difference which 
  866.       you use, as long as they are both the same). 
  867.  
  868.  If you supply the number 6 as input to the program, you should notice that the 
  869.  number 1/6 is given to nine significant figures. You can easily change this. 
  870.  Edit the program and insert before the second line: 
  871.  
  872.  
  873.   numeric digits 25
  874.  
  875.  If you run this new program you should see that 25 significant figures are 
  876.  produced. In this way you can calculate numbers to whatever accuracy you 
  877.  require, within the limits of the machine. 
  878.  
  879.  At this point it seems worth a mention that you can put more than one 
  880.  instruction on a line in a Rexx program. You simply place a semicolon between 
  881.  the instructions, like this: 
  882.  
  883.  
  884.   /* This program inputs a number and does some calculations on it */
  885.   pull a; b=a*a; c=1/a; d=3+a; e=2**(a-1); say 'Results are:' a b c d e
  886.  
  887.  Needless to say, that example went a bit over the top... 
  888.  
  889.  
  890. ΓòÉΓòÉΓòÉ 3.3. Errors ΓòÉΓòÉΓòÉ
  891.  
  892. Suppose you ignored the instructions of the previous section and typed a 
  893. non-integer such as 3.4 as input to the program. Then you would get an error, 
  894. because the ** (to-power) operator is only designed to work when the second 
  895. parameter (that is, the power number) is an integer. You might see this, for 
  896. example: 
  897.  
  898.  
  899. 3.4
  900. 6 +++ e=2**(a-1)
  901. Error 26 running arith.cmd, line 6: Invalid whole number
  902.  
  903. Or if you typed zero, you might see the following (because you cannot divide by 
  904. zero): 
  905.  
  906.  
  907. rexx arith
  908. 0
  909. 4 +++ c=1/a
  910. Error 42 running arith.cmd, line 4: Arithmetic overflow or underflow
  911.  
  912. Perhaps most interestingly, if you type a sequence of characters which is not a 
  913. number, you might see this. It does not complain about the characters you 
  914. entered, but at the fact that the program tries to use it as a number. 
  915.  
  916.  
  917. rexx arith
  918. hello
  919. 3 +++ b=a*a
  920. Error 41 running arith.cmd, line 3: Bad arithmetic conversion
  921.  
  922. In each case, you have generated a "syntax error" (it is classified as a syntax 
  923. error, even though the problem was not directly related to the program's 
  924. syntax). What you see is a "traceback" starting with the line which caused the 
  925. error (no other lines are listed in this traceback, because we have not yet 
  926. considered any Rexx control structures), and a description of the error. This 
  927. information should help you to determine where the error occurred and what 
  928. caused it. More difficult errors can be traced with the "trace" instruction 
  929. (see later). 
  930.  
  931.  
  932. ΓòÉΓòÉΓòÉ 3.4. Untyped data ΓòÉΓòÉΓòÉ
  933.  
  934. In the previous section, you found that you could input either a number or a 
  935. sequence of letters and store it in the variable a, although arithmetic can 
  936. only be performed on numbers. That is because data in Rexx are untyped. In 
  937. other words, the contents of a variable or the result of an expression can be 
  938. any sequence of characters. What those characters are used for matters only to 
  939. you, the programmer. However, if you try to perform arithmetic on a random 
  940. sequence of characters you will generate a syntax error, as shown in the 
  941. previous section. 
  942.  
  943. You have seen that you can add strings together by placing a space in between 
  944. them. There are two other ways: the abuttal and the concatenation operator. An 
  945. abuttal is simply typing the two pieces of data next to each other without a 
  946. space. This is not always appropriate: for example you cannot type an "a" next 
  947. to a "b", because that would give "ab", which is the name of another unrelated 
  948. variable. Instead, it is safer to use the concatenation operator, ||. Both 
  949. these operations concatenate the strings without a space in between. For 
  950. example: 
  951.  
  952.  
  953. /* demonstrates concatenation and the use of untyped data */
  954. a='A string'
  955. b='123'
  956. c='456'
  957. d=a":" (b||c)*3
  958. say d
  959.  
  960. The above program says "A string: 370368". This is because (b||c) is the 
  961. concatenation of strings b and c, which is "123456". That sequence of 
  962. characters happens to represent a number, and so it can be multiplied by 3 to 
  963. give 370368. Finally, that is added with a space to the concatenation of a with 
  964. ":" and stored in d. 
  965.  
  966.  
  967. ΓòÉΓòÉΓòÉ 3.5. More on variables ΓòÉΓòÉΓòÉ
  968.  
  969. The previous examples only used single-letter variable names. In fact it is 
  970. more useful to have whole words as variable names, and Rexx allows this up to 
  971. an implementation maximum (which should be suitably large, e.g. 250 
  972. characters). Moreover, not only letters but numbers and the six characters 
  973. "@#$!?_" are allowed in variable names - or "symbols", as they are called in 
  974. the literature. These are valid symbols: 
  975.  
  976.      fred 
  977.  
  978.      Dan_Yr_0gof 
  979.  
  980.      HI! 
  981.  The case of letters is unimportant, so that for example "Hello", "HELLO" and 
  982.  "hellO" all mean the same. 
  983.  
  984.  If you use a symbol in an expression when it has not been previously given a 
  985.  value, that does not cause an error (unless "signal on novalue" is set - see 
  986.  later). Instead, it just results in its own name translated into upper case. 
  987.  
  988.  
  989.   /* A demonstration of simple symbols */
  990.   foo=3
  991.   bar="Characters"
  992.   say foo bar':' hi!
  993.  
  994.  This program says "3 Characters: HI!". 
  995.  
  996.  As well as "simple symbols", which are variables like the above, there are 
  997.  arrays. Any ordinary variable name can also be used as the name of an array: 
  998.  
  999.  
  1000.   /* This program uses an array. */
  1001.   pull a
  1002.   array.1=a
  1003.   array.2=a*a
  1004.   array.3=a**3
  1005.   say array.1 array.2 array.3 array.1+array.2+array.3
  1006.  
  1007.  An element of an array is accessed by typing the array name, a dot, and the 
  1008.  element number. The array name and the dot are together known as the "stem" of 
  1009.  the array. The name of the element is called a "compound symbol". Note that an 
  1010.  array does not have to be declared before it is used. 
  1011.  
  1012.  In fact not only numbers, but strings and variable names may be used as 
  1013.  element names. Also, an element name can consist of two or more parts 
  1014.  separated by dots, so giving two or more dimensional arrays. 
  1015.  
  1016.  
  1017.   /* This program uses an array with various elements */
  1018.   book.1.author="M. F. Cowlishaw"
  1019.   book.1.title="The REXX Language, a practical approach to programming"
  1020.   book.1.pub="Englewood Cliffs 1985"
  1021.   book.2.author="A. S. Rudd"
  1022.   book.2.title="Practical Usage of REXX"
  1023.   book.2.pub="Ellis Horwood 1990"
  1024.   /* insert lots more */
  1025.   say "Input a book number"
  1026.   pull i
  1027.   say "Author: " book.i.author
  1028.   say "Title: " book.i.title
  1029.   say "Publisher:" book.i.pub
  1030.  
  1031.  In the above program, an array called "book" is created, containing a number 
  1032.  of records each with elements AUTHOR, TITLE and PUB. Notice that these three 
  1033.  uppercase names are produced by symbols "author", "title" and "pub", because 
  1034.  those symbols have not been given values. When a book number i has been input, 
  1035.  the elements of the ith record are printed out. It is not an error to 
  1036.  reference an undefined element of an array. If you type "3" into the above 
  1037.  program, you will see this: 
  1038.  
  1039.  
  1040.   Input a book number
  1041.   3
  1042.   Author: BOOK.3.AUTHOR
  1043.   Title: BOOK.3.TITLE
  1044.   Publisher: BOOK.3.PUB
  1045.  
  1046.  As before, if a compound symbol has not been given a value, then its name is 
  1047.  used instead. 
  1048.  
  1049.  There is a way to initialise every element of an array: by assigning a value 
  1050.  to the stem itself. Edit the above program and insert after the comment line: 
  1051.  
  1052.  
  1053.   book.="Undefined"
  1054.  
  1055.  This gives every possible element of the array the value "Undefined", so that 
  1056.  if you again type "3" you will see the following: 
  1057.  
  1058.  
  1059.   Input a book number
  1060.   3
  1061.   Author: Undefined
  1062.   Title: Undefined
  1063.   Publisher: Undefined
  1064.  
  1065.  
  1066. ΓòÉΓòÉΓòÉ 3.6. Functions ΓòÉΓòÉΓòÉ
  1067.  
  1068. The Online Rexx Summary contains a list of the functions which are available in 
  1069. Rexx. Each of these functions performs a specific operation upon the 
  1070. parameters. For example, 
  1071.  
  1072.  
  1073. /* Invoke the date function with various parameters */
  1074. say date("W")',' date()
  1075.  
  1076. This might say, for example, "Friday, 22 May 1992". A function is called by 
  1077. typing its name immediately followed by "(". After that come the parameters, if 
  1078. any, and finally a closing ")". In the above example, the "date" function is 
  1079. called twice. The value of date("W") is the name of the weekday, and the value 
  1080. of date() is the date in "default" format. 
  1081.  
  1082.  
  1083. ΓòÉΓòÉΓòÉ 3.7. Conditionals ΓòÉΓòÉΓòÉ
  1084.  
  1085. It is time to use some Rexx control structures. The first of these will be the 
  1086. conditional. Here is an example: 
  1087.  
  1088.  
  1089. /* Use a conditional to tell whether a number is less than 50 */
  1090. pull a
  1091. if a<50 then say a "is less than 50"
  1092. else say a "is not less than 50"
  1093.  
  1094. The program is executed in the manner in which it reads - so, if a is less than 
  1095. 50 then the first instruction is executed, else the second instruction is 
  1096. executed. 
  1097.  
  1098. The "a<50" is a conditional expression. It is like an ordinary expression (in 
  1099. fact conditional expressions and ordinary numeric expressions are 
  1100. interchangeable), but it contains a comparison operator. 
  1101.  
  1102. There are many comparison operators, as follows: 
  1103.  
  1104.      = (equal to) 
  1105.  
  1106.      < (less than) 
  1107.  
  1108.      > (greater than) 
  1109.  
  1110.      <= (less or equal) 
  1111.  
  1112.      >= (greater or equal) 
  1113.  
  1114.      <> (greater or less) 
  1115.  
  1116.      \= (not equal) 
  1117.  
  1118.      \> (not greater) 
  1119.  
  1120.      \< (not less) 
  1121.  
  1122.  All the above operators can compare numbers, deciding whether one is equal to, 
  1123.  less than, or greater than the other. They can also compare non-numeric 
  1124.  strings, first stripping off leading and trailing blanks. 
  1125.  
  1126.  There are analogous comparison operators to these for comparing strings 
  1127.  strictly. The main difference between them is that 0 is equal to 0.0, 
  1128.  numerically speaking, but the two are different if compared as strings. The 
  1129.  other difference is that the strict operators do not strip blanks before 
  1130.  comparing. The strict operators are 
  1131.  
  1132.      == (equal to) 
  1133.  
  1134.      << (less than) 
  1135.  
  1136.      >> (greater than) 
  1137.  
  1138.      <<= (less or equal) 
  1139.  
  1140.      >>= (greater or equal) 
  1141.  
  1142.      \== (not equal) 
  1143.  
  1144.      \>> (not greater) 
  1145.  
  1146.      \<< (not less) 
  1147.  
  1148.  Conditional expressions may be combined with the boolean operators: 
  1149.  
  1150.      & (and) 
  1151.  
  1152.      | (or) 
  1153.  
  1154.      && (xor) 
  1155.  They may also be reversed with the \ (not) operator. 
  1156.  
  1157.  
  1158.   /* Decide what range a number is in */
  1159.   pull a
  1160.   if a>0 & a<10 then say "1-9"
  1161.   if a\<10 & a<20 then say "10-19"
  1162.   if \ (a<20 | a>=30) then say "20-29"
  1163.   if a<=0 | a>=30 then say "Out of range"
  1164.  
  1165.  As well as demonstrating the boolean and comparison operators, this program 
  1166.  shows that the "else" clause is not required to be present. 
  1167.  
  1168.  The above program may also be written using Rexx's other conditional 
  1169.  instruction, "select": 
  1170.  
  1171.  
  1172.   /* Decide what range a number is in */
  1173.   pull a
  1174.   select
  1175.   when a>0 & a<10 then say "1-9"
  1176.        when a\<10 & a<20 then say "10-19"
  1177.        when \ (a<20 | a>=30) then say "20-29"
  1178.        otherwise say "Out of range"
  1179.   end
  1180.  
  1181.  The "select" instruction provides a means of selecting precisely one from a 
  1182.  list of conditional instructions, with the option of providing a list of 
  1183.  instructions to do when none of the above were true. The difference is that if 
  1184.  no part of a "select" instruction can be executed then a syntax error results, 
  1185.  whereas it is OK to miss out the "else" part of an "if" instruction. 
  1186.  
  1187.  Only one instruction may be placed after "then", "else" and "when", but Rexx 
  1188.  provides a way of bracketing instructions together so that they can be treated 
  1189.  as a single instruction. To do this, place the instruction "do" before the 
  1190.  list of instructions and "end" after it. 
  1191.  
  1192.  
  1193.   /* execute some instructions conditionally */
  1194.   pull a
  1195.   if a=50 then
  1196.   do
  1197.   say "Congratulations!"
  1198.        say "You have typed the correct number."
  1199.        end
  1200.   else say "Wrong!"
  1201.  
  1202.  If you wish for one of the conditional instructions to do "nothing", then you 
  1203.  must use the instruction "nop" (for "no operation"). Simply placing no 
  1204.  instructions after the "then", "else" or "when" will not work. 
  1205.  
  1206.  
  1207. ΓòÉΓòÉΓòÉ 3.8. Loops ΓòÉΓòÉΓòÉ
  1208.  
  1209. Rexx has a comprehensive set of instructions for making loops, using the words 
  1210. "do" and "end" which you met briefly in the previous section. 
  1211.  
  1212.  
  1213. ΓòÉΓòÉΓòÉ 3.8.1. Counted loops ΓòÉΓòÉΓòÉ
  1214.  
  1215. The instructions within a counted loop are executed the specified number of 
  1216. times: 
  1217.  
  1218.  
  1219. /* Say "Hello" ten times */
  1220.     do 10
  1221.      say "Hello"
  1222. end
  1223.  
  1224. A variation of the counted loop is one which executes forever: 
  1225.  
  1226.  
  1227. /* This program goes on forever until the user halts it */
  1228.     do forever
  1229.      nop
  1230.     end
  1231.  
  1232.  
  1233. ΓòÉΓòÉΓòÉ 3.8.2. Control loops ΓòÉΓòÉΓòÉ
  1234.  
  1235. Control loops are like counted loops, but they use a variable (called the 
  1236. control variable) as a counter. The control variable may count simply in steps 
  1237. of 1: 
  1238.  
  1239.  
  1240. /* Count to 20 */
  1241.     do c=1 to 20
  1242.      say c
  1243.     end
  1244.  
  1245. or in steps of some other value: 
  1246.  
  1247.  
  1248. /* Print all multiples of 2.3 not more than 20 */
  1249.     do m=0 to 20 by 2.3
  1250.      say m
  1251.     end
  1252.  
  1253. It may take a specific number of steps: 
  1254.  
  1255.  
  1256. /* Print the first six multiples of 5.7 */
  1257.     do m=0 for 6 by 5.7
  1258.      say m
  1259.     end
  1260.  
  1261. or it may go on forever: 
  1262.  
  1263.  
  1264. /* Print all the natural numbers */
  1265.     do n=0
  1266.      say n
  1267.     end n
  1268.  
  1269. The "n" at the end of this last example is optional. At the end of any 
  1270. controlled loop, the name of the control variable may be placed after the 
  1271. "end", where it will be checked to see if it matches the control variable. 
  1272.  
  1273.  
  1274. ΓòÉΓòÉΓòÉ 3.8.3. Conditional loops ΓòÉΓòÉΓòÉ
  1275.  
  1276. A set of instructions may be executed repeatedly until some condition is true. 
  1277. For example, 
  1278.  
  1279.  
  1280. /* I won't take no for an answer */
  1281.     do until answer \= "NO"
  1282.      pull answer
  1283. end
  1284.  
  1285. Alternatively, they may be executed as long as some condition is true: 
  1286.  
  1287.  
  1288. /* It's OK to repeat this as long as there is no error */
  1289.     do while error=0
  1290.      pull a
  1291.      if a="ERROR" then error=1
  1292.      else say a
  1293.     end
  1294.  
  1295. Note that in this example, if there is already an error to start with then the 
  1296. set of instructions will not be executed at all. However in the previous 
  1297. example the instructions will always be executed at least once. 
  1298.  
  1299.  
  1300. ΓòÉΓòÉΓòÉ 3.8.4. Controlled conditional loops ΓòÉΓòÉΓòÉ
  1301.  
  1302. It is possible to combine forms a or b with form c mentioned above, like this: 
  1303.  
  1304.  
  1305. /* I won't take no for an answer unless it is typed three times */
  1306.     do 3 until answer \= "NO"
  1307.      pull answer
  1308.     end
  1309.  
  1310. or this: 
  1311.  
  1312.  
  1313. /* input ten answers, but stop when empty string is entered */
  1314.     do n=1 to 10 until ans==""
  1315.      pull ans
  1316.      a.n=ans
  1317.     end
  1318.  
  1319. The "iterate" and "leave" instructions allow you to continue with, or to leave, 
  1320. a loop respectively. For example: 
  1321.  
  1322.  
  1323. /* input ten answers, but stop when empty string is entered */
  1324. do n=1 to 10
  1325. pull a.n
  1326.      if a.n=="" then leave
  1327. end
  1328.  
  1329.  
  1330. /* print all integers from 1-10 except 3 */
  1331. do n=1 to 10
  1332. if n=3 then iterate
  1333.      say n
  1334. end
  1335.  
  1336. If a symbol is placed after the instructions "iterate" or "leave", then you can 
  1337. iterate or leave the loop whose control variable is that symbol. 
  1338.  
  1339.  
  1340. /* Print pairs (i,j) where 1 <= i,j <= 5, except (2,j) if j>=3 */
  1341. do i=1 to 5
  1342. do j=1 to 5
  1343.      if i=2 & j=3 then iterate i /* or "leave j" would work,
  1344.      or just "leave" */
  1345. say "("i","j")"
  1346.      end
  1347. end
  1348.  
  1349.  
  1350. ΓòÉΓòÉΓòÉ 3.9. Parsing ΓòÉΓòÉΓòÉ
  1351.  
  1352. The following program examines its arguments: 
  1353.  
  1354.  
  1355. /* Parse the arguments */
  1356. parse arg a.1 a.2 a.3 a.4 .
  1357. do i=1 to 4
  1358. say "Argument" i "was:" a.i
  1359. end
  1360.  
  1361. Execute it as usual, except this time type "alpha beta gamma delta" after the 
  1362. program name on the command line, for example: 
  1363.  
  1364.  
  1365. arguments alpha beta gamma delta
  1366.  
  1367. The program should print out: 
  1368.  
  1369.  
  1370. Argument 1 was: alpha
  1371. Argument 2 was: beta
  1372. Argument 3 was: gamma
  1373. Argument 4 was: delta
  1374.  
  1375. The argument "alpha beta gamma delta" has been parsed into four components. The 
  1376. components were split up at the spaces in the input. If you experiment with the 
  1377. program you should see that if you do not type four words as arguments then the 
  1378. last components printed out are empty, and that if you type more than four 
  1379. words then the last component contains all the extra data. Also, even if 
  1380. multiple spaces appear between the words, only the last component contains 
  1381. spaces. This is known as "tokenisation". 
  1382.  
  1383. It is not only possible to parse the arguments, but also the input. In the 
  1384. above program, replace "arg" by "pull". When you run this new program you will 
  1385. have to type in some input to be tokenised. 
  1386.  
  1387. Replace "parse" with "parse upper" in the program. Now, when you supply input 
  1388. to be tokenised it will be uppercased. 
  1389.  
  1390. "arg" and "pull" are, respectively, abbreviations for the instructions "parse 
  1391. upper arg" and "parse upper pull". That explains why the "pull" instruction 
  1392. appeared in previous examples, and why it was that input was always uppercased 
  1393. if you typed letters in response to it. 
  1394.  
  1395. Other pieces of data may be parsed as well. "parse source" parses information 
  1396. about how the program was invoked, and what it is called. "parse version" 
  1397. parses information about the interpreter itself. However, the two most useful 
  1398. uses of the parse instruction are "parse var [variable]" and "parse value 
  1399. [expression] with". These allow you to parse arbitrary data supplied by the 
  1400. program. 
  1401.  
  1402. For example, 
  1403.  
  1404.  
  1405. /* Get information about the date and time */
  1406. d=date()
  1407. parse var d day month year
  1408. parse value time() with hour ':' min ':' sec
  1409.  
  1410. The last line above illustrates a different way to parse data. Instead of 
  1411. tokenising the result of evaluating time(), we split it up at the character 
  1412. ':'. Thus, for example, "17:44:11" is split into 17, 44 and 11. 
  1413.  
  1414. Any search string may be specified in the "template" of a "parse" command. The 
  1415. search string is simply placed in quotation marks, for example: 
  1416.  
  1417.  
  1418. parse arg first "beta" second "delta"
  1419.  
  1420. This line assigns to variable first anything which appears before "beta", and 
  1421. to second anything which appears between "beta" and "delta". If "beta" does not 
  1422. appear in the argument string, then the entire string is assigned to first, and 
  1423. the empty string is assigned to "second". If "beta" does appear, but "delta" 
  1424. does not, then everything after "beta" will be assigned to second. 
  1425.  
  1426. It is possible to tokenise the pieces of input appearing between search 
  1427. strings. For example, 
  1428.  
  1429.  
  1430. parse arg "alpha" first second "delta"
  1431.  
  1432. This tokenises everything between "alpha" and "delta" and places the tokens in 
  1433. first and second. 
  1434.  
  1435. Placing a dot instead of a variable name during tokenising causes that token to 
  1436. be thrown away: 
  1437.  
  1438.  
  1439. parse pull a . c . e
  1440.  
  1441. This keeps the first, third and last tokens, but throws away the second and 
  1442. fourth. It is often a good idea to place a dot after the last variable name, 
  1443. thus: 
  1444.  
  1445.  
  1446. parse pull first second third .
  1447.  
  1448. Not only does this throw away the unused tokens, but it also ensures that none 
  1449. of the tokens contain spaces (remember, only the last token may contain spaces; 
  1450. this is the one we are throwing away). 
  1451.  
  1452. Finally, it is possible to parse by numeric position instead of by searching 
  1453. for a string. Numeric positions start at 1, for the first character, and range 
  1454. upwards for further characters. 
  1455.  
  1456.  
  1457. parse var a 6 piece1 +3 piece2 +5 piece3
  1458.  
  1459. The value of piece1 will be the three characters of a starting at character 6; 
  1460. piece2 will be the next 5 characters, and piece3 will be the rest of a. 
  1461.  
  1462.  
  1463. ΓòÉΓòÉΓòÉ 3.10. Interpret ΓòÉΓòÉΓòÉ
  1464.  
  1465. Suppose you have a variable "inst" which contains the string "a=a+1". You can 
  1466. execute that string as an instruction, by typing: 
  1467.  
  1468.  
  1469. interpret inst
  1470.  
  1471. The interpret instruction may be used to accept Rexx instructions from the 
  1472. user, or to assign values to variables whose names are not known in advance. 
  1473.  
  1474.  
  1475. /* Input the name of a variable, and set that variable to 42 */
  1476. parse pull var
  1477. interpret var "=" 42
  1478.  
  1479.  
  1480. ΓòÉΓòÉΓòÉ 3.11. The Stack ΓòÉΓòÉΓòÉ
  1481.  
  1482. Rexx has a data stack, which is accessed via the "push", "queue" and "pull" 
  1483. instructions. The "pull" instruction (or in full, "parse pull") inputs data 
  1484. from the user as we have seen before. However, if there is some data on the 
  1485. stack then it will pull that instead. 
  1486.  
  1487.  
  1488. /* Access the Rexx stack */
  1489. queue "Hello!"
  1490. parse pull a /* a contains "Hello!" */
  1491. parse pull b /* b is input from the user */
  1492. push "67890"
  1493. push "12345"
  1494. parse pull c /* c contains "12345" */
  1495. /* there is one item left on the stack */
  1496.  
  1497. The difference between "push" and "queue" is that when the items are pulled off 
  1498. the stack, the items which were queued appear in the same order that they were 
  1499. queued (FIFO, or first in, first out), and the items which were pushed appear 
  1500. in reverse order (LIFO, or last in, first out). 
  1501.  
  1502.  
  1503. ΓòÉΓòÉΓòÉ 3.12. Subroutines and functions ΓòÉΓòÉΓòÉ
  1504.  
  1505. The following program defines an internal function, and calls it with some 
  1506. data: 
  1507.  
  1508.  
  1509. /* Define a function */
  1510. say "The results are:" square(3) square(5) square(9)
  1511. exit
  1512.  
  1513. square: /* function to square its argument */
  1514. parse arg in
  1515. return in*in
  1516.  
  1517. The output from this program should be: "The results are: 9 25 81" 
  1518.  
  1519. When Rexx finds the function call "square(3)", it searches the program for a 
  1520. label called "square". It finds the label on line 5 - the name followed by a 
  1521. colon. The interpreter executes the code which starts at that line, until it 
  1522. finds the instruction "return". While that code is being executed, the 
  1523. arguments to the function can be determined with "parse arg" in the same way as 
  1524. the arguments to a program. When the "return" instruction is reached, the value 
  1525. specified is evaluated and used as the value of "square(3)". 
  1526.  
  1527. The "exit" instruction in this program causes it to finish executing instead of 
  1528. running into the function. 
  1529.  
  1530. A function which takes multiple arguments may be defined, simply by separating 
  1531. the arguments with a comma. That is, like this: 
  1532.  
  1533.  
  1534. /* Define a function with three arguments */
  1535. say "The results are:" condition(5,"Yes","No") condition(10,"X","Y")
  1536. exit
  1537.  
  1538. condition: /* if the first argument is less than 10, return the second,
  1539. else return the third. */
  1540. parse arg c,x,y
  1541. if c<10 then return x
  1542. else return y
  1543.  
  1544. A subroutine is similar to a function, except that it need not give a value 
  1545. after the "return" instruction. It is called with the "call" instruction. 
  1546.  
  1547.  
  1548. /* Define a subroutine to print a string in a box, then call it */
  1549. call box "This is a sentence in a box"
  1550. call box "Is this a question in a box?"
  1551. exit
  1552.  
  1553. box: /* Print the argument in a box */
  1554. parse arg text
  1555. say "+--------------------------------+"
  1556. say "|"centre(text,32)"|" /* centre the text in the box */
  1557. say "+--------------------------------+"
  1558. return
  1559.  
  1560. It is possible to call a function, even a built-in function, as if it were a 
  1561. subroutine. The result returned by the function is placed into the variable 
  1562. called "result". 
  1563.  
  1564.  
  1565. /* print the date, using the "call" instruction */
  1566. call date "N"
  1567. say result
  1568.  
  1569. If a function or subroutine does not need to use the variables which the caller 
  1570. is using, or if it uses variables which the caller does not need, then you can 
  1571. start the function with the "procedure" instruction. This clears all the 
  1572. existing variables away out of sight, and prepares for a new set of variables. 
  1573. This new set will be destroyed when the function finishes executing. The 
  1574. following program calculates the factorial of a number recursively: 
  1575.  
  1576.  
  1577. /* Calculate factorial x, that is, 1*2*3* ... *x */
  1578. parse pull x .
  1579. say x"!="factorial(x)
  1580. exit
  1581.  
  1582. factorial: /* calculate the factorial of the argument */
  1583. procedure
  1584. parse arg p
  1585. if p<3 then return p
  1586. else return factorial(p-1) * p
  1587.  
  1588. The variable p which holds the argument to funtion factorial is unaffected 
  1589. during the calculation of factorial(p-1), because it is hidden by the 
  1590. "procedure" instruction. 
  1591.  
  1592. If the subroutine or function needs access to just a few variables, then you 
  1593. can use "procedure expose" followed by the list of variable names to hide away 
  1594. all except those few variables. 
  1595.  
  1596. You can write functions and subroutines which are not contained in the same 
  1597. Rexx program. In order to do this, write the function and save it into a file 
  1598. whose name will be recognised by the interpreter. This type of function is 
  1599. called an "external" function, as opposed to an "internal" function which can 
  1600. be found inside the currently running program. 
  1601.  
  1602. If you want to call your function or subroutine using "call foobar" or 
  1603. "foobar()", then you should save it in a file named "foobar.cmd" which can be 
  1604. found in the current directory or in your path. 
  1605.  
  1606. The "procedure" instruction is automatically executed before running your 
  1607. external function, and so it should not be placed at the start of the function. 
  1608. It is not possible for an external function to access any of its caller's 
  1609. variables, except by the passing of parameters. 
  1610.  
  1611. For returning from external functions, as well as the "return" instruction 
  1612. there is "exit". The "exit" instruction may be used to return any data to the 
  1613. caller of the function in the same way as "return", but "exit" can be used 
  1614. return to the caller of the external function even when it is used inside an 
  1615. internal function (which is in turn in the external function). "exit" may be 
  1616. used to return from an ordinary Rexx program, as we have seen. In this case, a 
  1617. number may be supplied after "exit", which will be used as the exit code of the 
  1618. interpreter. 
  1619.  
  1620.  
  1621. ΓòÉΓòÉΓòÉ 3.13. Executing commands ΓòÉΓòÉΓòÉ
  1622.  
  1623. Rexx can be used as a control language for a variety of command-based systems. 
  1624. The way that Rexx executes commands in these systems is as follows. When Rexx 
  1625. encounters a program line which is nether an instruction nor an assignment, it 
  1626. treats that line as a string expression which is to be evaluated and passed to 
  1627. the environment. For example: 
  1628.  
  1629.  
  1630. /* Execute a given command upon a set of files */
  1631. parse arg command
  1632. command "file1"
  1633. command "file2"
  1634. command "file3"
  1635. exit
  1636.  
  1637. Each of the three similar lines in this program is a string expression which 
  1638. adds the name of a file (contained in the string constants) to the name of a 
  1639. command (given as a parameter). The resulting string is passed to the 
  1640. environment to be executed as a command. When the command has finished, the 
  1641. variable "rc" is set to the exit code of the command. 
  1642.  
  1643. The environment to which a command is given varies widely between systems, but 
  1644. in most systems you can select from a set of possible environments by using the 
  1645. "address" instruction. 
  1646.  
  1647.  
  1648. ΓòÉΓòÉΓòÉ 3.14. Signal ΓòÉΓòÉΓòÉ
  1649.  
  1650. Where other programming languages have the "goto" command, Rexx has "signal". 
  1651. The instruction "signal label" makes the program jump to the specified label. 
  1652. However, once this has been done, it is not possible to resume any "select" or 
  1653. "do" control structures that have recently been entered. Thus the main use of 
  1654. "signal" is to jump to an error handling routine when something goes wrong, so 
  1655. that the program can clean up and exit. 
  1656.  
  1657. There is a much more useful way of using "signal", however. That is to trap 
  1658. certain kinds of error condition. The conditions which may be trapped include: 
  1659. "syntax" (that is, any syntax error), "error" (any environment command that 
  1660. results in a non-zero exit code), "halt" (when the user interrrupts execution) 
  1661. and "novalue" (which is when a symbol is used without having been given a 
  1662. value). 
  1663.  
  1664. Error trapping for one of these conditions is turned on by 
  1665.  
  1666.  
  1667. signal on
  1668.  
  1669. and is turned off by 
  1670.  
  1671.  
  1672. signal off
  1673.  
  1674. When one of these conditions occurs, the program immediately signals to a label 
  1675. whose name is the same as that of the condition. Trapping is turned off, so 
  1676. another "signal on" will be required if you want to continue to trap that 
  1677. condition. 
  1678.  
  1679. Whenever a "signal" occurs, the variable "sigl" is set to the line number of 
  1680. the instruction which caused the jump. If the signal was due to an error trap, 
  1681. then the variable "rc" will be set to an error code. 
  1682.  
  1683.  
  1684. /* This program goes on forever until someone stops it. */
  1685. say "Press Control-C to halt"
  1686. signal on halt
  1687. do i=1
  1688. say i
  1689.      do 10000
  1690.      end
  1691. end
  1692.  
  1693. halt:
  1694. say "Ouch!"
  1695. say "Died at line" sigl
  1696.  
  1697.  
  1698. ΓòÉΓòÉΓòÉ 3.15. Tracing ΓòÉΓòÉΓòÉ
  1699.  
  1700. Full details of how to use Rexx's tracing facility are contained in the online 
  1701. rexx reference. 
  1702.  
  1703. If a program goes wrong and you need more information in order to work out why, 
  1704. then Rexx provides you with the ability to trace all or part of your program to 
  1705. see what is happening. 
  1706.  
  1707. The most common form of tracing is turned on by 
  1708.  
  1709.  
  1710. trace r
  1711.  
  1712. This causes each instruction to be listed before it is executed. Also, it 
  1713. displays the results of each calculation after it has been found. 
  1714.  
  1715. Another useful trace command is: 
  1716.  
  1717.  
  1718. trace ?a
  1719.  
  1720. This makes the interpreter list each instruction and stop before it is 
  1721. executed. You can execute the instruction by pressing return, or you can type 
  1722. in some Rexx to be interpreted, after which the interpreter will pause again. 
  1723. You can use this to examine the program's variables and so forth. 
  1724.  
  1725. If you want the interpreter to stop only when passing a label, use: 
  1726.  
  1727.  
  1728. trace ?l
  1729.  
  1730. This is useful for setting breakpoints in the program, or for making the 
  1731. program stop at a function call. 
  1732.  
  1733.  
  1734. ΓòÉΓòÉΓòÉ 3.16. The REXX Summary ΓòÉΓòÉΓòÉ
  1735.  
  1736.  
  1737. ΓòÉΓòÉΓòÉ 3.16.1. Summary of expression syntax ΓòÉΓòÉΓòÉ
  1738.  
  1739.  
  1740. Strings: "String constants" 'enclosed in quotes'
  1741. Hex strings: '616263 64'x
  1742. Numbers: 123.4e-56
  1743. Constant symbols: .abc 1d4 7!
  1744. Simple symbols: foo bar xyz3
  1745. Stems: array.
  1746. Compound symbols: c.3 element.bar.45
  1747. Operators: arithmetic: + - * / ** (to-power) % (div) // (mod)
  1748.  
  1749. string: [abuttal] [space] || (concatenation)
  1750.  
  1751. logical: \ (not) & (and) | (or) && (xor)
  1752.  
  1753. comparison: = > < <> <= >= \> \< \=
  1754.  
  1755. == >> << <<= >>= \>> \<< \== (strong comparison)
  1756. Function calls: fn(1,2,3) bar(,5) 'DATE'()
  1757.  
  1758.  
  1759. ΓòÉΓòÉΓòÉ 3.16.2. Summary of instructions ΓòÉΓòÉΓòÉ
  1760.  
  1761. /* this is a comment */
  1762.  
  1763. expression - execute a host command
  1764.  
  1765. symbol=value - assignment
  1766.  
  1767. ADDRESS [VALUE] [environment] - change the current environment
  1768. ADDRESS environment command - execute a command in an environment
  1769.  
  1770. CALL name [arg][,[arg],...]] - call a function or subroutine
  1771. CALL ON condition [NAME symbol]- turn on condition handling
  1772. CALL OFF condition - turn off condition handling
  1773. condition = ERROR | FAILURE | NOTREADY | HALT
  1774.  
  1775. DO [ symbol=start [TO finish] ] [WHILE expression_w]
  1776. [ [BY step ] ]
  1777. [ [FOR count ] ] [UNTIL expression_u]
  1778. [ expression_c ] [FOREVER ]
  1779. - block or repetitive block instruction
  1780.  
  1781. DROP symbol [symbol...] - de-assignment
  1782.  
  1783. END [symbol] - end block or repetitive block instruction
  1784.  
  1785. EXIT [expression] - exit program or external function
  1786.  
  1787. IF expression [;] THEN [;] statement [ ; ELSE [;] statement]
  1788. - conditional instruction
  1789.  
  1790. INTERPRET expression - dynamically execute a string
  1791.  
  1792. ITERATE [symbol] - continue repetitive block
  1793.  
  1794. LEAVE [symbol] - leave repetitive block
  1795.  
  1796. NOP - do nothing
  1797.  
  1798. NUMERIC DIGITS n - set parameters for numeric formatting
  1799. NUMERIC FUZZ n
  1800. NUMERIC FORM SCIENTIFIC
  1801. | ENGINEERING
  1802. | "string constant"
  1803. | [VALUE] expression
  1804.  
  1805. OPTIONS expression - Control system-dependent things
  1806.  
  1807. [PARSE [UPPER]] ARG template
  1808. [PARSE [UPPER]] PULL [template]
  1809. PARSE [UPPER] LINEIN [template]
  1810. PARSE [UPPER] SOURCE template
  1811. PARSE [UPPER] VERSION template
  1812. PARSE [UPPER] NUMERIC template
  1813. PARSE [UPPER] VAR symbol template
  1814. PARSE [UPPER] VALUE expression WITH template
  1815. template -> [firstPosition] assignments [assignments]
  1816. assignments -> [nextPosition] varlist [stopPosition]
  1817. varlist -> varname ' ' [varlist]
  1818. varname -> "non-constant symbol"
  1819. | '.'
  1820. firstPosition -> position
  1821. nextPosition -> position [nextPosition]
  1822. stopPosition -> position
  1823. position -> searchPosition
  1824. | absPosition
  1825. | relPosition
  1826. | '(' "expression" ')'
  1827. searchPosition -> "string constant"
  1828. absPosition -> "integer"
  1829. | '=' numexpr
  1830. relPosition -> '+' numexpr
  1831. | '-' numexpr
  1832. numexpr -> "integer"
  1833. | '(' "integer expression" ')'
  1834.  
  1835. PROCEDURE - hide the caller's symbols
  1836. PROCEDURE EXPOSE var1 [var2...]
  1837. PROCEDURE HIDE var1 [var2...]
  1838.  
  1839. PUSH expression - stack a value in LIFO order
  1840. QUEUE expression - stack a value in FIFO order
  1841.  
  1842. RETURN [value] - return from a function or subroutine
  1843.  
  1844. SAY [expression] - echo data
  1845. SAYN expression - echo data without newline
  1846.  
  1847. SELECT [expression]
  1848. WHEN expression THEN statements
  1849. WHEN expression THEN statements
  1850.  ...
  1851. [OTHERWISE statements]
  1852. END [SELECT] - switch on a list of conditions
  1853.  
  1854. SIGNAL [VALUE] name - jump to a label
  1855. SIGNAL ON condition [NAME symbol] - turn on condition handling
  1856. SIGNAL OFF condition - turn off condition handling
  1857. condition = ERROR | FAILURE | NOTREADY | HALT | SYNTAX | NOVALUE
  1858.  
  1859. TRACE [symbol] - control program tracing. Values are:
  1860. TRACE "string" A (all clauses) C (commands) E (error)
  1861. TRACE VALUE expression F (failure) I (intermediate values)
  1862. L (labels) N (normal, =F) O (off)
  1863. R (results)
  1864.  
  1865.  
  1866. ΓòÉΓòÉΓòÉ 3.16.3. Summary of builtin functions ΓòÉΓòÉΓòÉ
  1867.  
  1868.  
  1869. ΓòÉΓòÉΓòÉ 3.16.3.1. Standard functions ΓòÉΓòÉΓòÉ
  1870.  
  1871. ABBREV(information,info[,length]) - check for valid abbreviations
  1872. ABS(number) - return the absolute value
  1873. ADDRESS() - return the current environment
  1874. ARG([n][,opt]) - return or test an argument
  1875. BITAND(string1,string2[,pad])
  1876. BITOR (string1,string2[,pad]) - combine two strings with bit operations
  1877. BITXOR(string1,string2[,pad])
  1878. B2D(binary)
  1879. B2X(binary)
  1880. D2B(decimal)
  1881. C2X(string)
  1882. C2D(string[,n])
  1883. D2C(decimal[,n]) - convert between data formats
  1884. D2X(decimal[,n])
  1885. X2B(hex)
  1886. X2C(hex)
  1887. X2D(hex)
  1888. CENTER(s,n[,pad]) - centre a string in a field
  1889. CENTRE(s,n[,pad])
  1890. COMPARE(s1,s2[,pad]) - compare two strings
  1891. CONDITION([option]) - return information about trapped condition
  1892. Option can be (default I):
  1893. C (condition name) D (description)
  1894. I (instruction) S (status)
  1895. COPIES(s,n) - replicate a string
  1896. DATATYPE(string[,type]) - test datatype. Type can be:
  1897. A (alphanumeric) B (bits) L (lowercase)
  1898. M (mixed case) N (number) S (symbol chars)
  1899. U (upper case) W (whole number) X (hex)
  1900. DATE([format]) - get date. Format can be:
  1901. B (base date - days since 1/1/1 AD)
  1902. C (days in century) D (days in year)
  1903. E (European) J (Julian) M (month name)
  1904. N (normal: dd Mon yyyy) O (ordered)
  1905. S (sorted) U (USA) W (day of week)
  1906. DELSTR(string,n[,length]) - delete substring
  1907. DELWORD(string,n[,length]) - delete words
  1908. DIGITS() - NUMERIC DIGITS setting
  1909. ERRORTEXT(i) - Rexx error message
  1910. FORM() - NUMERIC FORM setting
  1911. FORMAT(number [,[before] [,[after] [,[expp] [,expt]]]] )
  1912. - format a number as specified
  1913. FUZZ() - NUMERIC FUZZ setting
  1914. INSERT(new,target[,[n][,[length][,pad]]]) - insert new string into target
  1915. JUSTIFY(s,n[,pad]) - justify text to given width
  1916. LASTPOS(needle,haystack[,start]) - find last occurrence of a string
  1917. LEFT(string,num[,pad]) - return an initial substring
  1918. LENGTH(string) - find the length of a string
  1919. LINESIZE() - find the terminal width
  1920. MAX(number[,number...]) - find the maximum of a set
  1921. MIN(number[,number...]) - find the minimum of a set
  1922. OVERLAY(new,target[,[n][,[length][,pad]]]) - overlay new string on to target
  1923. POS(needle,haystack[,start]) - find the first occurance of a string
  1924. QUEUED() - return the number of items on the stack
  1925. RANDOM([min][,[max][,seed]]) - return a random number
  1926. REVERSE(string) - find the reverse of a string
  1927. RIGHT(string,num[,pad]) - return a final substring
  1928. SOURCELINE([i]) - return a line of the source program
  1929. SPACE(s[,[n][,pad]]) - evenly space words in a sentence
  1930. STRIP(string[,[opt][,char]]) - remove leading/trailing spaces
  1931. SUBSTR(string,n[,length[,pad]]) - return a substring
  1932. SUBWORD(string,n[,k]) - return a substring of words
  1933. SYMBOL(name) - test to see if a symbol is defined
  1934. TIME([format]) - get the time. Format can be:
  1935. C (civil time) N (normal) L (long)
  1936. H (hours since midnight)
  1937. M (minutes since midnight)
  1938. S (seconds since midnight) E (elapsed time)
  1939. R (elapsed time then reset)
  1940. TRACE([setting]) - get and/or set trace mode (see trace
  1941. instruction)
  1942. TRANSLATE(string[,[tableo][,[tablei][,pad]]])
  1943. - translate characters using given tables
  1944. TRUNC(number[,n]) - truncate floating point number
  1945. VALUE(s[,[newvalue][,selector]]) - get or set value of a symbol
  1946. VERIFY(string,reference[,[option][,start]])
  1947. - verify string for valid characters
  1948. WORD(string,n) - return a word from a string
  1949. WORDINDEX(string,n) - return the position of a word in a string
  1950. WORDLENGTH(string,n) - return the length of a word in a string
  1951. WORDPOS(phrase,string[,start]) - find a phrase in a string
  1952. WORDS(string) - return the number of words in a string
  1953. XRANGE([a[,b]]) - return a range of characters
  1954.  
  1955.  
  1956. ΓòÉΓòÉΓòÉ 3.16.3.2. I/O functions (some of which are UNIX-specific) ΓòÉΓòÉΓòÉ
  1957.  
  1958. CHARIN([stream] [,[position] [,count]]) - read characters
  1959. CHAROUT([stream] [,[string] [,position] ]- write characters
  1960. CHARS([stream]) - number of characters available
  1961. CLOSE(stream) - close a stream
  1962. FDOPEN(fd [,[mode] [,stream]]) - open an fd number
  1963. FILENO(stream) - find an fd number
  1964. FTELL(stream) - return the current file pointer
  1965. LINEIN([stream] [,[line] [,count]]) - read a line
  1966. LINEOUT([stream] [,[string] [,line]]) - write a line
  1967. LINES([stream]) - determine whether lines may be read
  1968. OPEN(file [,[mode] [,stream]]) - open a file
  1969. PCLOSE(stream) - close a pipe
  1970. POPEN(command [,[mode] [,stream]]) - open a pipe to a shell command
  1971. STREAM(stream [,[option] [,command]]) - miscellaneous stream operations
  1972.  
  1973.  
  1974. ΓòÉΓòÉΓòÉ 3.16.3.3. UNIX-specific functions ΓòÉΓòÉΓòÉ
  1975.  
  1976. CHDIR(directory) - change to new directory
  1977. GETCWD() - return current working directory
  1978. GETENV(name) - get an environment variable
  1979. PUTENV(string) - set an environment variable
  1980. SYSTEM(s) - return the output of a shell command
  1981. USERID() - return the process owner's login name
  1982.  
  1983.  
  1984. ΓòÉΓòÉΓòÉ 3.16.3.4. Mathematical functions (implemented as separate package) ΓòÉΓòÉΓòÉ
  1985.  
  1986. ACOS(x) the arc-cosine of x in radians (0<=acs(x)<=pi)
  1987. ASIN(x) the arc-sine of x in radians (-pi/2<=asn(x)<=pi/2)
  1988. ATAN(x) the arc-tangent of x in radians (-pi/2<=atn(x)<=pi/2)
  1989. COS(x) the cosine of x radians
  1990. EXP(x) the exponential of x (2.718281... to the power x)
  1991. LN(x) the natural logarithm of x (x>0)
  1992. SIN(x) the sine of x radians
  1993. SQRT(x) the square root of x (x>=0) [arbitrary precision possible]
  1994. TAN(x) the tangent of x radians (x <> pi/2)
  1995. TOPOWER(x,y) x to the power y
  1996.  
  1997.  
  1998. ΓòÉΓòÉΓòÉ 4. Six Rules of Thumb for Beginning REXX Programmers ΓòÉΓòÉΓòÉ
  1999.  
  2000. SIX RULES OF THUMB FOR BEGINNING REXX PROGRAMMERS 
  2001. (who already know Pascal or C) 
  2002.  
  2003. (Copyright (c) 1993 by Raja Thiagarajan. This file may be copied for any 
  2004. NONcommercial purpose as long as it is left unchanged.) 
  2005.  
  2006. Since there are plenty of books, articles, and even OS/2 help files that teach 
  2007. REXX, why do we need this article? Because those books, articles, etc. are 
  2008. mostly aimed at people who have never programmed before. Thus, they have two 
  2009. major drawbacks. First, they dwell on things that programmers already know, 
  2010. like what a variable is. Second, they don't warn would-be REXX programmers that 
  2011. some things are different in REXX, and some of the "habits" that you might 
  2012. carry over from other languages can get you in trouble. 
  2013.  
  2014. This article gives six "rules of thumb" that should help you get started in 
  2015. REXX if you already know C or Pascal (or, really, any of the children of 
  2016. Algol). 
  2017.  
  2018.  
  2019. ΓòÉΓòÉΓòÉ 4.1. START EVERY REXX PROGRAM WITH A COMMENT! ΓòÉΓòÉΓòÉ
  2020.  
  2021. You already know this. There shouldn't be any reason for me to repeat it ... 
  2022. except that it's an easy mistake to make, and it ties in with an important 
  2023. concept that we'll get to under the second rule.  Here's "hello, world" in 
  2024. REXX: 
  2025.  
  2026.      /* hello.cmd -- program to say hi*/
  2027.      say "Hello, world"
  2028.  
  2029. Type these two lines in your favorite editor, save the result as HELLO.CMD, and 
  2030. enter HELLO at an OS/2 prompt. Your computer should respond "Hello, world". 
  2031.  
  2032. Under OS/2, you are required to start every REXX program with a comment. And I 
  2033. do mean start; if there's so much as a space or carriage return in front of 
  2034. that comment--well, why don't you try that now? Insert a space in front of the 
  2035. comment and try running the program again. You'll see a big fat error message. 
  2036. So: START EVERY REXX PROGRAM WITH A COMMENT. 
  2037.  
  2038. (By the way, the conventions for comments in REXX are simple. Each comment 
  2039. begins with a "/*" and ends with a "*/". Comments can be spread over several 
  2040. lines. Unlike ANSI C or Pascal, REXX permits you to nest comments, so it's much 
  2041. easier to comment out hunks of code for testing.) 
  2042.  
  2043.  
  2044. ΓòÉΓòÉΓòÉ 4.2. BE CAREFUL ABOUT USING SPACES IN CERTAIN PLACES! ΓòÉΓòÉΓòÉ
  2045.  
  2046. You've already had a taste of this in the previous rule: If you put a space 
  2047. before the opening comment, your program will bomb. But there are two more 
  2048. places where the significance of spaces will trip up someone who's used to 
  2049. programming in C or Pascal. In REXX, everything is ultimately a string. If you 
  2050. want to concatenate two strings, you can do so by putting the explicit string 
  2051. abuttal operator ("||") between them. You can also concatenate them by simply 
  2052. writing one after another (this is known as "implied abuttal"). Please enter 
  2053. and run the following program. 
  2054.  
  2055.      /* hello2.cmd -- Another program to say hi*/
  2056.      greeting = "Hello"
  2057.      say greeting "world"
  2058.      say greeting"world"
  2059.  
  2060. You should see "Hello world" on one line, followed by "Helloworld" on the 
  2061. second line. Your first guess might be that SAY in REXX is like PRINTF in C or 
  2062. WRITELN in Pascal; that it can accept an arbitrary number of arguments. But 
  2063. you'd be wrong. SAY can only be followed by a single expression: the string to 
  2064. be displayed. However, since greeting holds a string and "world" is a string, 
  2065. and since you've written one after the other, REXX treats this as implied 
  2066. abuttal. That is, REXX concatenates the two strings to form a single string 
  2067. which it then passes to SAY. Thus, the third line in the program above is 
  2068. equivalent to 
  2069.  
  2070.      say "Hello" "world"
  2071.  
  2072. or 
  2073.  
  2074.      say "Hello world"
  2075.  
  2076. On the other hand, the last line of the program is equivalent to 
  2077.  
  2078.      say "Hello"'world'
  2079.  
  2080. (In REXX, strings can be delimited by either single or double quotes. As in 
  2081. Pascal, you can "double" the delimiter to make it appear in a string literal. 
  2082. If I hadn't switched delimiters, the string would have been the one displayed 
  2083. as Hello"world.) Since there is no space between the strings, REXX abuts the 
  2084. strings without inserting a space between them. Thus, this line is equivalent 
  2085. to 
  2086.  
  2087.      say "Helloworld"
  2088. and it displays what you saw when you ran the program. 
  2089.  
  2090. Going back to the third line: You typed it with a single space between the 
  2091. variable 'greeting' and the string "world". What if you had used two spaces? 
  2092. Try it now. Edit the program and re-run it. 
  2093.  
  2094. Surprised? In REXX, more than one space is always treated the same as a single 
  2095. space (except in string literals). This is why you can write 
  2096.  
  2097.      if greeting = 'hello' then
  2098.         say "It's hello"
  2099.  
  2100. instead of having to always write 
  2101.  
  2102.      if greeting = 'hello' then
  2103.      say "It's hello"
  2104.  
  2105. Some of you are starting to yawn. So spaces are significant when you do string 
  2106. concatenation; so what? How often do you do string concatenation? Well, in 
  2107. REXX, you do it a lot. After all, it's the easiest way to output more than one 
  2108. thing at a time using the "preferred" output instruction! But there's a serious 
  2109. implication here that will cause you no end of grief until you figure it out. 
  2110. It's only a problem for people who have learned another language like C or 
  2111. Pascal and who expect REXX will work the same way. Up above, I wrote "You can 
  2112. also concatenate [strings] by simply writing one after another." Do you see a 
  2113. problem there? 
  2114.  
  2115. No? Enter the following program: 
  2116.  
  2117.      /* func.cmd -- program to demonstrate a "problem" with
  2118.                     function calls*/
  2119.      say abs(-3) "is *not*" abs (-3)
  2120.  
  2121. Before you run it, try to predict what it will display. Now run it. 
  2122.  
  2123. Well, whatever you predicted, it probably wasn't the 
  2124.  
  2125.      3 is *not* ABS -3
  2126.  
  2127. that you actually got. What happened? 
  2128.  
  2129. The "problem" is this. When you write abs(-3), REXX interprets it as a call to 
  2130. the absolute value function with -3 as an argument. However, when you put a 
  2131. space in front of the parentheses, REXX interprets this as an implicit abuttal; 
  2132. it assumes that you want to concatenate the string value of the variable 'abs' 
  2133. with the string '-3'. (The default value of 'abs' is "ABS" since the default 
  2134. value of every REXX variable is a string consisting of its name written in 
  2135. uppercase. By the way, like Pascal but unlike C, REXX ignores the 
  2136. upper/lower-case distinction outside of string literals.) Of course, since 
  2137. there's a space between the elements, you get a space between "ABS" and "-3". 
  2138.  
  2139. Some of you will recoil in horror at this: How dare REXX mandate that you 
  2140. cannot put a space between a function's name and its arguments! For my own 
  2141. part, I can only say that it's reasonable when you get used to it. And if REXX 
  2142. had been the first language you'd learned, it probably would seem weird the 
  2143. other way. So, grin and bear it, and BE CAREFUL ABOUT USING SPACES IN CERTAIN 
  2144. PLACES. 
  2145.  
  2146. An important digression: These first two rules of thumb bring up a very 
  2147. important difference between REXX and Pascal, C, or many other programming 
  2148. languages. Namely: REXX* is not entirely a free-form language. Sometimes, you 
  2149. have to be careful about where you put spaces in REXX. And sometimes you have 
  2150. to be careful about where you split lines. For instance, while Pascal or C have 
  2151. no trouble if you put arguments to a procedure on a different line from the 
  2152. name of the procedure, REXX is not as forgiving. Using SAY as an example, 
  2153.  
  2154.      say
  2155.      "Hello world"
  2156.  
  2157. is not the same as 
  2158.  
  2159.      say "Hello world"
  2160.  
  2161. The latter displays "Hello world"; the former displays a blank line and then 
  2162. bombs when it tries to execute "Hello world" as an OS/2 command. If you need to 
  2163. continue a clause across a line break, use a comma. The comma will be replaced 
  2164. by a space and then REXX will continue as if the end-of-line character didn't 
  2165. exist. So, for instance, 
  2166.  
  2167.      say ,
  2168.      "Hello world"
  2169.  
  2170. will display "Hello world". 
  2171.  
  2172.  
  2173. ΓòÉΓòÉΓòÉ 4.3. DON'T CONFUSE SUBROUTINE CALLS WITH FUNCTION CALLS! ΓòÉΓòÉΓòÉ
  2174.  
  2175. In C or Pascal, you use pretty much the same syntax whether you're calling a 
  2176. function (ie, a routine that returns a value) or a procedure (a routine that 
  2177. doesn't return a value). In fact, C blurs the distinction by letting you 
  2178. "ignore" the return value of a function if you want. But in REXX, the way you 
  2179. call a subroutine (which is REXX's term for a procedure) is completely 
  2180. different from the way you call a function. Here's an example of a function 
  2181. call in REXX: 
  2182.  
  2183.      length = max(x_coord, y_coord)
  2184.  
  2185. and here's an example of a subroutine call: 
  2186.  
  2187.      call charout myFile, dist
  2188.  
  2189. In REXX, a function is called by giving its name, followed directly by the left 
  2190. parenthesis (no space permitted! Remember the second rule!), followed by zero 
  2191. or more arguments (separated by commas) and then the right parenthesis. 
  2192.  
  2193. By contrast, a subroutine is called by using the keyword CALL, followed by the 
  2194. name of the subroutine, followed by a list of zero or more arguments separated 
  2195. by commas. No parentheses are used. 
  2196.  
  2197. (Digression: Am I the only one who's noticed that Microsoft's latest Visual 
  2198. Basic products seem to have picked up this distinction and syntax from REXX?) 
  2199.  
  2200. Having said all that, let me confess that you can call functions as if they 
  2201. were subroutines. In this case, the return value goes into the special variable 
  2202. RESULT. For instance: 
  2203.  
  2204.      /* subr.cmd -- Calls a function like a subroutine */
  2205.      call abs -3
  2206.      say "abs(-3) is" result
  2207.  
  2208. will display "abs(-3) is 3". Calling a subroutine as if it were a function is 
  2209. an exercise in futility. Thus, don't do something like 
  2210.  
  2211.      charout(myFile, "foo")     /*WRONG!*/
  2212.  
  2213. And always remember: DON'T CONFUSE SUBROUTINE CALLS WITH FUNCTION CALLS! 
  2214.  
  2215.  
  2216. ΓòÉΓòÉΓòÉ 4.4. DON'T TREAT REXX COMPOUND VARIABLES AS ARRAYS! ΓòÉΓòÉΓòÉ
  2217.  
  2218. In Pascal and C, you declare arrays and reference their elements using brackets 
  2219. ("[]"). In REXX, you don't declare arrays for two good reasons: First, you 
  2220. can't declare variables, and second, REXX doesn't have arrays. Okay, more 
  2221. seriously: REXX's compound variables can often be used as arrays. For instance, 
  2222. try the following program: 
  2223.  
  2224.      /* comp1.cmd -- 1st program to try compound vars */
  2225.      do j = 1 to 3
  2226.         square.j = j * j
  2227.      end j
  2228.  
  2229.      do i = 1 to 3
  2230.         say "square."i "is" square.i
  2231.      end i
  2232.  
  2233. You will get "square.1 is 1", "square.2 is 4", and "square.3 is 9". In this 
  2234. case, we could treat the square compound variable as if it were an array. But 
  2235. in other cases, we can't. For instance, try deleting the last three lines in 
  2236. the above program and replace them with the following: 
  2237.  
  2238.      do i = 2 to 4
  2239.         say "square."i-1 "is" square.i-1
  2240.      end i
  2241.  
  2242. If the dots in REXX worked like brackets in C or Pascal, this program should 
  2243. display the same thing as before, right? Well try it. 
  2244.  
  2245. You got "square.1 is 3", "square.2 is 8", and then a "Bad arithmetic" error 
  2246. message. What happened? Well, "square.i-1" does not mean "calculate i-1 and 
  2247. then reference that element of the square array". It more nearly means, 
  2248. "calculate i, reference that element of the square array, and subtract 1 from 
  2249. it." (The "bad arithmetic" occurs when you try to subtract 1 from the value of 
  2250. square.4, which is "SQUARE.4".) Actually, it doesn't even mean that, because 
  2251. REXX doesn't have arrays--oh, I said that before. 
  2252.  
  2253. "Aha!" you say. "There's an easy way to fix this! We can use parentheses and 
  2254. write 
  2255.  
  2256.      do i = 2 to 4
  2257.         say "square."i-1 "is" square.(i-1)
  2258.      end i
  2259.  
  2260. and that will work!" Uh huh. Try it now. 
  2261.  
  2262. This time, the program bombs immediately. The problem is, "square.(i-1)" means 
  2263. "Call the function named 'square.' with the argument 'i-1'." Since you haven't 
  2264. declared a function named 'square.', REXX complains that the "Routine was not 
  2265. found." 
  2266.  
  2267. (Hold it! Do not tell me that we can fix this by putting a space in front of 
  2268. the parentheses! It'd break my heart to find out that you slept through the 
  2269. second rule. ;-) 
  2270.  
  2271. How can we fix this? How can we easily reference an array element in REXX using 
  2272. an arbitrary expression? Simple enough: We can't. If you want to reference a 
  2273. compound variable using some arbitrary expression, you should set a variable to 
  2274. that expression and then use the variable. So, for instance, replacing those 
  2275. three lines with 
  2276.  
  2277.      do i = 2 to 4
  2278.         j = i - 1
  2279.         say "square."j "is" square.j
  2280.      end i
  2281.  
  2282. will do the trick. 
  2283.  
  2284. In case some of you may still be holding out hopes that you can think of 
  2285. compound variables in REXX as arrays in C or Pascal, let's try running another 
  2286. program. Type in and run the following: 
  2287.  
  2288.      /* comp2.cmd -- 2nd program to try compound vars */
  2289.      j = 3
  2290.      k = 4
  2291.      ary.j.k = "one"
  2292.      m = 34/10
  2293.      say ary.3.4 "is the same as" ary.j.k "is the same as" ary.m
  2294.  
  2295. If you're going to convince me that REXX compound variables are the same as 
  2296. arrays in C or Pascal, you'll have to explain how the program above works. Any 
  2297. volunteers? 
  2298.  
  2299. Actually, the fact that REXX compound variables are not the same as arrays is a 
  2300. great opportunity, not a difficulty. Try the program below: 
  2301.  
  2302.      /* comp3.cmd -- 3rd use of compound variables */
  2303.      count. = 0
  2304.      textWords = ''
  2305.      say "Enter a line of text below:"
  2306.      parse upper pull textLine
  2307.      do i = 1 to words(textLine)
  2308.         w = word(textLine, i)
  2309.         count.w = count.w + 1
  2310.         if count.w = 1 then
  2311.            textWords = textWords w
  2312.      end i
  2313.  
  2314.      do i = 1 to words(textWords)
  2315.         w = word(textWords, i)
  2316.         say 'You used the word "'w'"' count.w 'time(s).'
  2317.      end i
  2318.  
  2319. Whew! Okay, now run this program. Enter "The quick brown fox jumps over the 
  2320. lazy dog". Your computer will tell you each word that appeared in the line of 
  2321. text, and how many times each word appeared. As far as this rule of thumb goes, 
  2322. there are two important things to point out in this program: 
  2323.  
  2324. First, there is the line "count. = 0". This shows the use of a stem variable in 
  2325. REXX. When you initialize a stem variable, any variable that begins with that 
  2326. stem is set to that value. So, after this line, the variables count., count.1, 
  2327. count.57, count.foo, and count.dracula all have a value of zero. (Also, you can 
  2328. use the DROP instruction on a stem variable to return all those compound 
  2329. variables to their initial state.) 
  2330.  
  2331. Second: Loosely speaking, we're turning count. into an "array". But what are 
  2332. the indexes? The REXX function "words" returns the number of blank-delimited 
  2333. words in a string, and "word(str, j)" returns the j-th such word in str. So w 
  2334. is a word -- and the indexes on count are the actual words that appear in the 
  2335. string! So, for instance, count."the" holds the number of times that "the" 
  2336. appears in the string -- for our sample run, that was 2. 
  2337.  
  2338. So it's important that you DON'T TREAT REXX COMPOUND VARIABLES AS ARAYS, 
  2339. because it can get you into trouble, and because you'll miss the chance to 
  2340. write some very powerful and flexible programs. 
  2341.  
  2342.  
  2343. ΓòÉΓòÉΓòÉ 4.5. MAKE THE MOST OF THE EXTERNAL DATA QUEUE! ΓòÉΓòÉΓòÉ
  2344.  
  2345. Enter the following program: 
  2346.  
  2347.      /* sayhi.cmd -- program to say hello */
  2348.      say "Please enter your name below:"
  2349.      parse pull name
  2350.      if name = "" then
  2351.         name = "Stranger"
  2352.      say "Hello," name"."
  2353.  
  2354. and run it, entering your name. Your computer will say hello to you. Okay, this 
  2355. isn't very earth-shattering. But I want to draw your attention to the third 
  2356. line of the program: "parse pull name". This is the line that accepts input 
  2357. from the keyboard. However, that's not its "primary" use. The PARSE PULL 
  2358. instruction removes a line from the external data queue, falling back on 
  2359. standard input only if the queue is empty. 
  2360.  
  2361. To demonstrate this, enter and run the following program: 
  2362.  
  2363.      /* push1.cmd -- program to put an item in the external data queue */
  2364.      push "Jean-luc"
  2365.  
  2366. and run it. What happened? 
  2367.  
  2368. Okay, so nothing happened. Get a directory, clear the screen, and do some other 
  2369. housekeeping tasks. Now enter "sayhi" at the prompt. 
  2370.  
  2371. If that doesn't impress you, nothing will. REXX's external data queue can be 
  2372. used to communicate between far-flung programs, and it isn't affected by any 
  2373. intervening non-REXX programs. It's also useful within a program; one 
  2374. subroutine can stuff as much into the external data queue as it wants, and 
  2375. another subroutine can get it back out by using PARSE PULL. 
  2376.  
  2377. You can put things in the external data queue using PUSH or QUEUE. PUSH puts 
  2378. them at the front of the queue, and QUEUE puts them at the back. (That is, PUSH 
  2379. treats the queue like a LIFO stack, and QUEUE treats it as a FIFO queue.) You 
  2380. take elements off the front of the queue by using PARSE PULL. Finally, you use 
  2381. the REXX function QUEUED to find the number of items that are in the external 
  2382. data queue. So, one quick way to flush the queue would be 
  2383.  
  2384.      /* flush.cmd -- Program to flush the external data queue*/
  2385.      do queued()
  2386.         parse pull dummy
  2387.      end
  2388.  
  2389. (If you want to see what you're flushing, insert a "say dummy" line after the 
  2390. parse pull line.) By now, I hope I've convinced you to MAKE THE MOST OF THE 
  2391. EXTERNAL DATA QUEUE. 
  2392.  
  2393.  
  2394. ΓòÉΓòÉΓòÉ 4.6. USE PARSE TEMPLATES! ΓòÉΓòÉΓòÉ
  2395.  
  2396. Type in this sample program: 
  2397.  
  2398.      /* temp1.cmd -- 1st program to use template */
  2399.      parse arg i j k
  2400.      say 'i is "'i'", j is "'j'", and k is "'k'"'
  2401.  
  2402. and run it by entering 
  2403.  
  2404.      temp1 Alfa Bravo Charlie Delta
  2405.  
  2406. at an OS/2 prompt. Your computer will respond 
  2407.  
  2408.      i is "Alfa", j is "Bravo", and k is "Charlie Delta"
  2409.  
  2410. Let's analyze the second line in detail. When OS/2 calls this program, 
  2411. everything after the "temp1 " on the command line will be packed into a string. 
  2412. The PARSE ARG instruction is used to "split up" this string and put pieces of 
  2413. it into the variables you specify. In this case, you used a parse template of 
  2414. "i j k", which means to put the first word from the argument string into i, put 
  2415. the second word into j, and put the rest into k. The spaces that separate these 
  2416. words are discarded, though any trailing spaces are saved and put in the last 
  2417. variable. (As in comp3.cmd, a "word" is any sequence of non-space characters 
  2418. that is delimited by one or more spaces.) If this program is passed more than 
  2419. three words (as in our example), the extras all become part of k. If fewer than 
  2420. three words are given, then the "extra" variables are set to the empty string. 
  2421. Try entering "temp1 hello world" to see the latter rule in action. 
  2422.  
  2423. If you're a C programmer, you may already see the great convenience of parse 
  2424. templates over argc and argv[]; certainly it's nice that the arguments go into 
  2425. the variables you want without having to do lots of calls to strcpy. But wait, 
  2426. there's more! For one thing, PARSE ARG is an instruction, not a declaration. 
  2427. Add the following two lines to the end of temp1.cmd: 
  2428.  
  2429.      parse arg m
  2430.      say 'm is "'m'"'
  2431.  
  2432. and rerun it with "temp1 Alfa Bravo Charlie Delta". You get the same results as 
  2433. above, and the computer will also inform you that 'm is "Alfa Bravo Charlie 
  2434. Delta"'. So if you "change your mind" about what values should go where, or if 
  2435. you want to use the values in several different ways, you can do it easily. 
  2436.  
  2437. But wait, there's still more! Suppose you're only interested in the first and 
  2438. third words given to your program. You can use a period as a placeholder in the 
  2439. template. Add the following lines to temp1: 
  2440.  
  2441.      parse arg w1 . w3 .
  2442.      say 'w1 is "'w1'" and w3 is "'w3'"'
  2443.  
  2444. The top line means, "Put the first word in w1, discard the second word, put the 
  2445. third word in w3, and discard the rest of the line." You should be able to 
  2446. easily predict what will happen when you enter "temp1 Alfa Bravo Charlie 
  2447. Delta". Try it to check if you're right. 
  2448.  
  2449. If that isn't enough, you can also use column numbers in parse templates. Try 
  2450. adding these lines to your (now quite large!) temp1.cmd: 
  2451.  
  2452.      parse arg c1 5 c5 10
  2453.      say 'c1 is "'c1'" and c5 is "'c5'"'
  2454.  
  2455. and run it via "temp1 Alfa Bravo Charlie Delta". (Note the spelling of "Alfa".) 
  2456. You will be told that c1 is "Alfa" and c5 is " Brav". This new PARSE ARG line 
  2457. means "Put the characters in columns 1-4 into the variable c1, put the 
  2458. characters in columns 5-9 into the variable c5, and discard the characters from 
  2459. column 10 on (if any)." Column 1 is the first character after the space that 
  2460. follows the name of your program. Try predicting what would happen if you put 
  2461. an extra space in front of the word "Alfa" when you execute temp1 with the same 
  2462. arguments again, and try it to see if your prediction was correct. 
  2463.  
  2464. (By the way, you can also use "relative positional patterns"; for instance, the 
  2465. PARSE ARG line could have been written with "+5" instead of "10".) 
  2466.  
  2467. Have we exhausted the possibilities of the parse template? NO! However, I'll 
  2468. just show one more example. I'm sure you're sick of temp1, so let's try a new 
  2469. program, namely: 
  2470.  
  2471.      /* vcopy.cmd -- verbose copy command */
  2472.      parse upper arg "FROM: " srcFile "TO: " destFile
  2473.      "copy" srcFile destFile
  2474.  
  2475. Type this program in and save it as vcopy.cmd. (Note that we've added a new 
  2476. keyword, "upper". This keyword will convert everything to uppercase, so the 
  2477. program will work no matter what combination of upper- or lowercase our users 
  2478. type). Now run it by entering 
  2479.  
  2480.      vcopy from: temp1.cmd to: boring.cmd
  2481.  
  2482. OS/2 will copy the file temp1.cmd to boring.cmd. (We put the OS/2 copy command 
  2483. in quotes so REXX wouldn't mistake it for a variable name.) The nice thing is, 
  2484. the following command will give the same results: 
  2485.  
  2486.      vcopy this is ignored from: temp1.cmd to: boring.cmd
  2487.  
  2488. To summarize, you can use string literals in a parse template and REXX will do 
  2489. all the hard work of matching the arguments to your template. Clearly you 
  2490. should USE PARSE TEMPLATES because they'll make your job much easier. 
  2491.  
  2492. (Here's an exercise for the reader: Modify vcopy.cmd so that if the user types 
  2493. more than one word after "FROM: " or "TO: ", the extra words are ignored. Test 
  2494. your modified program by entering 
  2495.  
  2496.      vcopy from: temp1.cmd through OS/2 to: boring.cmd at long last
  2497.  
  2498. and seeing that it still copies temp1.cmd to boring.cmd. Hint: You only need to 
  2499. add two characters!) 
  2500.  
  2501.  
  2502. ΓòÉΓòÉΓòÉ 4.7. WHERE TO GO FROM HERE ΓòÉΓòÉΓòÉ
  2503.  
  2504. If you're serious about REXX, I highly recommend that you get Michael F. 
  2505. Cowlishaw's The REXX Language. TRL is the standard book that defines REXX; it's 
  2506. like "K&R" is to C. I found the book to be a joy to read because Cowlishaw 
  2507. explains much of the why behind the features of REXX, and because he has a good 
  2508. sense of humor that he never uses to put down other computer languages (or the 
  2509. people who program in them). My only complaint about the book is the price; 
  2510. does Prentice-Hall really have to charge $38 for a 200-page paperback? 
  2511.  
  2512. The full title is The REXX Language: A Practical Approach to Programming, 
  2513. Second Edition. It's published by Prentice Hall, and the ISBN number is 
  2514. 0-13-780651-5. 
  2515.  
  2516. Another book I found quite helpful is Charles Daney's Programming in REXX, 
  2517. published by McGraw-Hill, Inc. and with ISBN 0-07-015305-1. Though not as 
  2518. concise (and sometimes not as clear) as TRL, it provides many interesting 
  2519. sample programs and a thorough discussion of various time-saving REXX tips and 
  2520. tricks. I really liked the discussion on writing filters in REXX (page 187 on). 
  2521. Daney's book is $44.95. 
  2522.  
  2523. There are several newsgroups and mailing lists that include much useful 
  2524. information. If you have access to the Internet, I highly recommend that you 
  2525. check out the comp.lang.rexx newsgroup. The people on c.l.r are among the 
  2526. friendliest I've "met" on the Internet. For matters specific to OS/2 REXX, it's 
  2527. also worth reading comp.os.os2.misc and comp.os.os2.programmer. If you have 
  2528. access to BITNet, check out the REXXLIST discussion list. 
  2529.  
  2530. Finally, comp.lang.rexx has a FAQ maintained by Eric Giguerre. You can obtain 
  2531. it as the file rexxfaq in the pub/ directory on the rexx.uwaterloo.ca ftp site. 
  2532. This FAQ includes a bibliography of REXX books, detailed information on the 
  2533. BITnet lists, ftp sites for REXX-related information, and much more. 
  2534.  
  2535. Raja Thiagarajan / sthiagar@bronze.ucs.indiana.edu / 6-6-93 
  2536.  
  2537.  
  2538. ΓòÉΓòÉΓòÉ 5. REXXUTIL Information and Samples ΓòÉΓòÉΓòÉ
  2539.  
  2540. The following attempts to better explain some of the powerful features provided 
  2541. by OS/2 V2's dynamic link library; REXXUTIL.DLL (Rexx utility functions). 
  2542. REXXUTIL functions are described in the online 'REXX Information' reference and 
  2543. the 'OS/2 2.0 Technical Library Procedures Language/2 REXX Reference' 
  2544. publication (order number S10G-6268). The information following is intended to 
  2545. provide a more detailed description of some of the functions. 
  2546.  
  2547.  
  2548. Michael Lamb MIKELAMB(KGNVMC)         Michael Lamb
  2549. Workstation Technical Support         4 Cross Creek Rd
  2550. ISSC - MHV Solution Center            New Paltz, NY 12561-3805
  2551. 30NC/370 Neighborhood Rd
  2552. Kingston NY 12401
  2553. (914)385-0666 t/l-695-0666
  2554.  
  2555.  
  2556. ΓòÉΓòÉΓòÉ 5.1. Plans for this information ΓòÉΓòÉΓòÉ
  2557.  
  2558. Much of this file has changed since the first few attempts at compiling useful 
  2559. REXXUTIL information. Plans are to place this information out on an IBM 
  2560. Internal FORUM, (REXXOS2 FORUM) and the OS2REXX CFORUM which makes its way out 
  2561. into the external customer world. Hopefully within a month or so of making it 
  2562. available I've received any corrections/omissions from both IBMer's and 
  2563. customers. Thereafter I plan to create an OS2EWS package that will contain this 
  2564. text information with the sample CMD files as separate files. Also I plan on 
  2565. including an INF formatted file of the information. I really do want the 
  2566. information to be as accurate as possible before creating the INF file so 
  2567. please report to me any items of omission or error. 
  2568.  
  2569.  
  2570. ΓòÉΓòÉΓòÉ 5.2. Publications ΓòÉΓòÉΓòÉ
  2571.  
  2572. One should realize that many of the functions provided by REXXUTIL have origins 
  2573. with Presentation Manager Winxxx calls. These publications are helpful and be 
  2574. reviewed for more information: 
  2575.  
  2576.  
  2577. S10G-6265 OS/2 PM Programming Reference Vol - 2
  2578.           Contains all the Winxxx calls, the Workplace Shell classes, and
  2579.           their _wpxxx messages. Also this is available as an online doc
  2580.           that comes with the OS/2 Toolkit.
  2581. S10G-6309 OS/2 System Object Model Reference
  2582.           Also an online doc that comes with the OS/2 Toolkit.
  2583. GBOF-2254 OS/2 Technical Redbooks (series of technical documents)
  2584.           GG24-3732 OS/2 V2 Volume 3: Presentation Manager & WPS
  2585.           GG24-3774 OS/2 V2 Volume 4: Application Development
  2586. ZB35-5100 The REXX Language: A Practical Approach to Programming,
  2587.           ISBN 0-13-780651-5
  2588.  
  2589.  
  2590. ΓòÉΓòÉΓòÉ 5.3. Some of the functions used/explained herein ΓòÉΓòÉΓòÉ
  2591.  
  2592.  SysIni:   Using REXXUTIL's SysIni function one can modify many settings of the 
  2593.            WorkPlace Shell as well as change other applications settings that 
  2594.            make use of *.INI files such as the system OS2.INI and OS2SYS.INI. 
  2595.  
  2596.  SysCreateObject: (PM WinCreateObject - Create Workplace Object) Using 
  2597.            REXXUTIL's SysCreateObject function one can create various objects; 
  2598.            like folders, programs, and shadow objects using Rexx. This section 
  2599.            for the most part includes parameter information which was gathered 
  2600.            together from various sources of information. 
  2601.  
  2602.  SysSetObjectData: (PM WinSetObjectData - Set Object Data) Using REXXUTIL's 
  2603.            SysSetObjectData function one can change an objects characteristics 
  2604.            (of an already created object, if you know its objectid). 
  2605.  
  2606.  SysDestroyObject: (PM WinDestroyObject - Destroy Workplace Object) Using 
  2607.            REXXUTIL's SysDestroyObject one can delete an object created if you 
  2608.            know its objectid. 
  2609.  
  2610.  
  2611. ΓòÉΓòÉΓòÉ 5.4. Misc Notes ΓòÉΓòÉΓòÉ
  2612.  
  2613. If one views the *.RC files located in your bootdrive:\OS2 directory you can 
  2614. learn a lot about the various INI settings and folder structure. Review INI.RC 
  2615. and INISYS.RC files, they are used to create your OS2.INI and OS2SYS.INI files. 
  2616. (Note in the *.RC files "?:" is used to indicate the boot drive) 
  2617.  
  2618. Some of REXXUTIL's functions are only available when using the very latest 
  2619. REXX20 PACKAGE which consists of the very latest REXX fixes and enhancements 
  2620. for GA OS/2 V2.0. Should you have problems running any of the sample programs 
  2621. you should make sure your system has the vary latest REXX20 updates. In 
  2622. addition to the REXX fixes, various OS/2 V2 base fixes may be needed as well. 
  2623. You may need to install/apply the latest 2.0 Service Pack, or even OS/2 2.1 in 
  2624. order for some of the operations to behave properly. 
  2625.  
  2626. If anyone discovers other parameters or other "hidden" features of any of the 
  2627. functions discussed, please share your discovery. I'll try to update the 
  2628. information as I receive it. 
  2629.  
  2630. Thanks...
  2631.  
  2632.  
  2633. Michael Lamb MIKELAMB(KGNVMC)         Michael Lamb
  2634. Workstation Technical Support         4 Cross Creek Rd
  2635. ISSC - MHV Solution Center            New Paltz, NY 12561-3805
  2636. 30NC/370 Neighborhood Rd
  2637. Kingston NY 12401
  2638. (914)385-0666 t/l-695-0666
  2639.  
  2640.  
  2641. ΓòÉΓòÉΓòÉ 5.5. Change Log ΓòÉΓòÉΓòÉ
  2642.  
  2643.  
  2644.   04/30/92 - Added information about DuplicateFlag parm
  2645.            - Added more setup string information from manuals
  2646.   06/02/92 - Added information about breaking Title line character "^"
  2647.            - Added information about adding multiple DOS_DEVICE statements
  2648.            - Added code to SHADOW.CMD to make shadow object of a file
  2649.   !!NOTE!! - The REXXOS2 fixes are required to make some of
  2650.              the newer samples work properly.
  2651.   06/30/92 - Added information regarding two new REXXUTIL functions:
  2652.              SysSetObjectData and SysDestroyObject, also two new
  2653.              samples STARTDOS, BOOTDOS (Thanks to Rick McGuire)
  2654.   07/13/92 - Reorganized the way the material is presented. Also added more
  2655.              sample Rexx routines REBUILD, OBJCLASS and LPTADD, descriptions
  2656.              follow. Also changed parm CONCURRENTVIEW to CCVIEW (Thanks
  2657.              Dan Kehn, Felix Sawicki)
  2658.   07/15/92 - Updated entire document as I mistakenly truncated it at 80
  2659.              characters. Rewrote some sample Rexx routines so they do not
  2660.              extend beyond 80 characters. Also updated the SysSetObjectData
  2661.              description to show how can open an object (Thanks Rick). Added
  2662.              information about creating multi-line titles, carat works for
  2663.              two line titles but not more than 2.
  2664.              New samples, OBJECTID and FONTS included, descriptions follow.
  2665.   07/29/92 - Corrected an error I made when I broke the setup lines into
  2666.              multiple lines. I needed to add ]]'s to make sure they
  2667.              concatenated without spaces (Thanks Rick). Also added
  2668.              information regarding changing some System Settings (added
  2669.              new section after sample Rexx code). Also added warning
  2670.              in REBUILD.CMD sample about replacing Folder objects. Also
  2671.              added new sample ICONRES.CMD which builds a folder containing
  2672.              many of the OS/2 V2 installed icons using system DLL files.
  2673.   01/30/93   Added to some examples the use of SysDestroyObject to clean up
  2674.              after creating objects, also added the syntax for the call.
  2675.              Changed REBUILD.CMD sample to used 'U' for updateifexists as
  2676.              the duplicateflag to prevent problems. Added warning about
  2677.              the 'R' duplicateflag parameter to field description.
  2678.              Added information about changing Background tab, Change color
  2679.              button values. Changed OBJECTID.CMD to enclose results in
  2680.              double quotes to easier distinguish results.
  2681.              Changed descriptions of calls to better match what's found in the
  2682.              toolkit documentation for the Winxxx calls.
  2683.   04/11/93   Added some information in ASSOCTYPE, ASSOCFILTER section.
  2684.              Added new PROGTYPE values. Added ICONVIEWPOS information.
  2685.   07/04/93   Too many changes to note. Lots having to do with OS/2 V2.1
  2686.  
  2687.  
  2688. ΓòÉΓòÉΓòÉ 5.6. REXXUTIL Functions ΓòÉΓòÉΓòÉ
  2689.  
  2690. This section contains information on the some of the functions of the REXXUTIL 
  2691. library that comes with OS/2 REXX. 
  2692.  
  2693.  
  2694. ΓòÉΓòÉΓòÉ 5.6.1. SysCreateObject ΓòÉΓòÉΓòÉ
  2695.  
  2696. Function: SysCreateObject
  2697. Syntax:
  2698. result=SysCreateObject(classname, title, location <,setup>, <,duplicateflag>)
  2699.  
  2700.  classname: The name of the class of which this object is a member.
  2701.  
  2702.  title:    The object title, as it is to appear when displayed on the user
  2703.            interface underneath an icon or on the title bar of an open object.
  2704.            (Note this can be changed later using the TITLE keyword)
  2705.  
  2706.  location: The object location. This can be specified as either an
  2707.            object ID (for example, <WP_DESKTOP>) or a file system path
  2708.            (for example, C:\bin\mytools).
  2709.            (Object ids will be explained later)
  2710.  
  2711.  setup:    A WinCreateObject setup string. Described more later on.
  2712.  
  2713.  duplicateflag: This parameter indicates what action should be taken
  2714.            when the Setup string specifies an object ID, and an object with
  2715.            that object ID already exists. If the setup string does not give
  2716.            an object ID, another object will be created.
  2717.  
  2718.  result:    The return code from WinCreateObject. This returns 1 (TRUE) if the
  2719.            object was created and 0 (FALSE) if the object was not created.
  2720.  
  2721.  Purpose:  Create a new instance of an object class.
  2722.  
  2723.  
  2724. ΓòÉΓòÉΓòÉ 5.6.2. SysSetObjectData ΓòÉΓòÉΓòÉ
  2725.  
  2726.  
  2727. Function: SysSetObjectData
  2728. Syntax:
  2729. result=SysSetObjectData(name, setup)
  2730.  
  2731.  name:     The object name. This can be specified as an object id (for
  2732.            example <WP_DESKTOP>) or as a fully qualified file name.
  2733.  
  2734.  setup:    A WinCreateObject setup string. Described more later on.
  2735.  
  2736.  result:   The return code from WinSetObjectData. This will return 1 (TRUE)
  2737.            if the object was updated and 0 (FALSE) if the object was not
  2738.            updated.
  2739.  
  2740.  Purpose:  Alter the settings of an existing object.
  2741.  
  2742.            Can be used to open an instance of an object:
  2743.            /* open up the system folder */
  2744.            call SysSetObjectData '<WP_OS2SYS>', 'OPEN=DEFAULT;'
  2745.  
  2746.            Can be used to change the title of an object:
  2747.            /* change Information folder name */
  2748.            call SysSetObjectData '<WP_INFO>', 'TITLE=InfoFolder'
  2749.  
  2750. See the description of the SysCreateObject location and setup strings following 
  2751. for an explanation of the parameters. 
  2752.  
  2753.  
  2754. ΓòÉΓòÉΓòÉ 5.6.3. SysDestroyObject ΓòÉΓòÉΓòÉ
  2755.  
  2756. Function: SysDestroyObject
  2757. Syntax:
  2758. result=SysDestroyObject(name)
  2759.  
  2760.  name:     The object name. This should be specified as an object id, for
  2761.            example <WP_CMDREF>. It can also be a fully specified file name.
  2762.  
  2763.  result:   The return code from WinDestroyData. This will return 1 (TRUE)
  2764.            if the object was destroyed and 0 (FALSE) if the object was
  2765.            not destroyed.
  2766.  
  2767.  Purpose:  Delete an existing workplace object, or file.
  2768.  
  2769. See the description of the SysCreateObject location parameter following for an 
  2770. explanation of the object name. See the OBJECTID.CMD sample for a way to 
  2771. determine the objectid's the system knows about. 
  2772.  
  2773.  
  2774. ΓòÉΓòÉΓòÉ 5.6.4. Parameters Explained ΓòÉΓòÉΓòÉ
  2775.  
  2776. Parameters to the functions are now explained in more detail. 
  2777.  
  2778.  
  2779. ΓòÉΓòÉΓòÉ 5.6.4.1. classname ΓòÉΓòÉΓòÉ
  2780.  
  2781. A registered object class defined to the system. Of particular interest are the 
  2782. WPFolder/WPProgram/WPShadow classes. Note using the sample Rexx code included 
  2783. in the SysQueryClassList function help screen one can list all of the 
  2784. registered classes: 
  2785.  
  2786.  
  2787.   call SysQueryClassList "list."
  2788.   do i = 1 to list.0
  2789.      say 'Class' i 'is' list.i
  2790.   end
  2791.  
  2792.  
  2793. ΓòÉΓòÉΓòÉ 5.6.4.2. title ΓòÉΓòÉΓòÉ
  2794.  
  2795. The objects title you want to use. If you wish to break the title line you use 
  2796. a comma "," as the line break character. However, there were problems with this 
  2797. and it may or may not work depending on whether you have the latest REXX and 
  2798. OS/2 V2 fixes installed. You may instead decide to use a hex 0A character 
  2799. (line-feed) in the string to separate lines. 
  2800.  
  2801. Rexx example: Note: x2c is Rexx's hex to character function. 
  2802.  
  2803.  
  2804.   title='First'x2c(A)'Second'x2c(A)'Third'
  2805.  
  2806. Note if you wish to use the special characters; comma or semi-colon in the 
  2807. string, prefix the character with the carat symbol. 
  2808.  
  2809. Example title, you want: 
  2810.  
  2811.  
  2812.   ] My Activities     ]   you would use...
  2813.   ] December 25, 1992 ]     title='My Activities,December 25^,1992'
  2814.  
  2815.  
  2816. ΓòÉΓòÉΓòÉ 5.6.4.3. location ΓòÉΓòÉΓòÉ
  2817.  
  2818. The object's location can be specified as either an existing object id, for 
  2819. example <WP_DESKTOP>, or alternatively a fully qualified file name of any file 
  2820. or directory. 
  2821.  
  2822. An object id string must always start with the '<' character and be terminated 
  2823. by the '>' character and is thus an invalid file system name. 
  2824.  
  2825. By looking at your \OS2\INI.RC file you can see a use of many object ids such 
  2826. as <WP_DESKTOP>. If this is used as a location then your object will be placed 
  2827. on the WorkPlace Shell desktop. 
  2828.  
  2829. If you are creating an object you should make sure you use the OBJECTID setup 
  2830. string parameter and give that object a unique object id. We'll see how this 
  2831. works later. 
  2832.  
  2833. HINTS: Here are some predefined object ids of system folders. Also if you are 
  2834. thinking of placing an object in the Startup Folder <WP_START>, make it a 
  2835. shadow of an object. 
  2836.  
  2837.  
  2838.          <WP_DESKTOP>   Desktop
  2839.          <WP_START>     Startup folder
  2840.          <WP_OS2SYS>    OS/2 System folder
  2841.          <WP_TEMPS>     Templates folder
  2842.          <WP_CONFIG>    System Setup folder
  2843.          <WP_INFO>      Information folder
  2844.          <WP_DRIVES>    Drives folder
  2845.          <WP_NOWHERE>   Hidden folder
  2846.          <WP_PROMPTS>   Command Prompts folder
  2847.          <WP_TOOLS>     Productivity folder
  2848.          <WP_GAMES>     Games folder
  2849.  
  2850. Some other common OS/2 folder objectids: 
  2851.  
  2852.  
  2853.          <MAH_FOLDER>   Mahjongg folder
  2854.          <MMPM2_FOLDER> Multimedia folder
  2855.          <MMPM2_SOUNDS> Multimedia Sound Bites folder
  2856.          <MMPM2_MOVIES> Multimedia Movies folder
  2857.          <TK_TOOLKIT>   Toolkit 2.1 folder
  2858.          <TK_DEVINFO>   Toolkit Information folder
  2859.          <TK_DEVTOOLS>  Development Tools folder
  2860.          <TK_CSAMPLE>   Sample Programs folder
  2861.  
  2862.  
  2863. ΓòÉΓòÉΓòÉ 5.6.4.4. setup ΓòÉΓòÉΓòÉ
  2864.  
  2865. This field needs the most explaining. Each object class, WPProgram, WPFolder, 
  2866. etc, documents its setup string keynames and parameters. A larger section 
  2867. follows that details many of the available keynames and parameters. The setup 
  2868. string contains a series of "keyname=value" pairs, that change the behavior of 
  2869. the object. "keynames" are separated by semicolons, and "values" are separated 
  2870. by commas. 
  2871.  
  2872.  
  2873.     "key=value;key2=value1,value2;"
  2874.  
  2875. If you want a literal comma or semicolon inside one of your fields you must 
  2876. precede the comma/semi-colon with a carat as in the following: 
  2877.  
  2878.  
  2879.       ^,   A literal comma
  2880.       ^;   A literal semicolon
  2881.  
  2882. Note that ALL setup string parameters have safe defaults, so it is never 
  2883. necessary to pass unnecessary parameters to an object. 
  2884.  
  2885. (Note: The setup string was limited to a total length of 255 bytes in the 2.0 
  2886. GA code, this limitation is removed if the Service Pack is applied or you are 
  2887. using OS/2 2.1) (APAR PJ02271) 
  2888.  
  2889.  
  2890. ΓòÉΓòÉΓòÉ 5.6.4.5. duplicateflag ΓòÉΓòÉΓòÉ
  2891.  
  2892. There are three possible values for this parameter: 
  2893.  
  2894.   FailIfExists  No object should be created if an object with the given object 
  2895.            already exists. This is the default and maps to the PM creation 
  2896.            flag, CO_FAILIFEXISTS 
  2897.  
  2898.  UpdateIfExists If an object with the given object ID already exists, the 
  2899.            existing object will be updated with the new setting information. 
  2900.            Maps to the creation flag, CO_UPDATEIFEXISTS. If the object does not 
  2901.            exist, it is created. 
  2902.  
  2903.  ReplaceIfExists  If an object with the given object ID already exists, the 
  2904.            existing object should be replaced. Maps to the PM creation flag, CO_REPLACEIFEXISTS.
  2905.  
  2906.             WARNING: Be careful using the 'R' ReplaceIfExists value. Any 
  2907.            attempt to rebuild an object first deletes any object that is using 
  2908.            that same <objectid>. This can be useful if you want to restore an 
  2909.            object back to its original installed state. This can also be bad 
  2910.            since if you rebuild a folder it first deletes all objects in it 
  2911.            since those objects are tied to the folder object. 
  2912.  Note: Only the first character is required/examined, i.e. F, R, or U 
  2913.  
  2914.  
  2915. ΓòÉΓòÉΓòÉ 5.6.5. Setup Strings ΓòÉΓòÉΓòÉ
  2916.  
  2917. Using WPFolder and WPProgram classes in your SysCreateObject call you can build 
  2918. folder and program objects. What follows are setup string parameters. Their 
  2919. various key names, values, and a short description follow each item. 
  2920.  
  2921. An instance of each class is created initially by the system in its template 
  2922. form. It has the title "Folder" / "Program", respectively, and resides in the 
  2923. systems "Templates" folder. 
  2924.  
  2925.  
  2926. ΓòÉΓòÉΓòÉ 5.6.5.1. WPFolder setup string parms ΓòÉΓòÉΓòÉ
  2927.  
  2928.  
  2929. ΓòÉΓòÉΓòÉ 5.6.5.1.1. View ΓòÉΓòÉΓòÉ
  2930.  
  2931.  
  2932. KEYNAME      VALUE           Description
  2933. -----------------------------------------------------------------------------
  2934. OPEN         ICON            Open icon view when object is created/updated.
  2935.              TREE            Open tree view when object is created/updated.
  2936.              DETAILS         Open details view when object is created/updated.
  2937.            Example:
  2938.              /* Open up the tree view of the system folder */
  2939.              call SysSetObjectData '<WP_OS2SYS>', 'OPEN=TREE;'
  2940. ICONVIEW     s1[,s2,...sn]   Set icon view to specified style(s).
  2941. TREEVIEW     s1[,s2,...sn]   Set tree view to specified style(s).
  2942. DETAILSVIEW  s1[,s2,...sn]   Set details view to specified style(s).
  2943. (styles)     FLOWED          flowed list items
  2944.              NONFLOWED       non-flowed list items
  2945.              NONGRID         non-gridded icon view
  2946.              NORMAL          normal size icons
  2947.              MINI            small icons
  2948.              INVISIBLE       no icons
  2949.              LINES           lines in tree view
  2950.              NOLINES         no lines in tree view
  2951. ICONFONT     value           Font size and facename. See Font Notes following.
  2952. TREEFONT     value           Font size and facename. See Font Notes following
  2953. DETAILSFONT  value           Font size and facename. See Font Notes following
  2954.  
  2955. Font Notes: The format for the value is normally; size.facename fontstyle hex0 
  2956.  
  2957.  
  2958.   example:   8.Courier Bold
  2959.  
  2960.  Remember the value should end with null zero. Example code to change the 
  2961. Information Folder icon view font: 
  2962.  
  2963.  
  2964.     call SysSetObjectData '<WP_INFO>', 'ICONFONT=8.Courier Bold'x2c(0)
  2965.  
  2966. We say 'normally' because there are certain circumstances where you must 
  2967. separate values using a period. Also if you use a font style of 'Normal' you 
  2968. just leave off the font style (don't use the word 'Normal') Following is a 
  2969. small table to help. 
  2970.  
  2971.  
  2972. FaceName: Courier FontStyle: Normal
  2973.   'ICONFONT=8.Courier'x2c(0)
  2974. FaceName: Courier FontStyle: Bold Italic
  2975.   'TREEFONT=8.Courier Bold Italic'x2c(0)
  2976. 10 FaceName: System Proportional FontStyle: Bold
  2977.   'DETAILSFONT=10.System Proportional.Bold'x2c(0)
  2978.  
  2979. HINT: To find out what the string should look like, create a folder, name it 
  2980. simple like MYFOLD, then manually change the font size/name using the 
  2981. Open/Settings/Change font button. Close the settings, then from an OS/2 command 
  2982. line first determine the name of your desktop, for a typical 2.0 FAT file 
  2983. system it would be something like C:\OS!2_2.0_D (It gets easier for 2.1 where 
  2984. the Desktop is normally named C:\DESKTOP) Then locate the folder you created 
  2985. C:\OS!2_2.0_D\MYFOLD Then enter: EAUTIL C:\OS!2_2.0_D\MYFOLD MYFOLD.EAS /S /P 
  2986. This will create a MYFOLD.EAS file, use a browse program to view this file and 
  2987. you'll see the values required. 
  2988.  
  2989.  
  2990. ΓòÉΓòÉΓòÉ 5.6.5.1.2. Background ΓòÉΓòÉΓòÉ
  2991.  
  2992.  
  2993. KEYNAME      VALUE           Description
  2994. -----------------------------------------------------------------------------
  2995. BACKGROUND   filename        Sets the folder background. filename is the
  2996.                              name of a file in the \OS2\BITMAP directory
  2997.                              of the boot drive.
  2998.  
  2999.  
  3000. ΓòÉΓòÉΓòÉ 5.6.5.1.3. File ΓòÉΓòÉΓòÉ
  3001.  
  3002.  
  3003. KEYNAME      VALUE           Description
  3004. -----------------------------------------------------------------------------
  3005. WORKAREA     YES             Make the folder a Workarea folder
  3006.              NO
  3007.  
  3008.  
  3009. ΓòÉΓòÉΓòÉ 5.6.5.1.4. Window ΓòÉΓòÉΓòÉ
  3010.  
  3011.  
  3012. KEYNAME      VALUE           Description
  3013. -----------------------------------------------------------------------------
  3014. HIDEBUTTON   YES             Views of this object will have a hide button
  3015.                              as opposed to a minimize button.
  3016.              NO              Views of this object will have a minimize button
  3017.                              as opposed to a hide button.
  3018. MINWIN       HIDE            Views of this object will hide when their
  3019.                              minimize button is selected.
  3020.              VIEWER          Views of this object will minimize to the
  3021.                              minimized window viewer when their minimize
  3022.                              button is selected.
  3023.              DESKTOP         Views of this object will minimize to the
  3024.                              Desktop when their minimize button is selected.
  3025. CCVIEW       YES             New views of this object will be created every
  3026.                              time the user selects open.
  3027.              NO              Open views of this object will resurface when
  3028.                              the user selects open.
  3029.  
  3030.  
  3031. ΓòÉΓòÉΓòÉ 5.6.5.2. WPProgram setup string parms ΓòÉΓòÉΓòÉ
  3032.  
  3033.  
  3034. ΓòÉΓòÉΓòÉ 5.6.5.2.1. Program ΓòÉΓòÉΓòÉ
  3035.  
  3036.  
  3037. KEYNAME      VALUE           Description
  3038. -----------------------------------------------------------------------------
  3039. EXENAME      filename        Sets the name of the program
  3040. PARAMETERS   params          Sets the parameters list, which may
  3041.                              include substitution characters
  3042.                              ---Substitution characters---
  3043.                              Special substitution parameters are allowed:
  3044.                              [ ]     :(bracket blank bracket) You are prompted
  3045.                                       to type any parameters you want to use.
  3046.                              [text]  :Characters placed inside of the brackets
  3047.                                       are displayed as the prompt string.
  3048.                              no parm :If the program object is started by
  3049.                                       clicking on it no parameters are passed.
  3050.                                       If you start the program object by
  3051.                                       dragging a file over it, the full
  3052.                                       filename is passed.
  3053.                              %       :No parameters are passed. Useful for
  3054.                                       program objects you may want to start
  3055.                                       from a folders pop-up menu.
  3056.                              %*      :Like passing no parms, but useful if you
  3057.                                       need to insert the filename of a dragged
  3058.                                       object somewhere other than at the end
  3059.                                       of the parameter list.
  3060.                              %**P    :Insert drive and path information without
  3061.                                       the last backslash (\).
  3062.                              %**D    :Insert drive with ':' or UNC name.
  3063.                              %**N    :Insert file name without extension.
  3064.                              %**F    :Insert file name with extension.
  3065.                              %**E    :Insert extension without leading dot. In
  3066.                                       HPFS, the extension always comes after
  3067.                                       the last dot.
  3068.                              REMEMBER: If you specify a parameter in the field
  3069.                                        the name of any file being dragged onto
  3070.                                        this object is added to the end of the
  3071.                                        parameter list.
  3072. STARTUPDIR   pathname        Sets the working directory
  3073.  
  3074.  
  3075. ΓòÉΓòÉΓòÉ 5.6.5.2.2. Sessions ΓòÉΓòÉΓòÉ
  3076.  
  3077.  
  3078. KEYNAME      VALUE           Description
  3079. -----------------------------------------------------------------------------
  3080. PROGTYPE     OS/2 session values:
  3081.              PM              Sets the session type to PM
  3082.              FULLSCREEN      Sets the session type to OS/2 full screen
  3083.              WINDOWABLEVIO   Sets the session type to OS/2 windowed
  3084.              DOS session values:
  3085.              VDM             Sets the session type to DOS full screen
  3086.              WINDOWEDVDM     Sets the session type to DOS windowed
  3087.              WIN-OS/2 session values:
  3088.              WIN             WIN-OS2 full screen
  3089.              WINDOWEDWIN     WIN-OS2 windowed, NOT a separate VDM session
  3090.              SEPARATEWIN     WIN-OS2 windowed, Separate VDM session
  3091.              -- Values for OS/2 2.1 systems --
  3092.              PROG_31_STD     WIN-OS2 full screen, Windows 3.1 Standard mode.
  3093.              PROG_31_STDSEAMLESSVDM
  3094.                              WIN-OS2 windowed, Separate VDM session,
  3095.                              3.1 Standard mode
  3096.              PROG_31_STDSEAMLESSCOMMON
  3097.                              WIN-OS2 windowed, NOT a separate VDM session,
  3098.                              3.1 Standard mode
  3099.              PROG_31_ENH     WIN-OS/2 full screen, NOT a separate VDM session,
  3100.                              3.1 Enhanced Compatibility
  3101.              PROG_31_ENHSEAMLESSVDM
  3102.                              WIN-OS2 windowed, Separate VDM session,
  3103.                              3.1 Enhanced Compatibility
  3104.              PROG_31_ENHSEAMLESSCOMMON
  3105.                              WIN-OS2 windowed, NOT a separate VDM session,
  3106.                              3.1 Enhanced Compatibility
  3107. MINIMIZED    YES             Start program minimized
  3108. MAXIMIZED    YES             Start program maximized
  3109. NOAUTOCLOSE  YES             Leaves the window open upon program termination.
  3110.              NO              Closes the window when the program terminates.
  3111. SET          XXX=VVV         XXX is any environment variable. VVV sets the
  3112.                              value of the environment variable. When used will
  3113.                              wipe out many variables you may have assumed were
  3114.                              set. Check environment space closely when using.
  3115.                              Also used to specify DOS settings for DOS and
  3116.                              Windows programs. --See next section--
  3117.  
  3118.  
  3119. ΓòÉΓòÉΓòÉ 5.6.5.2.3. DOS and WIN-OS2 Settings ΓòÉΓòÉΓòÉ
  3120.  
  3121. IMPORTANT NOTES: 
  3122.  
  3123.    1. To change these values you use SET keyname= 
  3124.  
  3125.               Example:   SET DOS_FILES=45;SET DOS_HIGH=1;
  3126.               Also for some use values of 1 for On, 0 for off
  3127.               Example:   SET COM_HOLD=1;     (on, default is off)
  3128.  
  3129.    2. To add more than one line to a setting you can use the same technique 
  3130.       used to have more than one title line. See the discussion previous 
  3131.       regarding that technique. Here's an example using the DOS_DEVICE keyname: 
  3132.  
  3133.  
  3134.             setup='...SET DOS_DEVICE=C:\OS2\MDOS\ANSI.SYS'x2c(A)'C:\OS2\MDOS\EGA.SYS...'
  3135.  
  3136.    3. Some settings may already have default values, like DOS_VERSION. You must 
  3137.       be careful since any action against that setting is treated as a 
  3138.       replacement (even if you are using the updateifexist duplicateflag 
  3139.       value). So if you wanted to add one item to DOS_VERSION, you should also 
  3140.       include all of the existing values. 
  3141.  
  3142.    4. Some settings are new once you've installed the OS/2 V2 Service Pack or 
  3143.       upgraded to OS/2 V2.1. As well some may not be on your workstation due to 
  3144.       your hardware configuration, for instance use of VIDEO_8514A_XGA_IOTRAP 
  3145.       is only available on certain systems. 
  3146.  
  3147.    5. WIN-OS2 Settings are new to V2 users and appear once the Service Pack is 
  3148.       installed or you have upgraded to OS/2 V2.1. Refer to the section "Global 
  3149.       WIN-OS2 Settings" for more information. 
  3150.  
  3151.  List of DOS and WIN-OS2 Setting fields 
  3152.  
  3153.  
  3154.   -----------------------------------------------------------------------------
  3155.   Keyname                   Values and notes about usage
  3156.                             (<>'s are used to signify default setting for some)
  3157.                             (Remember 1=on and 0=off for those that us on/off)
  3158.   -----------------------------------------------------------------------------
  3159.   WIN_RUNMODE               Use the PROGTYPE parameter mentioned previously
  3160.                             to define a enhanced mode WIN-OS2 program (Also
  3161.                             see note 5 from above)
  3162.   WIN_DDE                   (See note 5 above)
  3163.   WIN_CLIPBOARD             (See note 5 above)
  3164.   AUDIO_ADAPTER_SHARING     On Off
  3165.   COM_DIRECT_ACCESS         On <Off>
  3166.   COM_HOLD                  On <Off>
  3167.   COM_RECEIVE_BUFFER_FLUSH  Valid settings: <NONE>
  3168.                                              ALL
  3169.                                              RECEIVE DATA INTERRUPT ENABLE
  3170.                                              SWITCH TO FOREGROUND
  3171.   COM_SELECT                Valid settings: <ALL> COM1 COM2 COM3 COM4 NONE
  3172.   DOS_AUTOEXEC              C:\AUTOEXEC.BAT
  3173.                             Use full BATch filename also you can pass parameters
  3174.   DOS_BACKGROUND_EXECUTION  <On> Off
  3175.   DOS_BREAK                 On <Off>
  3176.   DOS_DEVICE                Default: empty
  3177.                             Remember to separate any used with "," for newline
  3178.   DOS_FCBS                  Limits: 0-255, default 16
  3179.   DOS_FCBS_KEEP             Limits: 0-255, default 8
  3180.   DOS_FILES                 Limits: 20-255, default 20
  3181.   DOS_HIGH                  On <Off>
  3182.   DOS_LASTDRIVE             Limits: last physical drive to Z, default Z
  3183.   DOS_RMSIZE                Limits: 128-640, default 640, increments of 16
  3184.   DOS_SHELL                 Default: "?:\OS2\MDOS\COMMAND.COM "
  3185.                                      "?:\OS2\MDOS\ /P" where ?
  3186.                                       is the boot drive
  3187.   DOS_STARTUP_DRIVE         Default: empty
  3188.                             Accepts text; like A: or C:\DISKS\DRDOS.IMG
  3189.   DOS_UMB                   On <Off>
  3190.   DOS_VERSION               Default: DCJSS02.EXE,3,40,255
  3191.                                      DFIA0MOD.SYS,3,40,255
  3192.                                      DXMA0MOD.SYS,3,40,255
  3193.                                      IBMCACHE.COM,3,40,255
  3194.                                      IBMCACHE.SYS,3,40,255
  3195.                                      ISAM.EXE,3,40,255
  3196.                                      ISAM2.EXE,3,40,255
  3197.                                      ISQL.EXE,3,40,255
  3198.                                      NET3.COM,3,40,255
  3199.                                      EXCEL.EXE,10,10,4
  3200.                                      PSCPG.COM,3,40,255
  3201.                                      SAF.EXE,3,40,255
  3202.                                      WIN200.BIN,10,10,4
  3203.                             Remember what you put here will replace the existing
  3204.                             list of items so be careful, also remember to use
  3205.                             carats in front of any commas you need.
  3206.                             Example:
  3207.                             'SET DOS_VERSION=IBMCACHE.SYS^,3^,40^,255;']],...
  3208.   DPMI_DOS_API              Valid settings: <AUTO>  ENABLED  DISABLED
  3209.   DPMI_MEMORY_LIMIT         Limits: 0-512, default 4
  3210.   DPMI_NETWORK_BUFF_SIZE    Limits: 1-64, default 8
  3211.   EMS_FRAME_LOCATION        Valid settings: <AUTO> NONE C000 C400 C800 CC00
  3212.                                                         D000 D400 D800 DC00
  3213.                                                         8000 8400 8800 8C00 9000
  3214.   EMS_HIGH_OS_MAP_REGION    Limits: 0-96, default 32, note increments of 16
  3215.   EMS_LOW_OS_MAP_REGION     Limits: 0-576, default 384, note increments of 16
  3216.   EMS_MEMORY_LIMIT          Limits: 0-32768, default 2048, note increments of 16
  3217.   HW_NOSOUND                On <Off>
  3218.   HW_ROM_TO_RAM             On <Off>
  3219.   HW_TIMER                  On <Off>
  3220.   IDLE_SECONDS              Limits: 0-60, default 0
  3221.   IDLE_SENSITIVITY          Limits: 1-100, default 75
  3222.   INT_DURING_IO             On <Off>
  3223.   KBD_ALTHOME_BYPASS        On <Off>
  3224.   KBD_BUFFER_EXTEND         <On> Off
  3225.   KBD_CTRL_BYPASS           Valid settings: <NONE>  ALT_ESC  CTRL_ESC
  3226.   KBD_RATE_LOCK             On <Off>
  3227.   MEM_EXCLUDE_REGIONS       Initially empty, you can specify a range of memory
  3228.                             to exclude or you can supply a singe address for the
  3229.                             beginning of a 4KB region, if you need several
  3230.                             regions separate them with a comma (don't forget to
  3231.                             use the carat since commas are special setup string
  3232.                             parameters) Example:
  3233.                             'SET MEM_EXCLUDE_REGIONS=C0000^,D0000-D8000;']],
  3234.   MEM_INCLUDE_REGIONS       Initially empty, you can specify a range of memory
  3235.                             to include or you can supply a singe address for the
  3236.                             beginning of a 4KB region, if you need several
  3237.                             regions separate them with a comma (don't forget to
  3238.                             use the carat since commas are special setup string
  3239.                             parameters) Example:
  3240.                             'SET MEM_INCLUDE_REGIONS=C0000^,D0000-D7FFF;']],
  3241.                             NOTE: The include region D0000-D80000 will include
  3242.                                   the entire memory between D8000 and D8FFFF.
  3243.   MOUSE_EXCLUSIVE_ACCESS    On <Off>
  3244.   NETWARE_RESOURCES         Valid settings: NONE  PRIVATE  GLOBAL
  3245.                             Special note, you use the words to change the value
  3246.                             BUT the string MUST be 7 characters long!
  3247.                             Example:
  3248.                             'SET NETWARE_RESOURCES=GLOBAL ;'
  3249.   PRINT_SEPARATE_OUTPUT     <On> Off
  3250.   PRINT_TIMEOUT             Limits: 0-3600, default 15
  3251.   TOUCH_EXCLUSIVE_ACCESS    On Off
  3252.   VIDEO_8514A_XGA_IOTRAP    <On> Off
  3253.   VIDEO_FASTPASTE           On <Off>
  3254.   VIDEO_MODE_RESTRICTION    Valid settings: <NONE>  CGA  MONO
  3255.                             Special note, you use the words to change the value
  3256.                             BUT the string MUST be 15 characters long!
  3257.                             Example:
  3258.                             'SET VIDEO_MODE_RESTRICTION=CGA            ;'
  3259.   VIDEO_ONDEMAND_MEMORY     <On> Off
  3260.   VIDEO_RETRACE_EMULATION   <On> Off
  3261.   VIDEO_ROM_EMULATION       <On> Off
  3262.   VIDEO_SWITCH_NOTIFICATION On <Off>
  3263.   VIDEO_WINDOW_REFRESH      Limits: 1-600, default 1
  3264.   XMS_HANDLES               Limits: 0-128, default 32
  3265.   XMS_MEMORY_LIMIT          Limits: 0-16384, default 2048, increment of 4
  3266.   XMS_MINIMUM_HMA           Limits: 0-63, default 0
  3267.  
  3268.  
  3269. ΓòÉΓòÉΓòÉ 5.6.5.2.4. Association ΓòÉΓòÉΓòÉ
  3270.  
  3271.  
  3272. KEYNAME      VALUE           Description
  3273. -----------------------------------------------------------------------------
  3274. ASSOCFILTER  filters         Sets the filename filter for files
  3275.                              associated to this program.
  3276.                              Multiple filters are separated by commas.
  3277.                              See notes about preserving existing filter
  3278.                              values following.
  3279. ASSOCTYPE    type            Sets the type of files associated to this
  3280.                              program. Multiple filters are separated
  3281.                              by commas.
  3282.                              See notes about preserving existing associate
  3283.                              types following.
  3284.  
  3285. Preserving existing values 
  3286.  
  3287.  When using ASSOCFILTER and/or ASSOCTYPE include two commas at the end of your 
  3288. string to preserve any settings that are already applied: 
  3289.  
  3290.  
  3291.   Example: ... ASSOCTYPE=Metafile,PIF file,,;ASSOCFILTER=*.MET,*.PIF,,; ...
  3292.  
  3293.  
  3294. ΓòÉΓòÉΓòÉ 5.6.5.2.5. Window ΓòÉΓòÉΓòÉ
  3295.  
  3296.  
  3297. KEYNAME      VALUE           Description
  3298. -----------------------------------------------------------------------------
  3299. MINWIN       HIDE            Views of this object will hide when their
  3300.                              minimize button is selected.
  3301.              VIEWER          Views of this object will minimize to the
  3302.                              minimized window viewer when their minimize
  3303.                              button is selected.
  3304.              DESKTOP         Views of this object will minimize to the
  3305.                              Desktop when their minimize button is selected.
  3306. CCVIEW       YES             New views of this object will be created every
  3307.                              time the user selects open.
  3308.              NO              Open views of this object will resurface when
  3309.                              the user selects open.
  3310.  
  3311.  
  3312. ΓòÉΓòÉΓòÉ 5.6.5.3. General and Miscellaneous ΓòÉΓòÉΓòÉ
  3313.  
  3314. NOTE: Some keynames are valid for any objects. Here in this section many of 
  3315. them are described. These can be used for the WPFolder and WPProgram objects. 
  3316.  
  3317.  
  3318. KEYNAME      VALUE           Description
  3319. -----------------------------------------------------------------------------
  3320. ICONFILE     filename        This sets the object's icon.
  3321. ICONRESOURCE id,module       This sets the object's icon. 'id' is the
  3322.                              identity of an icon resource in the 'module'
  3323.                              dynamic link library (DLL). For example:
  3324.                              ICONRESOURCE=73 PMWP;
  3325.                              This would indicate resource 73 in PMWP.DLL.
  3326.                              See a supplied sample command file for more info.
  3327. ICONPOS      x,y             This sets the object's initial icon position.
  3328.                              The x and y values represent the position in
  3329.                              the object's folder in percentage coordinates.
  3330. ICONVIEWPOS  w,x,y,z         This sets the object's initial size. The values
  3331.                              represent relative position in percentage
  3332.                              coordinates. For example: ICONPOS=25 25 50 50
  3333.                              Would create a folder whose bottom left corner is
  3334.                              25% from the left and 25% from the bottom and half
  3335.                              the screen width/height.
  3336. TEMPLATE     YES             Creates object as a template.
  3337.              NO              Resets objects template property.
  3338. TITLE        value           Can be used to assign a name/title to an object.
  3339. OBJECTID     <name>          This sets the object's identity. The object
  3340.                              id will stay with the object even if it is
  3341.                              moved or renamed. An object id is any unique
  3342.                              string preceded with a '<' and terminated
  3343.                              with a '>'. This may also be a real name
  3344.                              specified as a fully qualified path name.
  3345.                              IMPORTANT: For any object you create you should
  3346.                              use a unique objectid! Do this for two reasons:
  3347.                              1) If you use an objectid it signifies a unique
  3348.                                 object that will not be recreated if you use
  3349.                                 the "FailIfExists" flag in your Rexx call. Not
  3350.                                 using an objectid would cause multiple objects
  3351.                                 to be created if the same program was run
  3352.                                 over and over.
  3353.                              2) Should you need to later delete it or change
  3354.                                 your object, you can use this objectid in your
  3355.                                 Rexx call to refer to it.
  3356.                              Also one should not use an objectid that starts
  3357.                              with "WP_" as many OS/2 objects use those,
  3358.                              consider those reserved characters.
  3359. HELPPANEL    id              This sets the object's default help panel.
  3360. HELPLIBRARY  filename        This sets the help library.
  3361. OPEN         SETTINGS        Open settings view of object when created/updated.
  3362.              DEFAULT         Open default view of object when created/updated.
  3363.                              Don't forget for folder objects you can use
  3364.                              OPEN with these values: ICON, TREE, DETAILS
  3365. NODELETE     YES             Will not allow you to delete the object.
  3366.              NO              Resets the object's no delete property.
  3367. NOCOPY       YES             Will not allow you to make a copy.
  3368.              NO              Resets the object's no copy property.
  3369. NOMOVE       YES             Will not allow you to move the object to another
  3370.                              folder, will create shadow on a move.
  3371.              NO              Resets the object's no move property.
  3372. NODRAG       YES             Will not allow you to drag the object.
  3373.              NO              Resets the object's no drag property.
  3374. NOLINK       YES             Will not allow you to create a shadow link.
  3375.              NO              Resets the object's no link property.
  3376. NOSHADOW     YES             Will not allow you to create a shadow link.
  3377.              NO              Resets the object's no shadow property.
  3378. NORENAME     YES             Will not allow you to rename the object.
  3379.              NO              Resets the object's no rename property.
  3380. NOPRINT      YES             Will not allow you to print it.
  3381.              NO              Resets the object's no print property.
  3382. NOTVISIBLE   YES             Will not display the object.
  3383.              NO              Resets the object's not visible property.
  3384.  
  3385.  
  3386. ΓòÉΓòÉΓòÉ 5.6.5.4. WPShadow setup string ΓòÉΓòÉΓòÉ
  3387.  
  3388.  A shadow object is a persistent link or reference to any other object. This is 
  3389. achieved by storing away the location and identity of the object that it is 
  3390. linked to and then rerouting all requests for help, context menus, and open 
  3391. views on to the object that it is linked to. Delete, Copy, and Move are the 
  3392. only action requests that are handled by the WPShadow object and are not 
  3393. rerouted to the linked object. 
  3394.  
  3395. When you place objects into your Startup folder you should be placing a shadow 
  3396. object there. See the SHADOW sample code for an example of its usage. 
  3397.  
  3398. These are the keyname-value pairs supported by the WPShadow class. 
  3399.  
  3400.  
  3401. KEYNAME      VALUE           Description
  3402. -----------------------------------------------------------------------------
  3403. SHADOWID     <name> or       The value for this is an object's id (OBJECTID)
  3404.              filename        or a fully qualified pathname of a directory,
  3405.                              program file, or data file.
  3406.  
  3407. Note: When creating a shadow object always use the OBJECTID= string to give 
  3408. your object a unique id so that later you may refer to it, and potentially 
  3409. delete it with SysDestroyObject. 
  3410.  
  3411.  
  3412. ΓòÉΓòÉΓòÉ 5.7. REXX CMD Samples ΓòÉΓòÉΓòÉ
  3413.  
  3414. Listing of sample programs 
  3415.  
  3416.  
  3417. ΓòÉΓòÉΓòÉ 5.7.1. Listing of sample programs ΓòÉΓòÉΓòÉ
  3418.  
  3419.   FOLDER.CMD
  3420.  
  3421.            Creates a folder and program objects in the folder 
  3422.  
  3423.   SHADOW.CMD
  3424.  
  3425.            Creates shadows of objects 
  3426.  
  3427.   FLDSHAD.CMD
  3428.  
  3429.            Creates a folder, then program object in the folder, then place a 
  3430.            shadow of the program object on the desktop. 
  3431.  
  3432.   MKSHAD.CMD
  3433.  
  3434.            Creates a shadow object of an objectid, file or drive/directory. 
  3435.  
  3436.   STARTDOS.CMD
  3437.  
  3438.            Starts a DOS program using specific DOS VDM settings. 
  3439.  
  3440.   BOOTDOS.CMD
  3441.  
  3442.            Starts a DOS session, booting from a specific DOS image with 
  3443.            specific DOS VDM settings. 
  3444.  
  3445.   REBUILD.CMD
  3446.  
  3447.            Allows one to rebuild OS/2 system objects, kinda like MAKEINI does. 
  3448.  
  3449.   LPTADD.CMD
  3450.  
  3451.            Code using SysIni to add LPT4-9 ports. 
  3452.  
  3453.   OBJECTID.CMD
  3454.  
  3455.            Code using SysIni to list OBJECTIDs known to the WorkPlace Shell 
  3456.  
  3457.   FONTS.CMD
  3458.  
  3459.            Code using SysIni to list installed fonts and verify their 
  3460.            existence. 
  3461.  
  3462.   ICONRES.CMD
  3463.  
  3464.            Code building a folder containing many of the various icons found in 
  3465.            installed DLL files for OS/2 V2. Demonstrates use of setup string 
  3466.            parameter ICONRESOURCE. 
  3467.  
  3468.   SWAPEDIT.CMD
  3469.  
  3470.            Code that allows you to make the Enhanced Editor (EPM) the default 
  3471.            open action for most data objects instead of the OS/2 Enhanced 
  3472.            Editor (E). 
  3473.  
  3474.   OPENWPS.CMD
  3475.  
  3476.            Code that allows you to open up an objectid or directory using views 
  3477.            you specify. 
  3478.  
  3479.  
  3480. ΓòÉΓòÉΓòÉ 5.7.2. FOLDER.CMD ΓòÉΓòÉΓòÉ
  3481.  
  3482.  
  3483. /* FOLDER.CMD: Sample code using REXXUTIL function calls                */
  3484. /*                                                                      */
  3485. /* Builds a folder on the DeskTop and places some program objects in it.*/
  3486. /*                                                                      */
  3487. /* Demonstrates use of these REXXUTIL functions:                        */
  3488. /*   SysCreateObject   - create or update an object                     */
  3489. /*   SysDestroyObject  - delete an object                               */
  3490. /*   SysSetObjectData  - update an existing object                      */
  3491. /*                                                                      */
  3492. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  3493. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  3494. /* Version 1.1                                                          */
  3495.  
  3496. /* Load REXXUTIL */
  3497. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  3498. Signal on Syntax Name LoadCheck
  3499. Call SysLoadFuncs
  3500. LoadCheck: /* rc of 43 means REXXUTILs not found */
  3501. If rc=43 Then Do
  3502.    Say ''
  3503.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  3504.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  3505.    Exit
  3506. End
  3507. Signal off Syntax
  3508.  
  3509. call SysCls
  3510. Say '';Say 'Using REXXUTILs to Add a Folder and Program Objects...'
  3511.  
  3512. Say '';Say 'Press Y to add Test Folder to Desktop...';Say '';
  3513. parse upper value SysGetKey('NOECHO') with key
  3514. If key<>'Y' Then Signal Exiter
  3515.  
  3516. /* All of the routines pass parameters to a subroutine to perform the call */
  3517. classname='WPFolder'
  3518. title    ='Test Folder'
  3519. location ='<WP_DESKTOP>'
  3520. setup    ='OBJECTID=<TEST_FOLDER>'
  3521. Call BldObj
  3522.  
  3523. Say '';
  3524. Say 'Press ENTER and we will open up that folder and watch as other objects'
  3525. Say 'are added into it.'
  3526. key=SysGetKey()
  3527. Call SysSetObjectData '<TEST_FOLDER>', 'OPEN=DEFAULT;'
  3528.  
  3529. Say 'Place a program object into the folder...';Say '';
  3530. classname='WPProgram'
  3531. title    ='SYSLEVEL-FULLSCR'
  3532. location ='<TEST_FOLDER>'
  3533. setup    ='OBJECTID=<TEST_SYSL>;']],
  3534.           'EXENAME=\OS2\SYSLEVEL.EXE;']],
  3535.           'PROGTYPE=FULLSCREEN;'
  3536. Call BldObj
  3537.  
  3538. classname='WPProgram'
  3539. title    ='CHKDSK-PM'
  3540. location ='<TEST_FOLDER>'
  3541. setup    ='OBJECTID=<TEST_PMCK>;']],
  3542.           'EXENAME=\OS2\PMCHKDSK.EXE;']],
  3543.           'MINIMIZED=YES;']],
  3544.           'PROGTYPE=PM;'
  3545. Call BldObj
  3546.  
  3547. classname='WPProgram'
  3548. title    ='SYSLEVEL-VIO'
  3549. location ='<TEST_FOLDER>'
  3550. setup    ='OBJECTID=<TEST_SYSLVIO>;']],
  3551.           'EXENAME=\OS2\SYSLEVEL.EXE;']],
  3552.           'PROGTYPE=WINDOWABLEVIO;'
  3553. Call BldObj
  3554.  
  3555. classname='WPProgram'
  3556. title    ='MEM-Fullscreen'
  3557. location ='<TEST_FOLDER>'
  3558. setup    ='OBJECTID=<TEST_MEMFUL>;']],
  3559.           'EXENAME=\OS2\MDOS\MEM.EXE;']],
  3560.           'PROGTYPE=VDM;']],
  3561.           'PARAMETERS=/?;']],
  3562.           'NOAUTOCLOSE=YES;'
  3563. Call BldObj
  3564.  
  3565. classname='WPProgram'
  3566. title    ='MEM-WindowVDM'
  3567. location ='<TEST_FOLDER>'
  3568. setup    ='OBJECTID=<TEST_MEMWIN>;']],
  3569.           'EXENAME=\OS2\MDOS\MEM.EXE;']],
  3570.           'PROGTYPE=WINDOWEDVDM;']],
  3571.           'PARAMETERS=/?;']],
  3572.           'NOAUTOCLOSE=YES;'
  3573. Call BldObj
  3574.  
  3575. Say ''
  3576. Say 'Okay, now lets change the title of the folder using SysSetObjectData.'
  3577. Say 'Press ENTER and watch the folder get renamed...'
  3578. key=SysGetKey()
  3579. Call SysSetObjectData '<TEST_FOLDER>',  'TITLE=System Stuff';
  3580.  
  3581. Say ''
  3582. Say 'All done, now we will remove the objects by using...'
  3583. Say '...the SysDestroyObject call against the folder objectid.'
  3584. Say 'Note: If you delete a folder all objects contained within are removed.'
  3585. Say 'Press ENTER to watch the objects disappear...'
  3586. key=SysGetKey()
  3587. Call SysDestroyObject '<TEST_FOLDER>'
  3588.  
  3589. Exiter:
  3590. Call SysDropFuncs
  3591. Exit
  3592.  
  3593. /* Build Object */
  3594. BldObj:
  3595. call charout ,'Building: 'title
  3596.  
  3597. /*The basic call is listed next.                                           */
  3598. /*rc=SysCreateObject(classname, title, location <,setup>, <,duplicateflag>)*/
  3599.  
  3600. /* Build object using UPDATEIFEXIST as duplicateflag */
  3601. result = SysCreateObject(classname, title, location, setup, 'U')
  3602.  
  3603. If result=1 Then call charout ,'...   Object created!'
  3604. Else             call charout ,'...   Not created! Return code='result
  3605.  
  3606. Say '';
  3607. Return
  3608.  
  3609.  
  3610. ΓòÉΓòÉΓòÉ 5.7.3. SHADOW.CMD ΓòÉΓòÉΓòÉ
  3611.  
  3612.  
  3613. /* SHADOW.CMD: Sample code using REXXUTIL function calls                */
  3614. /*                                                                      */
  3615. /* Builds shadows in the DeskTop and Startup Folder                     */
  3616. /*                                                                      */
  3617. /* Demonstrates use of these REXXUTIL functions:                        */
  3618. /*   SysCreateObject   - create or update an object                     */
  3619. /*   SysDestroyObject  - delete an object                               */
  3620. /*   SysSetObjectData  - update an existing object                      */
  3621. /*                                                                      */
  3622. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  3623. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  3624. /* Version 1.1                                                          */
  3625.  
  3626. /* Load REXXUTIL */
  3627. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  3628. Signal on Syntax Name LoadCheck
  3629. Call SysLoadFuncs
  3630. LoadCheck: /* rc of 43 means REXXUTILs not found */
  3631. If rc=43 Then Do
  3632.    Say ''
  3633.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  3634.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  3635.    Exit
  3636. End
  3637. Signal off Syntax
  3638.  
  3639. Call SysCls
  3640. Say '';Say 'Demonstration using REXXUTILs to Add Shadow Objects...'
  3641.  
  3642. /* The titles and objectid's are found from the \OS2\INI.RC file */
  3643.  
  3644. Say '';Say 'First lets place some items on the Desktop...'
  3645. Call AddShad 'Enhanced Editor',,  /* Title */
  3646.              '<WP_DESKTOP>',,     /* Location for shadow object */
  3647.              '<WP_EPM>',,         /* Value of existing objectid or file */
  3648.              '<SHAD_WP_EPM>'      /* New unique value of this shadow object */
  3649.  
  3650. Call AddShad 'OS/2 Window',,      /* Title */
  3651.              '<WP_DESKTOP>',,     /* Location for shadow object */
  3652.              '<WP_OS2WIN>',,      /* Value of existing objectid or file */
  3653.              '<SHAD_WP_OS2WIN>'   /* New unique value of this shadow object */
  3654.  
  3655. Call AddShad 'OS/2 DeskTop',,     /* Title */
  3656.              '<WP_DESKTOP>',,     /* Location for shadow object */
  3657.              '<WP_DESKTOP>',,     /* Value of existing objectid or file */
  3658.              '<SHAD_WP_DESKTOP>'  /* New unique value of this shadow object */
  3659.  
  3660. Say '';Say 'You can even make shadow objects of files...'
  3661. Call AddShad 'CONFIG.SYS',,       /* Title */
  3662.              '<WP_DESKTOP>',,     /* Location for shadow object */
  3663.              'C:\CONFIG.SYS',,    /* Value of data file */
  3664.              '<SHAD_CONFIG_SYS>'  /* New unique value of this shadow object */
  3665.  
  3666. Say '';Say 'Now lets place an item in the Startup Folder...'
  3667. Say 'First would you like me to open the Startup Folder so you can see the'
  3668. Say 'object being created? Press Y to open the folder.'
  3669. parse upper value SysGetKey('NOECHO') with key
  3670. If key='Y' Then Call SysSetObjectData '<WP_START>', 'OPEN=DEFAULT;'
  3671.  
  3672. Call AddShad 'System Clock',,     /* Title */
  3673.              '<WP_START>',,       /* Location for shadow object */
  3674.              '<WP_CLOCK>',,       /* Value of existing objectid of file */
  3675.              '<SHAD_WP_CLOCK>'    /* New unique value of this shadow object */
  3676.  
  3677. Say '';Say 'All done, if you would like me to remove the objects press R'
  3678. parse upper value SysGetKey('NOECHO') with key
  3679. If key='R' Then Do
  3680.    Call SysDestroyObject '<SHAD_WP_EPM>'
  3681.    Call SysDestroyObject '<SHAD_WP_OS2WIN>'
  3682.    Call SysDestroyObject '<SHAD_WP_CLOCK>'
  3683.    Call SysDestroyObject '<SHAD_WP_DESKTOP>'
  3684.    Call SysDestroyObject '<SHAD_CONFIG_SYS>'
  3685. End
  3686.  
  3687. Say '';Say 'Demonstration over...'
  3688. Exiter:
  3689. Call SysDropFuncs
  3690. Exit
  3691.  
  3692. /* Routine to create a shadow object when passed arguments: */
  3693. /* Title, Location, ShadowId, and ObjectId                  */
  3694. AddShad:
  3695. Parse arg title,loc,shadowid,objectid
  3696. Say '';Say 'Press Y to add shadow object: 'title' to 'loc
  3697. parse upper value SysGetKey('NOECHO') with key
  3698. If key='Y' Then Do
  3699.    setup='SHADOWID='shadowid';OBJECTID='objectid';'
  3700.  
  3701.    /*The basic call is listed next.                                         */
  3702.    /*rc=SysCreateObject(classname,title,location <,setup>, <,duplicateflag>)*/
  3703.  
  3704.    /* Build object using FAIL as duplicateflag */
  3705.    result=SysCreateObject('WPShadow', title, loc, setup, 'F')
  3706.  
  3707.    If result=1 Then Say 'Object created'
  3708.    Else             Say 'Not created, return code='result
  3709. End
  3710. Return
  3711.  
  3712.  
  3713. ΓòÉΓòÉΓòÉ 5.7.4. FLDSHAD.CMD ΓòÉΓòÉΓòÉ
  3714.  
  3715.  
  3716. /* FLDSHAD.CMD: Sample code using REXXUTIL function calls               */
  3717. /*                                                                      */
  3718. /* Builds a folder on the DeskTop places a program object in it then    */
  3719. /* places a shadow of the program object on the DeskTop.                */
  3720. /*                                                                      */
  3721. /* Demonstrates use of these REXXUTIL functions:                        */
  3722. /*   SysCreateObject   - create or update an object                     */
  3723. /*   SysDestroyObject  - delete an object                               */
  3724. /*   SysSetObjectData  - update an existing object                      */
  3725. /*                                                                      */
  3726. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  3727. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  3728. /* Version 1.1                                                          */
  3729.  
  3730. /* Load REXXUTIL */
  3731. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  3732. Signal on Syntax Name LoadCheck
  3733. Call SysLoadFuncs
  3734. LoadCheck: /* rc of 43 means REXXUTILs not found */
  3735. If rc=43 Then Do
  3736.    Say ''
  3737.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  3738.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  3739.    Exit
  3740. End
  3741. Signal off Syntax
  3742.  
  3743. /*The basic call is listed next.                                           */
  3744. /*rc=SysCreateObject(classname, title, location <,setup>, <,duplicateflag>)*/
  3745.  
  3746. call SysCls
  3747. Say '';Say 'Using REXXUTILs to Add Folder/Program/Shadow Objects...'
  3748.  
  3749. Say '';Say 'Press Y to add Test Folder to Desktop...';Say '';
  3750. parse upper value SysGetKey('NOECHO') with key
  3751. If key<>'Y' Then Signal Exiter
  3752.  
  3753. classname='WPFolder'
  3754. title    ='Test Folder'
  3755. location ='<WP_DESKTOP>'
  3756. setup    ='OBJECTID=<TEST2_FOLDER>'
  3757. Call BldObj
  3758.  
  3759. Say '';
  3760. Say 'Press ENTER and we will open up that folder and watch as an object'
  3761. Say 'is added into it.'
  3762. key=SysGetKey()
  3763. Call SysSetObjectData '<TEST2_FOLDER>', 'OPEN=DEFAULT;'
  3764.  
  3765. classname='WPProgram'
  3766. title    ='SYSLEVEL-VIO'
  3767. location ='<TEST2_FOLDER>'
  3768. setup    ='OBJECTID=<TEST2_SYSLVIO>;']],
  3769.           'EXENAME=\OS2\SYSLEVEL.EXE;']],
  3770.           'PROGTYPE=WINDOWABLEVIO;'
  3771. Call BldObj
  3772.  
  3773. Say '';
  3774. Say 'Press ENTER and we will place a shadow of the new object on the Desktop.'
  3775. key=SysGetKey()
  3776.  
  3777. classname='WPShadow'
  3778. title    ='SYSLEVEL-VIO'
  3779. location ='<WP_DESKTOP>'
  3780. setup    ='SHADOWID=<TEST2_SYSLVIO>;OBJECTID=<SHAD_TEST2_SYSLVIO>;'
  3781. Call BldObj
  3782.  
  3783. Say ''
  3784. Say 'All done, now we will remove the objects by using...'
  3785. Say '...the SysDestroyObject call.'
  3786. Say 'Note: If you delete a folder all objects contained within are removed.'
  3787. Say 'Press ENTER to watch the objects disappear...'
  3788. key=SysGetKey()
  3789. Call SysDestroyObject '<SHAD_TEST2_SYSLVIO>'
  3790. Call SysDestroyObject '<TEST2_FOLDER>'
  3791.  
  3792. Exiter:
  3793. Call SysDropFuncs
  3794. Exit
  3795.  
  3796. /* Build Object */
  3797. BldObj:
  3798. call charout ,'Building: 'title
  3799.  
  3800. /*The basic call is listed next.                                            */
  3801. /*rc=SysCreateObject(classname, title, location <,setup>, <,duplicateflag>) */
  3802.  
  3803. /* Build object using UPDATEIFEXIST as duplicateflag */
  3804. result = SysCreateObject(classname, title, location, setup, 'U')
  3805.  
  3806. If result=1 Then call charout ,'...   Object created!'
  3807. Else             call charout ,'...   Not created! Return code='result
  3808.  
  3809. Say '';
  3810. Return
  3811.  
  3812.  
  3813. ΓòÉΓòÉΓòÉ 5.7.5. MKSHAD.CMD ΓòÉΓòÉΓòÉ
  3814.  
  3815.  
  3816. /* MKSHAD.CMD: Sample code using REXXUTIL function calls                */
  3817. /*                                                                      */
  3818. /* Builds shadows when passed names of files, drive/directories, or     */
  3819. /* existing objectid of WorkPlace Shell objects.                        */
  3820. /*                                                                      */
  3821. /* Enter: MKSHAD ?   for more information                               */
  3822. /*                                                                      */
  3823. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  3824. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  3825. /* Version 1.0                                                          */
  3826. /* Load REXXUTIL */
  3827. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  3828. Signal on Syntax Name LoadCheck
  3829. Call SysLoadFuncs
  3830. LoadCheck: /* rc of 43 means REXXUTILs not found */
  3831. If rc=43 Then Do
  3832.    Say ''
  3833.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  3834.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  3835.    Exit
  3836. End
  3837. Signal off Syntax
  3838. Parse arg name loc how
  3839. If name='?' ] translate(name)='HELP' Then Signal Helper
  3840. yes=1;no=0;
  3841. name=strip(name,'B','"')
  3842. loc=strip(loc,'B','"')
  3843. how=strip(how,'B','"')
  3844. hname=name
  3845. /* Default is to prompt before creating shadow unless /N is passed */
  3846. If translate(how)='/N' Then Do,
  3847.    how=''; quiet=yes;
  3848. End
  3849. Else If translate(loc)='/N' Then Do
  3850.    loc=''; quiet=yes;
  3851. End
  3852. Else If translate(name)='/N' Then Do
  3853.    name=''; quiet=yes;
  3854. End
  3855. Else quiet=no;
  3856. /* If no parm is passed assume need current directory shadowed on desktop */
  3857. If name='' Then name=directory()
  3858. /* Passing an objectid to be shadowed */
  3859. Else If left(name,1)='<' & right(name,1)='>' Then Do
  3860.      /* Check to see if it exists, build a list of all existing objectids */
  3861.      App='PM_Workplace:Location'
  3862.      call SysIni 'USER', App, 'All:', 'ObjIDTab'
  3863.      Do t=1 to ObjIDTab.0
  3864.         If name=ObjIDTab.t Then leave
  3865.      End
  3866.      If name<>ObjIDTab.t Then Do
  3867.         Say 'ERROR! Objectid:' name' not found'
  3868.         Signal Exiter
  3869.      End
  3870. End
  3871. Else Do
  3872.    /* If this file exists then no need to check other possibilities */
  3873.    Fname=stream(name,'C','Q EXISTS')
  3874.    If fname<>'' Then name=fname /* fully qualified name is returned */
  3875.    Else Do /* Must be a drive/directory passed */
  3876.       If right(name,1)<>'\' Then name=name]]'\'
  3877.       name=filespec('drive',name)]]filespec('path',name)
  3878.       name=strip(name,'T','\')
  3879.       If right(name,1)=':' Then name=name]]'\'
  3880.       Call SysFileTree name, mystem, 'D'
  3881.       If mystem.0=0 Then Do
  3882.          Say 'Sorry, cannot tell what should be shadowed.'
  3883.          Say 'The value:' hname
  3884.          Say 'Is not a file nor drive/directory that exists.'
  3885.          Signal Exiter
  3886.       End
  3887.    End
  3888. End
  3889. /* Location processing */
  3890. If loc<>'' Then Do
  3891.    /* Check to see if location exists, build list of all existing objectids */
  3892.    App='PM_Workplace:Location'
  3893.    call SysIni 'USER', App, 'All:', 'ObjIDTab'
  3894.    Do t=1 to ObjIDTab.0
  3895.       If loc=ObjIDTab.t Then leave
  3896.    End
  3897.    If loc<>ObjIDTab.t Then Do
  3898.       Say 'WARNING! Location:' loc' not found'
  3899.       Say 'Will create shadow on DeskTop instead.'
  3900.       loc='<WP_DESKTOP>'
  3901.    End
  3902. End
  3903. Else loc='<WP_DESKTOP>'
  3904. /* If an objectid then strip < character, leave end in */
  3905. If left(name,1)='<' & right(name,1)='>' Then obj='<SHAD_'strip(name,'B','<')
  3906. Else obj='<SHAD_'name'>'
  3907. If quiet=no Then Do
  3908.    Say 'Create a shadow of      :' name
  3909.    Say 'Location to be created  :' loc
  3910.    Say 'Objectid for the object :' obj
  3911.    Say 'To create press C any other key ends the program'
  3912.    parse upper value SysGetKey('NOECHO') with key
  3913.    If key<>'C' Then Signal Exiter
  3914. End
  3915. setup='SHADOWID='name';OBJECTID='obj';'
  3916. result=SysCreateObject('WPShadow', ' ', loc, setup, 'U')
  3917. If quiet=no Then Do
  3918.    If result=1 Then Say 'Shadow object created'
  3919.    Else             Say 'Not created, return code='result
  3920. End
  3921. /* Common exit point */
  3922. Exiter:
  3923. Call SysDropFuncs
  3924. Exit
  3925. /* Help Routine */
  3926. Helper:
  3927. Say '** MKSHAD ** Make a shadow object'
  3928. Say 'Syntax: MKSHAD [name] [location] [/n]'
  3929. Say 'If no parameters are passed it is assumed you want the current drive'
  3930. Say 'and directory shadowed to the DeskTop.'
  3931. Say 'Otherwise you can specify the name of an existing objectid, and existing'
  3932. Say 'file, or drive/directory to be shadowed. Followed by the location of'
  3933. Say 'where the shadow should be placed. If no location is specified then the'
  3934. Say 'DeskTop is assumed. The location should be an existing objectid of a'
  3935. Say 'folder and should be enclosed in double quotes, i.e. "<WP_STARTUP>"'
  3936. Say 'Look at your \OS2\INI.RC for many existing objectids for system objects.'
  3937. Say 'If you use /N then you are not prompted for confirmation, the object'
  3938. Say 'will immediately be created.'
  3939. Say '---Examples---'
  3940. Say ' MKSHAD C:\OS2'
  3941. Say ' - Shadow of C:\OS2 directory placed on the DeskTop.'
  3942. Say ' MKSHAD "<WP_OS2WIN>" "<WP_STARTUP>"'
  3943. Say ' - Shadow of OS/2 Window object placed into Startup folder.'
  3944. Say ' MKSHAD C:\CONFIG.SYS /n'
  3945. Say ' - Shadow of CONFIG.SYS placed on the DeskTop, no prompts.'
  3946. Say ' MKSHAD C:\OS2\MDOS\WINOS2\README.ATM "<WP_INFO>"'
  3947. Say ' - Shadow of README.ATM placed in the Information folder.'
  3948. Signal Exiter
  3949.  
  3950.  
  3951. ΓòÉΓòÉΓòÉ 5.7.6. STARTDOS.CMD ΓòÉΓòÉΓòÉ
  3952.  
  3953.  
  3954. /* STARTDOS.CMD: Sample code using REXXUTIL's SysCreateObject function  */
  3955. /* Starts a DOS program using specific DOS VDM settings.  This is       */
  3956. /* particularly useful for LAN execution that requires NET USE commands.*/
  3957. /* The example invokes the PKZIP.EXE program using files setting of 45  */
  3958. /* Rick McGuire:  MCGUIRE/GDLVM7                                        */
  3959. /* Load REXXUTIL */
  3960. call rxfuncadd sysloadfuncs, rexxutil, sysloadfuncs
  3961. call sysloadfuncs
  3962.  
  3963. /* The basic call is listed next.                                          */
  3964. /* result = SysCreateObject(classname, title, location, setup)             */
  3965.  
  3966. classname='WPProgram'
  3967. title='My DOS Program'
  3968. location='<WP_NOWHERE>'                  /* place in invisible folder      */
  3969. program='EXENAME=C:\PKZIP.EXE;'          /* DOS program name               */
  3970. type='PROGTYPE=WINDOWEDVDM;'             /* type of DOS session (windowed) */
  3971. startup='STARTUPDIR=C:\;'                /* startup directory              */
  3972. settings='SET DOS_FILES=45;'             /* required DOS settings          */
  3973. open='OPEN=DEFAULT;'                     /* open now                       */
  3974.  
  3975. call SysCreateObject classname, title, location,,
  3976.     program]]type]]startup]]settings]]open, 'REPLACE'
  3977. Return
  3978.  
  3979.  
  3980. ΓòÉΓòÉΓòÉ 5.7.7. BOOTDOS.CMD ΓòÉΓòÉΓòÉ
  3981.  
  3982.  
  3983. /* BOOTDOS.CMD: Sample code using REXXUTIL's SysCreateObject function   */
  3984. /* Starts a DOS session, booting from a specific DOS image with         */
  3985. /* specific DOS VDM settings.                                           */
  3986. /* Rick McGuire:  MCGUIRE/GDLVM7                                        */
  3987. /* Load REXXUTIL */
  3988. call rxfuncadd sysloadfuncs, rexxutil, sysloadfuncs
  3989. call sysloadfuncs
  3990.  
  3991. /* The basic call is listed next.                                          */
  3992. /* result = SysCreateObject(classname, title, location, setup)             */
  3993.  
  3994. classname='WPProgram'
  3995. title='Booted DR DOS'
  3996. location='<WP_NOWHERE>'                  /* place in invisible folder      */
  3997. program='EXENAME=*;'                     /* DOS program name (use shell)   */
  3998. type='PROGTYPE=WINDOWEDVDM;'             /* type of DOS session (windowed) */
  3999. image='C:\DRDOS.VM;'                     /* DOS image file                 */
  4000.                                          /* required DOS settings          */
  4001. settings='SET DOS_BACKGROUND_EXECUTION=ON;'
  4002. open='OPEN=DEFAULT;'                     /* open now                       */
  4003.  
  4004. call SysCreateObject classname, title, location,,
  4005.     program]]type]]image]]settings]]open, 'REPLACE'
  4006. Return
  4007.  
  4008.  
  4009. ΓòÉΓòÉΓòÉ 5.7.8. REBUILD.CMD ΓòÉΓòÉΓòÉ
  4010.  
  4011.  
  4012. /* REBUILD.CMD: Sample code using REXXUTIL's SysCreateObject function   */
  4013. /* Can be used to rebuild objects created during the installation of    */
  4014. /* your OS/2 system. The \OS2\INSTALL\INI.RC file contains information  */
  4015. /* that can be used by the SysCreateObject function.                    */
  4016. /* The INI.RC file is used by MAKEINI.EXE to create your OS2.INI file   */
  4017. /*                                                                      */
  4018. /* Syntax:  Enter  "REBUILD ?" for complete syntax                      */
  4019. /*                                                                      */
  4020. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  4021. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  4022. /* Version 1.1                                                          */
  4023.  
  4024. '@ECHO OFF'
  4025. /* Load REXXUTIL */
  4026. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  4027. Signal on Syntax Name LoadCheck
  4028. Call SysLoadFuncs
  4029. LoadCheck: /* rc of 43 means REXXUTILs not found */
  4030. If rc=43 Then Do
  4031.    Say ''
  4032.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  4033.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  4034.    Exit
  4035. End
  4036. Signal off Syntax
  4037.  
  4038. Arg parms
  4039. cmdparms=parms /* Save command line parms for later processing */
  4040.  
  4041. /* Until REXXUTIL offers a function call to retrieve the OS2 boot drive   */
  4042. /* we assume the environment variable COMSPEC has location of boot drive. */
  4043. BtDrv=filespec('drive',value('COMSPEC',,'OS2ENVIRONMENT'))
  4044.  
  4045. parse upper var cmdparms type '(' inifile .
  4046. /* If user does not enter location of *.RC file then try to find it */
  4047. If inifile='' Then inifile=BtDrv]]'\OS2\INI.RC'
  4048. rcx=stream(inifile,'C','Q EXISTS')
  4049. If rcx='' Then Do
  4050.    Say '';Say '';Say inifile 'not found'
  4051.    Signal Exiter
  4052. End
  4053. type=left(type,1)
  4054. If verify(type,'FPOA') Then Signal Helper
  4055.  
  4056. /* Initialize tables and table counters */
  4057. iniftab.=''; iniptab.='' iniotab.=''; /*Folders, Programs, Others */
  4058. iniflns=0;   iniplns=0;  iniolns=0;
  4059. initab.='';  inilns=0;
  4060. Call stream inifile,'C','CLOSE'
  4061. Do while lines(inifile)>0  /* Read RC file into tables */
  4062.    lne=linein(inifile)
  4063.    parse var lne '"PM_InstallObject"' lne
  4064.    If lne\='' Then Do
  4065.       parse var lne '"'rest1'" 'lne
  4066.       parse var lne '"'setup'"'
  4067.       parse var rest1 title';'object';'location';'
  4068.       If object='WPFolder' Then Do
  4069.          iniflns=iniflns+1
  4070.          iniftab.1.iniflns=object;   iniftab.2.iniflns=title;
  4071.          iniftab.3.iniflns=location; iniftab.4.iniflns=setup;
  4072.       End
  4073.       Else If object='WPProgram' Then Do
  4074.          iniplns=iniplns+1
  4075.          iniptab.1.iniplns=object;   iniptab.2.iniplns=title;
  4076.          iniptab.3.iniplns=location; iniptab.4.iniplns=setup;
  4077.       End
  4078.       Else Do
  4079.          iniolns=iniolns+1
  4080.          iniotab.1.iniolns=object;   iniotab.2.iniolns=title;
  4081.          iniotab.3.iniolns=location; iniotab.4.iniolns=setup;
  4082.       End
  4083.    End
  4084. End
  4085. Call stream inifile,'C','CLOSE'
  4086.  
  4087. /* Calculation for screen loop */
  4088. parse value SysTextScreenSize() with row col
  4089. scrsz=row-12
  4090.  
  4091. If type='F' ] type='A' Then Do; /* Folder routine */
  4092.    objt='Folder'; inilns=iniflns;
  4093.    Do i=1 to inilns; Do j=1 to 4;
  4094.       initab.j.i=iniftab.j.i
  4095.    End; End;
  4096.    Call DispSel
  4097. End;
  4098. If type='P' ] type='A' Then Do; /* Program routine */
  4099.    objt='Program'; inilns=iniplns;
  4100.    Do i=1 to inilns; Do j=1 to 4;
  4101.       initab.j.i=iniptab.j.i
  4102.    End; End;
  4103.    Call DispSel
  4104. End;
  4105. If type='O' ] type='A' Then Do; /* Other routine */
  4106.    objt='Other'; inilns=iniolns;
  4107.    Do i=1 to inilns; Do j=1 to 4;
  4108.       initab.j.i=iniotab.j.i
  4109.    End; End;
  4110.    Call DispSel
  4111. End;
  4112.  
  4113. Exiter: /* When get here done with processing */
  4114. Call SysDropFuncs
  4115. Exit
  4116.  
  4117. /* Routine to display objects and allow selection */
  4118. DispSel:
  4119. key=''
  4120. Do while key\='Q'
  4121.    Call SysCls; Say '';Say objt' objects found in: 'inifile;Say '';
  4122.    Do i=1 to inilns
  4123.       If trunc(i/scrsz)==i/scrsz Then Call Promptx 1
  4124.       If key='Q' Then leave
  4125.       n=right('  ']]i,3)]]') ']]left(initab.2.i]]copies(' ',30),30)
  4126.  
  4127.       n=n]]left(initab.3.i]]copies(' ',20),20)
  4128.       Say n
  4129.    End
  4130.    If key\='Q' Then Call Promptx 0
  4131. End
  4132. Return
  4133.  
  4134. /* Screen loop routine also calls object build routine */
  4135. Promptx: Arg scr
  4136. Say '';Say 'To attempt to rebuild an object enter the number of the object'
  4137. If scr=0 Then Say 'or enter Q to quit...'
  4138. Else Say 'or press enter to show next screen...  Or enter Q to Quit...'
  4139. pull key .
  4140. If (key>=1) & (key <=inilns) then Do
  4141.     rcx=BldIt(initab.1.key,initab.2.key,initab.3.key,initab.4.key)
  4142.  
  4143.     /* Ask if want objects in folder rebuilt */
  4144.     If object='WPFolder' Then Do
  4145.        Say '';Say 'Press Y to recreate the program objects in this folder.'
  4146.        parse upper value SysGetKey('NOECHO') with ansr
  4147.        If ansr='Y' Then Do
  4148.           parse var setup 'OBJECTID='obj';'
  4149.           Do ii=1 to iniplns;
  4150.              If iniptab.3.ii=obj Then Do
  4151.                 rcx=BldIt(iniptab.1.ii,iniptab.2.ii,iniptab.3.ii,iniptab.4.ii)
  4152.              End
  4153.           End;
  4154.        End;
  4155.     End;
  4156.  
  4157. End;
  4158. If scr=1 Then Do;
  4159.    Call SysCls;Say '';Say objt' objects found in: 'inifile;Say '';
  4160. End;
  4161. Return
  4162.  
  4163. /* Routine to build object */
  4164. BldIt: Parse Arg object,title,location,setup
  4165. Say 'Command generated:'
  4166. Say 'SysCreateObject('object', 'title', 'location', 'setup', U)'
  4167. /* Build object using UPDATE as duplicateflag */
  4168. result = SysCreateObject(object, title, location, setup, 'U')
  4169. If result=1 Then Say '...   Object created!'
  4170. Else             Say '...   Not created! Return code='result
  4171. Say '';Say 'Press any key to continue...'
  4172. SysGetKey('NOECHO')
  4173. Return result
  4174.  
  4175. /* Syntax help */
  4176. Helper:
  4177. call SysCls
  4178. Say '';Say ''; Say 'REBUILD:'
  4179. Say 'Routine to rebuild system installed objects listed in *.RC files.'
  4180. Say 'Can be used as an alternative to using the MAKEINI command.'
  4181. Say 'Your INI.RC file is used by MAKEINI.EXE during installation to'
  4182. Say 'create your OS2.INI file.'
  4183. Say ''; Say 'Syntax:';Say '';
  4184. Say 'REBUILD object [(filespec]'
  4185. Say '';Say 'Valid objects A(ll), F(olders), P(rograms), O(ther)'
  4186. Say 'Can also can use (filespec for name of *.RC file, default is \OS2\INI.RC'
  4187. Signal Exiter
  4188.  
  4189.  
  4190. ΓòÉΓòÉΓòÉ 5.7.9. LPTADD.CMD ΓòÉΓòÉΓòÉ
  4191.  
  4192.  
  4193. /* LPTADD.CMD: Sample code using REXXUTIL's SysIni function.            */
  4194. /* Routine will expand the number of LPT ports the WorkPlace Shell      */
  4195. /* recognizes from LPT1-3 to LPT1-9. Also a routine to add LPT3-9 to    */
  4196. /* the WIN-OS2 WIN.INI file.                                            */
  4197. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  4198. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  4199. /* Version 1.0                                                          */
  4200. '@ECHO OFF'
  4201. /* Load REXXUTIL */
  4202. call rxfuncadd sysloadfuncs, rexxutil, sysloadfuncs
  4203. call sysloadfuncs
  4204.  
  4205. /* The basic call for setting a single key value is listed next.        */
  4206. /* result = SysIni([inifile], app, key, val)                            */
  4207.  
  4208. call SysCls; Say '';
  4209. Say 'Using REXXUTILs SysIni call to add LPT4-9 to the WorkPlace Shell'
  4210. Say '';Say 'Press Y to add/initialize LPT4-9 ports...';Say '';
  4211. parse upper value SysGetKey('NOECHO') with key
  4212. If key='Y' Then Do
  4213.    Say 'LPT Ports: setting up for LPT4-9 ports...'
  4214.    Do n=4 to 9
  4215.       Say ' Setting up PM_LPT'n'...'
  4216.       rx=SysIni('SYSTEM', 'PM_SPOOLER_PORT', 'LPT'n, ';']]'00'x)
  4217.       If rx\='' Then Say 'LPT'n' Bad result='result
  4218.       rx=SysIni('SYSTEM', 'PM_LPT'n,         'DESCRIPTION', 'LPT']]n]]'00'x)
  4219.       If rx\='' Then Say 'LPT'n' Bad result='result
  4220.       rx=SysIni('SYSTEM', 'PM_LPT'n,         'INITIALIZATION', ';']]'00'x)
  4221.       If rx\='' Then Say 'LPT'n' Bad result='result
  4222.       rx=SysIni('SYSTEM', 'PM_LPT'n,         'PORTDRIVER', 'PARALLEL;']]'00'x)
  4223.       If rx\='' Then Say 'LPT'n' Bad result='result
  4224.       rx=SysIni('SYSTEM', 'PM_LPT'n,         'TERMINATION', ';']]'00'x)
  4225.       If rx\='' Then Say 'LPT'n' Bad result='result
  4226.       rx=SysIni('SYSTEM', 'PM_LPT'n,         'TIMEOUT', '45;']]'00'x)
  4227.       If rx\='' Then Say 'LPT'n' Bad result='result
  4228.    End
  4229.    Say 'LPT4-9 added... Press any key to continue...'
  4230.    SysGetKey('NOECHO')
  4231. End
  4232.  
  4233. call SysCls; Say '';
  4234. Say 'Can now attempt to add LPT3-9 to your WIN-OS2 WIN.INI file.'
  4235. Say '';Say 'Press Y to attempt to add LPT3-9 ports to WIN-OS2...';Say '';
  4236. parse upper value SysGetKey('NOECHO') with key
  4237. If key='Y' Then Do
  4238.   /* Change \OS2\MDOS\WINOS2\WIN.INI to add more ports LPT3-LPT9 */
  4239.   win.='';winnew.='';
  4240.   /* Until REXXUTIL offers a function call to retrieve the OS2 boot drive  */
  4241.   /* we assume the environment variable COMSPEC has location of boot drive. */
  4242.   BtDrv=filespec('drive',value('COMSPEC',,'OS2ENVIRONMENT'))
  4243.   fn=BtDrv'\OS2\MDOS\WINOS2\WIN.INI';
  4244.   fnx=stream(fn,'C','QUERY EXISTS')
  4245.   fn=fnx;
  4246.   If fn\='' Then Do /* If file exists then process adding extra ports */
  4247.      Call stream fn,'C','CLOSE'
  4248.      Do i=1 to 10000 while LINES(fn)>0
  4249.         parse value linein(fn) with win.i
  4250.      End
  4251.      Call stream fn,'C','CLOSE'
  4252.      i=i-1; k=0;
  4253.      Do j=1 to i /* Look for FILE:= then if line before = LPT2.OS2= add 3-9 */
  4254.         If win.j='FILE:=' Then Do
  4255.            m=j-1; winchg=no;
  4256.            If win.m='LPT2.OS2=' Then Do
  4257.               Say 'LPT Ports: setting up for Windows LPT3-9 ports...'
  4258.               winchg=yes;
  4259.               Do n=3 to 9
  4260.                  Say ' Setting up: LPT'n'.OS2='
  4261.                  k=k+1; winnew.k='LPT'n'.OS2='
  4262.               End;
  4263.            End;
  4264.         End;
  4265.         k=k+1;
  4266.         winnew.k=win.j;
  4267.      End;
  4268.      If winchg=yes Then Do;
  4269.         parse var fnx fnx'.' .
  4270.         ifn=fnx]]'.???';
  4271.         ifn=SysTempFileName(ifn)
  4272.         '@COPY' fn ifn '1>NUL 2>NUL' /* Copy original to backup name */
  4273.         Say 'Copy of' fn 'saved as' ifn
  4274.         Say 'Writing' fn 'with added lines.'
  4275.         call lineout fn,,1 /* Start writing at first character */
  4276.         Do i=1 to k /* write file back out */
  4277.            call lineout fn,winnew.i
  4278.         End
  4279.         Call stream fn,'C','CLOSE'
  4280.      End;
  4281.      Else Say 'Lines not added, either already done or not what we expect.'
  4282.   End;
  4283.   Else Say 'Could not locate' fn 'program ending...'
  4284. End;
  4285. Say 'LPTADD ending...'
  4286. Call SysDropFuncs
  4287. Exit
  4288.  
  4289.  
  4290. ΓòÉΓòÉΓòÉ 5.7.10. OBJECTID.CMD ΓòÉΓòÉΓòÉ
  4291.  
  4292.  
  4293. /* OBJECTID.CMD: Sample code using REXXUTIL's SysIni function.          */
  4294. /* Routine will display the OBJECTIDs known to the WorkPlace Shell      */
  4295. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  4296. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  4297. /* Version 1.1                                                          */
  4298. '@ECHO OFF'
  4299. /* Load REXXUTIL */
  4300. call rxfuncadd sysloadfuncs, rexxutil, sysloadfuncs
  4301. call sysloadfuncs
  4302.  
  4303. /* List ObjectIds */
  4304. App='PM_Workplace:Location'
  4305. call SysIni 'USER', App, 'All:', 'Keys'
  4306. if Result \= 'ERROR:' then do
  4307.    Call SysCls
  4308.    Say '';Say '';
  4309.    Say 'Listing ObjectId information (value enclosed in quotes)'; Say '';
  4310.    parse value SysTextScreenSize() with row col
  4311.    j=row-10
  4312.    Do i=1 to Keys.0
  4313.       If trunc(i/j)==i/j Then Do
  4314.          Say '';Say 'Press any key to show next screen...'
  4315.          key=SysGetKey()
  4316.          Call SysCls
  4317.          Say '';Say '';
  4318.          Say 'Listing ObjectId information (value enclosed in quotes)'; Say '';
  4319.       End
  4320.       Say '"'Keys.i'"'
  4321.    End
  4322. End
  4323. Else Say 'Error querying for' App
  4324. Call SysDropFuncs
  4325. Exit
  4326.  
  4327.  
  4328. ΓòÉΓòÉΓòÉ 5.7.11. FONTS.CMD ΓòÉΓòÉΓòÉ
  4329.  
  4330.  
  4331. /* FONTS.CMD: Sample code using REXXUTIL's SysIni function.             */
  4332. /* Routine will display the FONTS known to the WorkPlace Shell,         */
  4333. /* verifies that the font file exists and also if passed REBUILD as a   */
  4334. /* parameter will rebuild the INI entries based upon INI.RC values.     */
  4335.  
  4336. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  4337. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  4338. /* Version 1.1                                                          */
  4339.  
  4340. '@ECHO OFF'
  4341. /* Load REXXUTIL */
  4342. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  4343. Signal on Syntax Name LoadCheck
  4344. Call SysLoadFuncs
  4345. LoadCheck: /* rc of 43 means REXXUTILs not found */
  4346. If rc=43 Then Do
  4347.    Say ''
  4348.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  4349.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  4350.    Exit
  4351. End
  4352. Signal off Syntax
  4353. Parse upper arg parm
  4354.  
  4355. App='PM_Fonts'
  4356. /* Until REXXUTIL offers a function call to retrieve the OS2 boot drive   */
  4357. /* we assume the environment variable COMSPEC has location of boot drive. */
  4358. BtDrv=filespec('drive',value('COMSPEC',,'OS2ENVIRONMENT'))
  4359. If Parm<>'REBUILD' Then Do
  4360.    call SysIni 'USER', App, 'All:', 'Keys'
  4361.    If Result \= 'ERROR:' then do
  4362.       Do j=1 to Keys.0
  4363.          fname=space(SysIni('USER', App, Keys.j))
  4364.          msg=''
  4365.          If stream(BtDrv]]fname,'C','Q EXISTS')='' Then,
  4366.             msg='**Font file not found***';
  4367.          Keys.j=Keys.j 'Installed as:' fname ]] msg
  4368.       End
  4369.       Call SysCls
  4370.       Say '';Say '';Say 'Listing Installed Fonts';Say '';
  4371.       parse value SysTextScreenSize() with row col
  4372.       j=row-10
  4373.       Do i=1 to Keys.0
  4374.          If trunc(i/j)==i/j Then Do
  4375.             Say '';Say 'Press any key to show next screen...'
  4376.             key=SysGetKey()
  4377.             Call SysCls
  4378.             Say '';Say '';Say 'Listing Installed Fonts';Say '';
  4379.          End
  4380.          Say left(Keys.i,75)
  4381.       End
  4382.    End
  4383.    Else Say 'Error querying for' App
  4384. End
  4385. Else Do /* Requesting to rebuild fonts as listed in INI.RC */
  4386.    inifile=BtDrv]]'\OS2\INI.RC'
  4387.    rcx=stream(inifile,'C','Q EXISTS')
  4388.    If rcx='' Then Do
  4389.       Say '';Say '';
  4390.       Say inifile 'not found, cannot rebuild PM_Fonts INI entries'
  4391.       Signal Exiter
  4392.    End
  4393.    Do while lines(inifile)>0
  4394.       lne=linein(inifile)
  4395.       parse var lne '"PM_Fonts"' lne
  4396.       If lne\='' Then Do
  4397.          parse var lne '"'key'" 'lne
  4398.          parse var lne '"'val'"'
  4399.          msg=''
  4400.          Call charout ,'Building' left(key,13) left(val,25)
  4401.          If stream(BtDrv]]val,'C','Q EXISTS')='' Then,
  4402.             Say ' ** Font file 'BtDrv]]val' not found.'
  4403.          Else Do
  4404.             Call SysIni 'USER', App, key, val
  4405.             If result='' Then Say ' ...Okay...'
  4406.             Else Say ' ...'result
  4407.          End
  4408.       End
  4409.    End
  4410.    Call stream inifile,'C','CLOSE'
  4411. End
  4412. Say ''
  4413. Say 'FONTS completed, will display the FONTS known to the WorkPlace Shell,'
  4414. Say 'and verify that the font file exists. Also if passed REBUILD as a'
  4415. Say 'parameter will rebuild the INI entries based upon INI.RC values.'
  4416. Exiter:
  4417. Call SysDropFuncs
  4418. Exit
  4419.  
  4420.  
  4421. ΓòÉΓòÉΓòÉ 5.7.12. ICONRES.CMD ΓòÉΓòÉΓòÉ
  4422.  
  4423.  
  4424. /* ICONRES.CMD: Sample code using REXXUTIL's SysCreateObject function   */
  4425. /* Routine will create a folder containing many icons available in      */
  4426. /* installed DLLs on an OS/2 V2 system. Shows how to use the setup      */
  4427. /* string parm: ICONRESOURCE                                            */
  4428. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  4429. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  4430. /* Version 1.0                                                          */
  4431. '@ECHO OFF'
  4432. /* Load REXXUTIL */
  4433. call rxfuncadd sysloadfuncs, rexxutil, sysloadfuncs
  4434. call sysloadfuncs
  4435.  
  4436. call SysCls
  4437. Say '';
  4438. Say 'Using REXXUTILs to demonstrate use of the ICONRESOURCE parameter.'
  4439. Say 'A folder will be created and populated with various icons found'
  4440. Say 'in some installed DLL files.'
  4441. Say '';
  4442. Say 'ICONRESOURCE is a SysCreateObject setup string parameter, has syntax:'
  4443. Say '';
  4444. Say '  ICONRESOURCE=id module       Ex:  ICONRESOURCE=3 PMWP;'
  4445. Say '  id=number of the icon resource, module=filename of the DLL'
  4446. Say ''; Say 'NOTE: Over 70 icons, program will run for a minute or two.'
  4447. Say '      After program ends the WPS will continue to resolve objects, also'
  4448. Say '      the building of the objects adds approx 100K to your OS2.INI.'
  4449. Say '';Say 'Press Y to add the folder to Desktop and populate...';Say '';
  4450. parse upper value SysGetKey('NOECHO') with key
  4451. If key<>'Y' Then Signal Exiter
  4452.  
  4453. /* Build folder for icons */
  4454. call charout ,'Building: ICONRESOURCE Icon Folder'
  4455. result = SysCreateObject('WPFolder', 'ICONRESOURCE'x2c(A)'Icon Folder',,
  4456.         '<WP_DESKTOP>', 'OBJECTID=<ICN_FOLDER>;', 'U')
  4457. If result=1 Then call charout ,'...   Object created!'
  4458. Else             call charout ,'...   Not created! Return code='result
  4459. Say '';
  4460. classname='WPAbstract'
  4461. location='<ICN_FOLDER>'
  4462. /* WPCONFIG 1-13 WPPRTMRI 3-16 19-23 */
  4463. fn='PMWP'
  4464. Do i=1 to 75
  4465.    If i<5 ] i=13 ] (i>15 & i<21) ] i=22 ] (i>23 & i<30) ] i=32 ] i=33,
  4466.     ] i=44 ] i=46 ] i=48 ] i=52 ] i=53 ] (i>55 & i<73) Then Call BldObj
  4467. End
  4468. fn='WPCONFIG'
  4469. Do i=1 to 13
  4470.    Call BldObj
  4471. End
  4472. fn='WPPRTMRI'
  4473. Do i=3 to 23
  4474.    If (i<17 ] i>18) Then Call BldObj
  4475. End
  4476. Say '';Say 'All done, to remove drag folder to shredder...'
  4477. Exiter:
  4478. Call SysDropFuncs
  4479. Exit
  4480.  
  4481. /* Build Object */
  4482. BldObj:
  4483. if i<10 then j='0']]i
  4484. else j=i
  4485. title=fn'-']]j
  4486. setup='ICONRESOURCE=']]j]]' 'fn';OBJECTID=<ICN-'fn'-']]j]]'>'
  4487. call charout ,'Building: 'title
  4488. result = SysCreateObject(classname, title, location, setup, 'U')
  4489. If result=1 Then call charout ,'...   Object created!'
  4490. Else             call charout ,'...   Not created! Return code='result
  4491. Say '';
  4492. Return
  4493.  
  4494.  
  4495. ΓòÉΓòÉΓòÉ 5.7.13. SWAPEDIT.CMD ΓòÉΓòÉΓòÉ
  4496.  
  4497.  
  4498. /* SWAPEDIT.CMD: Sample code using REXXUTIL function calls              */
  4499. /*                                                                      */
  4500. /* Swaps the OS/2 System Editor (E) with the Enhanced Editor (EPM).     */
  4501. /*                                                                      */
  4502. /* Enter: SWAPEDIT  for more information                                */
  4503. /*                                                                      */
  4504. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  4505. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  4506. /* Version 1.0                                                          */
  4507. /* Load REXXUTIL */
  4508. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  4509. Signal on Syntax Name LoadCheck
  4510. Call SysLoadFuncs
  4511. LoadCheck: /* rc of 43 means REXXUTILs not found */
  4512. If rc=43 Then Do
  4513.    Say ''
  4514.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  4515.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  4516.    Exit
  4517. End
  4518. Signal off Syntax
  4519. Parse arg parm
  4520. /* Default is to prompt before swapping unless /N is passed */
  4521. If translate(parm)<>'/N' Then Call Logo
  4522. /* First apply the same associations to EPM as the System Editor */
  4523. setup    ='ASSOCTYPE=Plain Text,OS/2 Command File,DOS Command File,,;']],
  4524.           'ASSOCFILTER=*.DOC,*.TXT,,;'
  4525. result=SysSetObjectData('<WP_EPM>',setup)
  4526. If result=1 Then Say 'EPM object updated...'
  4527. Else             Say 'EPM object NOT updated! Return code='result
  4528.  
  4529. /* Now Replace the System Editor object (gets deleted then recreated) */
  4530. title    ='OS/2 System Editor'
  4531. setup    ='OBJECTID=<WP_SYSED>;']],
  4532.           'EXENAME=E.EXE;']],
  4533.           'ASSOCTYPE=Plain Text,OS/2 Command File,DOS Command File,,;']],
  4534.           'ASSOCFILTER=*.DOC,*.TXT,,;']],
  4535.           'HELPPANEL=9289;']],
  4536.           'PROGTYPE=PM;'
  4537. result=SysCreateObject('WPProgram', title, '<WP_TOOLS>', setup, 'R')
  4538. If result=1 Then Say 'System Editor object recreated...'
  4539. Else             Say 'System Editor object NOT created! Return code='result
  4540. /* Common exit point */
  4541. Exiter:
  4542. Call SysDropFuncs
  4543. Exit
  4544. /* Introductory message and confirmation */
  4545. Logo:
  4546. Call SysCls; Say; Say;
  4547. Say 'SWAPEDIT: Swap OS/2 System Editor (E) with the Enhanced Editor (EPM)'
  4548. Say ''
  4549. Say 'Some users of OS/2 would rather use the EPM editor for default actions'
  4550. Say 'against data file objects. One way to do this is to place the same'
  4551. Say 'associations on EPM as are on E, then delete and recreate the E program'
  4552. Say 'object. Use: SWAPEDIT /N  to perform the operation with no confirmation.'
  4553. Say ''
  4554. Say 'This program will place the same initial associations the OS/2 System'
  4555. Say 'Editor had on the Enhanced Editor. Then recreate the OS/2 System Editor'
  4556. Say 'program object. Afterwards for data file objects you will see the'
  4557. Say 'Enhanced Editor as the default choice and optionally you can use the'
  4558. Say 'OS/2 System Editor if you select the Open setting.'
  4559. Say ''
  4560. Say 'WARNING: Some files are over 255 characters in length and the EPM'
  4561. Say '         editor does not support this, so when editing files such as'
  4562. Say '         your CONFIG.SYS you should probably use the OS/2 System Editor.'
  4563. Say ''
  4564. Say 'Press C to continue or any other key to end the program'
  4565. parse upper value SysGetKey('NOECHO') with key
  4566. If key<>'C' Then Signal Exiter
  4567. Return
  4568.  
  4569.  
  4570. ΓòÉΓòÉΓòÉ 5.7.14. OPENWPS.CMD ΓòÉΓòÉΓòÉ
  4571.  
  4572.  
  4573. /* OPENWPS.CMD: Sample code using REXXUTIL function calls               */
  4574. /*                                                                      */
  4575. /* REXX Command file that allows you to open various views of objects.  */
  4576. /*                                                                      */
  4577. /* Enter: OPENWPS ?   for more information                              */
  4578. /*                                                                      */
  4579. /* Mike Lamb: MIKELAMB/KGNVMC / 30NC/370 Neighborhood Rd                */
  4580. /* ISSC MHV - Solution Center / Kingston NY 12401                       */
  4581. /* Version 1.0                                                          */
  4582.  
  4583. /* Load REXXUTIL */
  4584. Call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  4585. Signal on Syntax Name LoadCheck
  4586. Call SysLoadFuncs
  4587. LoadCheck: /* rc of 43 means REXXUTILs not found */
  4588. If rc=43 Then Do
  4589.    Say ''
  4590.    Say 'ERROR: Not able to load REXXUTILs. Perhaps REXX not installed or'
  4591.    Say '       REXXUTIL.DLL not found in a LIBPATH drive/directory.'
  4592.    Exit
  4593. End
  4594. Signal off Syntax
  4595. Parse Arg parm
  4596. If parm='?' ] translate(parm)='HELP' Then Signal Helper
  4597.  
  4598. quiet=0;       /* Set default message display */
  4599. type='DEFAULT' /* Set default open type */
  4600. objid=''       /* Set default object to open */
  4601. Do i=1 to words(parm)
  4602.   prm=word(parm,i)
  4603.   uparm=translate(prm)
  4604.   Select /* See if value is an open type */
  4605.     when uparm='SETTINGS' Then type='SETTINGS'
  4606.     when uparm='DEFAULT'  Then type='DEFAULT'
  4607.     when uparm='DETAILS'  Then type='DETAILS'
  4608.     when uparm='TREE'     Then type='TREE'
  4609.     when uparm='ICON'     Then type='ICON'
  4610.     when uparm='/N'       Then quiet=1
  4611.     otherwise Nop
  4612.   End
  4613.   If objid='' Then Do
  4614.      /* See if this value is an objectid */
  4615.      prm2=strip(prm,'B','"')
  4616.      If left(prm2,1)='<' & right(prm2,1)='>' Then Do
  4617.         /* Check to see if it exists, build list of all existing objectids */
  4618.         App='PM_Workplace:Location'
  4619.         call SysIni 'USER', App, 'All:', 'ObjIDTab'
  4620.         Do t=1 to ObjIDTab.0
  4621.            If prm2=ObjIDTab.t Then leave
  4622.         End
  4623.         If prm2<>ObjIDTab.t Then Do
  4624.            prm3=translate(prm2) /* Maybe need to uppercase value */
  4625.            Do t=1 to ObjIDTab.0
  4626.               If prm3=ObjIDTab.t Then leave
  4627.            End
  4628.            If prm3<>ObjIDTab.t Then Do
  4629.               Say 'ERROR! Objectid:' prm2' not found'
  4630.               Signal Exiter
  4631.            End
  4632.            Else objid=prm3
  4633.         End
  4634.         Else objid=prm2
  4635.      End
  4636.      Else Do
  4637.        If right(prm,1)=':' Then Call SysFileTree prm'\', mystem, 'D'
  4638.        Else Call SysFileTree prm, mystem, 'D'
  4639.        If mystem.0<>0 Then objid=prm
  4640.      End
  4641.   End
  4642. End
  4643. /* If no objectid nor valid directory passed open default directory */
  4644. If objid='' Then objid=Directory()
  4645. If quiet=0 Then Say 'Opening 'type' view of 'objid
  4646. /* Call to open the object */
  4647. Call SysSetObjectData objid, 'OPEN='type
  4648. If quiet=0 Then Do
  4649.    If result=1 Then Say 'Object opened'
  4650.    Else             Say 'Object NOT opened, return code='result
  4651. End
  4652. Exit
  4653.  
  4654. /* Common exit point */
  4655. Exiter:
  4656. Call SysDropFuncs
  4657. Exit
  4658.  
  4659. /* Help Routine */
  4660. Helper:
  4661. Call SysCls; Say; Say;
  4662. Say '** OPENWPS ** Open a WPS object or directory'
  4663. Say ''
  4664. Say 'Syntax: OPENWPS [name] [view] [/n]'
  4665. Say ''
  4666. Say 'If no parameters are passed it is assumed you want the current drive'
  4667. Say 'and directory opened using the DEFAULT view.'
  4668. Say 'Otherwise you can specify the name of an existing objectid, or'
  4669. Say 'drive/directory to be opened. Also you can specify the open view:'
  4670. Say 'Valid views:  ICON  TREE  DETAILS  SETTINGS  DEFAULT'
  4671. Say ''
  4672. Say 'When you specify an objectid you must enclosed it in double quotes,'
  4673. Say 'i.e. "<WP_INFO>" Look in \OS2\INI.RC for many existing objectids.'
  4674. Say ''
  4675. Say 'If you use /N then no messages are displayed, unless problems occur.'
  4676. Say ''
  4677. Say '---Examples---'
  4678. Say ' OPENWPS                           OPENWPS D:\ /N  '
  4679. Say ' - Open the default directory.     - Open root of D:, no messages.'
  4680. Say ' OPENWPS "<WP_INFO>"               OPENWPS "<WP_PULSE>" /N'
  4681. Say ' - Open the Information folder.    - Open the Pulse object, no messages.'
  4682. Signal Exiter
  4683.  
  4684.  
  4685. ΓòÉΓòÉΓòÉ 5.8. Code Fragments ΓòÉΓòÉΓòÉ
  4686.  
  4687.  
  4688. ΓòÉΓòÉΓòÉ 5.8.1. System Settings ΓòÉΓòÉΓòÉ
  4689.  
  4690. During our attempts at customizing the shell using REXXUTILs for newly created 
  4691. workstations we discovered many items can be controlled. Our first attempt was 
  4692. to turn off the default setting for Workplace Shell Print Screen. We wanted it 
  4693. disabled instead of enabled (saves our customers from accidentally printing the 
  4694. workplace shell screen contents :-)
  4695.  
  4696.  From there we learned other items could be changed: 
  4697.  
  4698. Remember the basic SysIni call is: 
  4699.  
  4700.  
  4701.   result = SysIni(inifile, app, key, val)
  4702.  
  4703. Note: Some items if changed did not seem to take effect until the next reboot. 
  4704.  
  4705.  
  4706. ΓòÉΓòÉΓòÉ 5.8.1.1. Confirmation ΓòÉΓòÉΓòÉ
  4707.  
  4708. To see the menu items that can be changed go to: 
  4709. OS/2 System / System Setup / System, Confirmation tab 
  4710.  
  4711.  
  4712. /* Confirm on folder delete                      0=not checked 1=checked */
  4713. res=SysIni('USER', 'PM_ControlPanel', 'ConfirmSubDelete', '0']]'00'x)
  4714. /* Confirm delete                                0=not checked 1=checked */
  4715. res=SysIni('USER', 'PM_ControlPanel', 'ConfirmDelete', '0']]'00'x)
  4716. /* Confirm on rename of files with extensions    0=not checked 1=checked */
  4717. res=SysIni('USER', 'PM_ControlPanel', 'ConfirmRenameFilesWithExt', '0']]'00'x)
  4718. /* Confirm on copy, move, create shadow          0=not checked 1=checked */
  4719. res=SysIni('USER', 'PM_ControlPanel', 'ConfirmCopyMoveEtc', '0']]'00'x)
  4720. /* Display progress indication dialog            0=not checked 1=checked */
  4721. res=SysIni('USER', 'PM_ControlPanel', 'DisplayProgressInd', '0']]'00'x)
  4722.  
  4723.  
  4724. ΓòÉΓòÉΓòÉ 5.8.1.2. Title ΓòÉΓòÉΓòÉ
  4725.  
  4726. To see the menu items that can be changed go to: 
  4727. OS/2 System / System Setup / System, Title tab 
  4728.  
  4729.  
  4730. /* Title clash */
  4731. /* Prompt for appropriate action  16 */
  4732. /* Auto-rename object             2  */
  4733. /* Replace existing object        8  */
  4734. result = SysIni('USER', 'PM_ControlPanel', 'NameClash', '16']]'00'x)
  4735.  
  4736.  
  4737. ΓòÉΓòÉΓòÉ 5.8.1.3. Button appearance for windows ΓòÉΓòÉΓòÉ
  4738.  
  4739. To see the menu items that can be changed go to: 
  4740. OS/2 System / System Setup / System, Window tab 
  4741.  
  4742.  
  4743. /* Hide button = 1 plus hex 0 */
  4744. result = SysIni('USER', 'PM_ControlPanel', 'MinButtonType', '1']]'00'x)
  4745. /* Minimize button = 2 plus hex 0 */
  4746. result = SysIni('USER', 'PM_ControlPanel', 'MinButtonType', '2']]'00'x)
  4747.  
  4748.  
  4749. ΓòÉΓòÉΓòÉ 5.8.1.4. Animation ΓòÉΓòÉΓòÉ
  4750.  
  4751.  
  4752. /* Enabled = hex 01 00 00 00 */
  4753. result = SysIni('USER', 'PM_ControlPanel', 'Animation', '01000000'x)
  4754. /* Disabled = hex 00 00 00 00 */
  4755. result = SysIni('USER', 'PM_ControlPanel', 'Animation', '00000000'x)
  4756.  
  4757.  
  4758. ΓòÉΓòÉΓòÉ 5.8.1.5. Minimize button behavior ΓòÉΓòÉΓòÉ
  4759.  
  4760.  
  4761. /* Hide Window = 1 plus hex 0 */
  4762. result = SysIni('USER', 'PM_ControlPanel', 'HiddenMinWindows', '1']]'00'x)
  4763. /* Minimize window to viewer = 2 plus hex 0 */
  4764. result = SysIni('USER', 'PM_ControlPanel', 'HiddenMinWindows', '2']]'00'x)
  4765. /* Minimize window to desktop = 3 plus hex 0 */
  4766. result = SysIni('USER', 'PM_ControlPanel', 'HiddenMinWindows', '3']]'00'x)
  4767.  
  4768.  
  4769. ΓòÉΓòÉΓòÉ 5.8.1.6. Object Open Behavior ΓòÉΓòÉΓòÉ
  4770.  
  4771.  
  4772. /* Display existing window; delete CCVIEW key */
  4773. result = SysIni('USER', 'PM_Workplace', 'CCVIEW', 'DELETE:')
  4774. /* Create new window; CCVIEW key set to 'ON' */
  4775. result = SysIni('USER', 'PM_Workplace', 'CCVIEW', 'ON']]'00'x)
  4776.  
  4777. To see the menu items that can be changed go to: OS/2 System / System Setup / 
  4778. System, Print Screen tab 
  4779.  
  4780.  
  4781. ΓòÉΓòÉΓòÉ 5.8.1.7. Print Screen ΓòÉΓòÉΓòÉ
  4782.  
  4783.  
  4784. /* Disable print screen */
  4785. result = SysIni('USER', 'PM_ControlPanel', 'PrintScreen', '0']]'00'x)
  4786. /* Enable print screen */
  4787. result = SysIni('USER', 'PM_ControlPanel', 'PrintScreen', '1']]'00'x)
  4788.  
  4789.  Logo
  4790.  
  4791.  To see the menu items that can be changed go to: 
  4792. OS/2 System / System Setup / System, Logo tab 
  4793.  
  4794.  
  4795. /* Indefinite */
  4796. result = SysIni('USER', 'PM_ControlPanel', 'LogoDisplayTime', '-1']]'00'x)
  4797. /* None */
  4798. result = SysIni('USER', 'PM_ControlPanel', 'LogoDisplayTime', '0']]'00'x)
  4799. /* Timed   Range: Seconds:0-59 Tenths: 0-9 */
  4800. /*  100  = 0 seconds 1 tenths              */
  4801. /* 2000  = 2 seconds 0 tenths (default)    */
  4802. /* 59900 = 59 seconds 9 tenths             */
  4803. result = SysIni('USER', 'PM_ControlPanel', 'LogoDisplayTime', '2000']]'00'x)
  4804.  
  4805.  Change color button 
  4806.  
  4807.  To see the menu items that can be changed hightlight your desktop, then use 
  4808. Open / Settings / Background tab 
  4809.  
  4810. Select the Values button to display the numeric values you'll need for the INI 
  4811. call. (Use the values when the RGB button is selected) 
  4812.  
  4813.  
  4814. /* Setting Desktop background color                  R   G   B          */
  4815. result = SysIni('USER', 'PM_Colors', 'Background', '204 204 204']]'00'x)
  4816.  
  4817. Note: Lots of other colors can be customized as well, review your \OS2\INI.RC 
  4818. file for the correct App and Key fields. 
  4819.  
  4820.  
  4821. ΓòÉΓòÉΓòÉ 5.8.1.8. Warning Beep ΓòÉΓòÉΓòÉ
  4822.  
  4823. To see the menu items that can be changed go to: 
  4824. OS/2 System / System Setup / Sound 
  4825.  
  4826.  
  4827. /* Turn off Warning Beep */
  4828. result = SysIni('USER', 'PM_ControlPanel', 'Beep', '0']]'00'x)
  4829. /* Turn on Warning Beep */
  4830. result = SysIni('USER', 'PM_ControlPanel', 'Beep', '1']]'00'x)
  4831.  
  4832.  
  4833. ΓòÉΓòÉΓòÉ 5.8.1.9. Note ΓòÉΓòÉΓòÉ
  4834.  
  4835. Remember: Most changes will not be reflected automatically. The next reboot 
  4836. should pick up your changes. These calls would be best used when first building 
  4837. a workstation, not for dynamic updates. 
  4838.  
  4839.  
  4840. ΓòÉΓòÉΓòÉ 5.8.2. Global WIN-OS2 Settings ΓòÉΓòÉΓòÉ
  4841.  
  4842.  With OS/2 V2.1 you are able to control certain WIN-OS/2 session properties for 
  4843. all Windows applications. You can locate this new control by going to: 
  4844.  
  4845. OS/2 System / System Setup / WIN-OS/2 Setup 
  4846.  
  4847. The changes you make here will be reflected for all newly created objects that 
  4848. use WIN-OS/2 settings. No setup string exists to change WIN_DDE, nor 
  4849. WIN_CLIPBOARD on a program by program basis. 
  4850.  
  4851.  
  4852. ΓòÉΓòÉΓòÉ 5.8.2.1. 3.1 Session tab ΓòÉΓòÉΓòÉ
  4853.  
  4854.  Key PM_Global31SessionType 
  4855.  
  4856.      Value 15 - WIN-OS/2 Window separate session (3.1 Standard) 
  4857.  
  4858.      Value 16 - WIN-OS/2 Window (3.1 Standard) 
  4859.  
  4860.      Value 17 - WIN-OS/2 Window separate session (3.1 Enhanced Compatibility) 
  4861.  
  4862.      Value 18 - WIN-OS/2 Window (3.1 Enhanced Compatibility) 
  4863.  
  4864.      Value 19 - WIN-OS/2 Full screen (3.1 Enhanced Compatibility) 
  4865.  
  4866.      Value 20 - WIN-OS/2 Full screen (3.1 Standard) 
  4867.  
  4868.  Example: 
  4869.  
  4870.  
  4871.   /* Set global session type to WIN-OS/2 Full screen (3.1 Standard) */
  4872.   result = SysIni('USER', 'WINOS2', 'PM_Global31SessionType', '20']]'00'x)
  4873.  
  4874.  
  4875. ΓòÉΓòÉΓòÉ 5.8.2.2. WIN-OS/2 Settings button ΓòÉΓòÉΓòÉ
  4876.  
  4877.  Key PM_GlobalWin31DataExchange 
  4878.  
  4879.      Value 0 - WIN_DDE On WIN_CLIPBOARD On 
  4880.  
  4881.      Value 4 - WIN_DDE Off WIN_CLIPBOARD On 
  4882.  
  4883.      Value 8 - WIN_DDE On WIN_CLIPBOARD Off 
  4884.  
  4885.      Value 12 - WIN_DDE Off WIN_CLIPBOARD Off 
  4886.   Example: 
  4887.  
  4888.  
  4889.   /* Set DDE on, Clipboard off */
  4890.   result = SysIni('USER', 'WINOS2', 'PM_GlobalWin31DataExchange', '8']]'00'x)
  4891.  
  4892.  Key PM_GlobalWindows31Settings 
  4893.  
  4894.      Need to supply the text of DOS, WIN settings separated by nul 0 character 
  4895.       AND the string ends with nul 0 nul 0 
  4896.   Example: 
  4897.  
  4898.  
  4899.   /* Default settings */
  4900.   setting='DPMI_MEMORY_LIMIT=64']]'00'x]],
  4901.           'PROGTYPE=PROG_31_STD']]'00'x]],
  4902.           'KBD_ALTHOME_BYPASS=1']]'00'x]],
  4903.           'VIDEO_SWITCH_NOTIFICATION=1']]'00'x]],
  4904.           'VIDEO_8514A_XGA_IOTRAP=0']]'00'x]]'00'x
  4905.   result = SysIni('USER', 'WINOS2', 'PM_GlobalWindows31Settings', setting)
  4906.  
  4907.  
  4908. ΓòÉΓòÉΓòÉ 5.8.2.3. Data Exchange tab ΓòÉΓòÉΓòÉ
  4909.  
  4910.  Data exchange between OS/2, DOS and WIN-OS/2 sessions 
  4911.  
  4912.    1. Dynamic data exchange  Key PM_DDESupport 
  4913.  
  4914.              -  Value 0 - Public (share with WIN-OS/2) 
  4915.  
  4916.              -  Value 1 - Private (non-share with WIN-OS/2) 
  4917.  
  4918.              -  Example: 
  4919.  
  4920.  
  4921.                                        /* Set DDE Private */
  4922.                                        result = SysIni('USER', 'WINOS2', 'PM_DDESupport', '1']]'00'x)
  4923.  
  4924.    2. Clipboard 
  4925.  
  4926.           Key PM_ClipboardSupport 
  4927.  
  4928.              -  Value 0 - Public (share with WIN-OS/2) 
  4929.  
  4930.              -  Value 1 - Private (non-share with WIN-OS/2) 
  4931.  
  4932.              -  Example: 
  4933.  
  4934.  
  4935.                                        /* Set Clipboard Private */
  4936.                                        result = SysIni('USER', 'WINOS2', 'PM_ClipboardSupport', '1']]'00'x)
  4937.  
  4938.  
  4939. ΓòÉΓòÉΓòÉ 6. Documentation for Various REXX Libraries ΓòÉΓòÉΓòÉ
  4940.  
  4941. This section contains the documentation for several REXX libraries available on 
  4942. the Internet. A good starting place is hobbes.nmsu.edu in the /os2/dev32/rexx 
  4943. directory. 
  4944.  
  4945.  
  4946. ΓòÉΓòÉΓòÉ 6.1. rxFTP ΓòÉΓòÉΓòÉ
  4947.  
  4948.                                  rxFtp
  4949.  
  4950.          Rexx Function Package for TCP/IP FTP for OS/2 2.0
  4951.  
  4952.                            by Patrick Mueller
  4953.  
  4954.    (c) Copyright International Business Machines Corporation 1993.
  4955.    All rights Reserved.
  4956.  
  4957.  
  4958. ΓòÉΓòÉΓòÉ 6.1.1. What is rxFtp? ΓòÉΓòÉΓòÉ
  4959.  
  4960. rxFtp is a REXX function package providing access to the OS/2 TCP/IP FTP API as 
  4961. provided by the IBM TCP/IP product, version 1.2.1. 
  4962.  
  4963. The function package assumes you know how to use the FTP program. The function 
  4964. names in the package closely resemble FTP subcommands. 
  4965.  
  4966. This function package requires the OS/2 TCP/IP product, version 1.2.1 or 
  4967. higher. A specific DLL for the OS/2 TCP/IP product, version 2.0, is included. 
  4968.  
  4969.  
  4970. ΓòÉΓòÉΓòÉ 6.1.2. Installation and Removal ΓòÉΓòÉΓòÉ
  4971.  
  4972. The rxFtp rexx function package is contained in the file rxFtp.dll. This file 
  4973. needs to be placed in a directory along your LIBPATH. To get access to the 
  4974. functions in the rxFtp function package, execute the following rexx code: 
  4975.  
  4976.    rc = RxFuncAdd("FtpLoadFuncs","rxFtp","FtpLoadFuncs")
  4977.    rc = FtpLoadFuncs()
  4978.  
  4979. If you want to use the 32-bit FTP functions available in TCP/IP for OS/2 
  4980. Version 2.0, rename the "rxftp32.dll" file to "rxftp.dll". 
  4981.  
  4982. You may not use both the 16-bit and 32-bit versions at the same time as they 
  4983. have the same function names. 
  4984.  
  4985. To unload the DLL, you should first call the FtpDropFuncs() function, then exit 
  4986. all CMD.EXE shells. After exiting all the command shells, the DLL will be 
  4987. dropped by OS/2 and can be deleted or replaced. 
  4988.  
  4989.  
  4990. ΓòÉΓòÉΓòÉ 6.1.3. Parameters and Return Values ΓòÉΓòÉΓòÉ
  4991.  
  4992.  
  4993. ΓòÉΓòÉΓòÉ 6.1.3.1. Set errors ΓòÉΓòÉΓòÉ
  4994.  
  4995. The following functions return Set error codes: 
  4996.  
  4997.      FtpSetUser 
  4998.  
  4999.      FtpSetBinary 
  5000.  
  5001.   The return code is 1 if the string passed in are valid, 0 if not. 
  5002.  FtpSetBinary() should be passed an abbreviation of "BINARY" or "ASCII" (thus, 
  5003.  "b", "as", "BIN", etc). 
  5004.  
  5005.  
  5006. ΓòÉΓòÉΓòÉ 6.1.3.2. FTP errors ΓòÉΓòÉΓòÉ
  5007.  
  5008. The rest of the functions (all the functions but the Set functions) return ftp 
  5009. error conditions. 
  5010.  
  5011. It will have one of the following values (or a numeric value if the number 
  5012. isn't one of these documented values): 
  5013.  
  5014.       "0"              - successful call
  5015.       "-1"             - Error during FTP function call
  5016.  
  5017.  If the function returns a "-1" for a return code, the variable FTPERRNO will 
  5018. be set to one of the following values: 
  5019.  
  5020.       "FTPSERVICE"     - unknown service
  5021.       "FTPHOST"        - unknown host
  5022.       "FTPSOCKET"      - unable to obtain socket
  5023.       "FTPCONNECT"     - unable to connect to server
  5024.       "FTPLOGIN"       - login failed
  5025.       "FTPABORT"       - transfer aborted
  5026.       "FTPLOCALFILE"   - problem openning local file
  5027.       "FTPDATACONN"    - problem initializing data connection
  5028.       "FTPCOMMAND"     - command failed
  5029.       "FTPPROXYTHIRD"  - proxy server does not support third party transfers
  5030.       "FTPNOPRIMARY"   - no primary connection for proxy transfer
  5031.  
  5032.  
  5033. ΓòÉΓòÉΓòÉ 6.1.4. Functions Reference ΓòÉΓòÉΓòÉ
  5034.  
  5035. This section lists the command syntax for each function and gives a description 
  5036. of it. 
  5037.  
  5038.  
  5039. ΓòÉΓòÉΓòÉ 6.1.4.1. FtpLoadFuncs ΓòÉΓòÉΓòÉ
  5040.  
  5041. rc = FtpLoadFuncs(quiet) 
  5042.  
  5043. Loads all the functions in the rxFtp package. 
  5044.  
  5045. If ANY parameters are passed to this function, it will bypass the 
  5046. program/author/copyright information normally displayed. All parameters are 
  5047. ignored (except to determine whether or not to bypass displaying the 
  5048. information). 
  5049.  
  5050.  
  5051. ΓòÉΓòÉΓòÉ 6.1.4.2. FtpDropFuncs ΓòÉΓòÉΓòÉ
  5052.  
  5053. rc = FtpDropFuncs() 
  5054.  
  5055. Drops all the functions in the rxFtp package. 
  5056.  
  5057.  
  5058. ΓòÉΓòÉΓòÉ 6.1.4.3. FtpVersion ΓòÉΓòÉΓòÉ
  5059.  
  5060. rc = FtpVersion(variable) 
  5061.  
  5062. Returns the version of RxFtp that you are running in the variable "variable". 
  5063.  
  5064.  
  5065. ΓòÉΓòÉΓòÉ 6.1.4.4. Set Functions ΓòÉΓòÉΓòÉ
  5066.  
  5067.      FtpSetUser(host,userid,password<,account>) 
  5068.  
  5069.      FtpSetBinary("Binary" | "Ascii") 
  5070.  
  5071.  FtpSetUser() sets the host, userid, and password for the remote host that most 
  5072.  of the other functions require. FtpSetBinary() sets the default text 
  5073.  translation for functions that can use this. This Binary or Ascii setting can 
  5074.  be overriden by any function that takes it as an option parameter. 
  5075.  
  5076.  Note that the host, userid, password, and account are retained during the life 
  5077.  of the process. If you are using the RxFtp package within a .CMD file run the 
  5078.  OS/2 prompt, this means the life of the CMD.EXE process. You may want to 
  5079.  'blank' out the password (at least) when you are finished, to prevent 
  5080.  unauthorized access to a host you previously used. 
  5081.  
  5082.  
  5083. ΓòÉΓòÉΓòÉ 6.1.4.5. File Functions ΓòÉΓòÉΓòÉ
  5084.  
  5085.      FtpAppend(localFile,remoteFile[,"Binary" | "Ascii"]) 
  5086.  
  5087.      FtpDelete(remoteFile) 
  5088.  
  5089.      FtpGet(localFile,remoteFile[,"Binary" | "Ascii"]) 
  5090.  
  5091.      FtpPut(localFile,remoteFile[,"Binary" | "Ascii"]) 
  5092.  
  5093.      FtpPutUnique(localFile,remoteFile[,"Binary" | "Ascii"]) 
  5094.  
  5095.      FtpRename(oldFile,newFile) 
  5096.  
  5097.  These functions perform work on files. The function should be obvious, except 
  5098.  for FtpPutUnique() which insures the remote file created is unique, and does 
  5099.  not overwrite the name of a file which already exists. 
  5100.  
  5101.  
  5102. ΓòÉΓòÉΓòÉ 6.1.4.6. Directory List Functions ΓòÉΓòÉΓòÉ
  5103.  
  5104.      FtpLs(pattern,stem) 
  5105.  
  5106.      FtpDir(pattern,stem) 
  5107.  
  5108.  These functions return directory list information in the stemmed variable 
  5109.  passed in. FtpLs() returns 'short' form; FtpDir() returns 'long' form. The 
  5110.  Stem value should be a string with a "." at the end. When the function 
  5111.  completes, the variable stem || ".0" will be set to the number of stem 
  5112.  variables returned, which are set in variables stem || ".1", stem || ".2", 
  5113.  etc. 
  5114.  
  5115.  
  5116. ΓòÉΓòÉΓòÉ 6.1.4.7. Directory Functions ΓòÉΓòÉΓòÉ
  5117.  
  5118.      FtpPwd(variable) 
  5119.  
  5120.      FtpChDir(directory) 
  5121.  
  5122.      FtpMkDir(directory) 
  5123.  
  5124.      FtpRmDir(directory) 
  5125.  
  5126.  These functions work with directories. The function should be obvious. 
  5127.  FtpPwd() returns the name of the current directory on the remote host if no 
  5128.  error occurred in the variable "variable" 
  5129.  
  5130.  
  5131. ΓòÉΓòÉΓòÉ 6.1.4.8. Logoff Function ΓòÉΓòÉΓòÉ
  5132.  
  5133. FtpLogoff() 
  5134.  
  5135. This function should be called to terminate all ftp sessions. 
  5136.  
  5137.  
  5138. ΓòÉΓòÉΓòÉ 6.1.4.9. Miscellaneous Functions ΓòÉΓòÉΓòÉ
  5139.  
  5140.      FtpQuote(quote) 
  5141.  
  5142.      FtpSite(site) 
  5143.  
  5144.      FtpSys(variable) 
  5145.  
  5146.  FtpQuote() and FtpSite() pass information to server as the "site" and "quote" 
  5147.  commands do. 
  5148.  
  5149.  FtpSys() returns the name of the operating system that server is running if no 
  5150.  error occurred in the variable "variable" 
  5151.  
  5152.  
  5153. ΓòÉΓòÉΓòÉ 6.1.4.10. Proxy Function ΓòÉΓòÉΓòÉ
  5154.  
  5155. FtpProxy(host,userid,password,account,pFile,rFile[,"Binary" | "Ascii"]) 
  5156.  
  5157. FtpProxy() copies a file from the named host/userid/password/account (account 
  5158. may be empty) to the host specified with the Set functions. pFile is name of 
  5159. the file on the named host/userid/password/account, rFile is the file on the 
  5160. host specified with the Set functions. 
  5161.  
  5162.  
  5163. ΓòÉΓòÉΓòÉ 6.1.5. Utilities Provided ΓòÉΓòÉΓòÉ
  5164.  
  5165.  miniftp.cmd 
  5166.            A test program demonstrating the use of the rxFtp package. 
  5167.  
  5168.  
  5169. ΓòÉΓòÉΓòÉ 6.2. rxSock ΓòÉΓòÉΓòÉ
  5170.  
  5171. rxSock -Rexx Function Package for TCP/IP Sockets for OS/2 2.0
  5172.  
  5173.    by Patrick Mueller (pmuellr@vnet.ibm.com)
  5174.  
  5175. (c) Copyright International Business Machines Corporation 1993.
  5176. All rights Reserved.
  5177.  
  5178.  
  5179. ΓòÉΓòÉΓòÉ 6.2.1. what is rxSock? ΓòÉΓòÉΓòÉ
  5180.  
  5181. rxSock is a REXX function package providing access to the OS/2 TCP/IP socket 
  5182. API as provided by the IBM TCP/IP product, version 1.2.1. 
  5183.  
  5184. The function reference below is minimalistic. It is assumed you are already 
  5185. familiar with the basic socket APIs, and can reference the OS/2 specific ones. 
  5186. A widely available book with information on the basic socket APIs is 
  5187. "Internetworking with TCP/IP Volume I: Principals, Protocols, and Architecture" 
  5188. by Douglas Comer. 
  5189.  
  5190. This function package requires the OS/2 TCP/IP product, version 1.2.1 or 
  5191. higher. 
  5192.  
  5193.  
  5194. ΓòÉΓòÉΓòÉ 6.2.2. Installation and Removal ΓòÉΓòÉΓòÉ
  5195.  
  5196. The rxSock rexx function package is contained in the file rxSock.dll. This file 
  5197. needs to be placed in a directory along your LIBPATH. To get access to the 
  5198. functions in the rxSock function package, execute the following rexx code: 
  5199.  
  5200.    rc = RxFuncAdd("SockLoadFuncs","rxSock","SockLoadFuncs")
  5201.    rc = SockLoadFuncs()
  5202.  
  5203. To unload the DLL, you should first call the SockDropFuncs() function, then 
  5204. exit all CMD.EXE shells. After exiting all the command shells, the DLL will be 
  5205. dropped by OS/2 and can be deleted or replaced. 
  5206.  
  5207.  
  5208. ΓòÉΓòÉΓòÉ 6.2.3. Parameters and Return Values ΓòÉΓòÉΓòÉ
  5209.  
  5210. Return values for most functions are the same as the C equivalents, unless 
  5211. otherwise noted. 
  5212.  
  5213. There are a number of standard parameters types referenced in the function 
  5214. reference. 
  5215.  
  5216.      socket 
  5217.       This is a socket value. It is an integral number. 
  5218.  
  5219.      domain 
  5220.       This is a domain value. The only currently supported domain is "AF_INET". 
  5221.  
  5222.      address 
  5223.       This is the 'stem' of a stemmed variable with the following values: 
  5224.  
  5225.         -  address.family 
  5226.            should always be "AF_INET" 
  5227.  
  5228.         -  address.port 
  5229.            a port number 
  5230.  
  5231.         -  address.addr 
  5232.            a dotted decimal address, or where appropriate, "INADDR_ANY" 
  5233.  
  5234.       When this parameter is needed you should set it the name of a stem 
  5235.       variable for the function to set (or that the function will read from). 
  5236.       For example, if you passed the string "xxx.!" as a parameter, the 
  5237.       variables 
  5238.  
  5239.                    "xxx.!family",
  5240.                    "xxx.!port", and
  5241.                    "xxx.!addr"
  5242.  
  5243.       will be set by the function, or queried by the function. 
  5244.  
  5245.      dotAddress 
  5246.       the standard dotted decimal address. For example, the string "9.23.19.63" 
  5247.       is a valid address. 
  5248.  
  5249.      host 
  5250.       This is the 'stem' of a stemmed variable with the following values: 
  5251.  
  5252.         -  host.name 
  5253.            the standard name of the host 
  5254.  
  5255.         -  host.alias.0 
  5256.            number of aliases for this host 
  5257.  
  5258.         -  host.alias.1 
  5259.            First alias for this host 
  5260.  
  5261.         -  host.alias.n 
  5262.            n'th alias for this host 
  5263.  
  5264.         -  host.addrtype 
  5265.            should always be "AF_INET" 
  5266.  
  5267.         -  host.addr 
  5268.            a dotted decimal address (default address) 
  5269.  
  5270.         -  host.addr.0 
  5271.            number of addresses for this host 
  5272.  
  5273.         -  host.addr.1 
  5274.            First address for this host 
  5275.  
  5276.         -  host.addr.n 
  5277.            n'th address for this host 
  5278.  
  5279.       When this parameter is needed you should set it the name of a stem 
  5280.       variable for the function to set (or that the function will read from). 
  5281.       For example, if you passed the string "xxx.!" as a parameter, the 
  5282.       variables 
  5283.  
  5284.                    "xxx.!name",
  5285.                    "xxx.!alias.0", "xxx.!alias.1" ... "xxx.!alias.n",
  5286.                    "xxx.!addrtype"
  5287.                    "xxx.!addr"
  5288.                    "xxx.!addr.0", "xxx.!addr.1" ... "xxx.!addr.n",
  5289.  
  5290.       will be set by the function, or queried by the function. 
  5291.  
  5292.  Special note on stemmed variables 
  5293.  
  5294.  The address and host type of parameters are stemmed variable names. 
  5295.  Traditionally, you would pass a string like "addr." as a parameter, and expect 
  5296.  to have the variables addr.family, addr.port, and addr.addr set by the 
  5297.  function. In the examples above though, I showed using a stem like "addr.!". 
  5298.  The exclamation point helps to distinguish the tail values, so they won't get 
  5299.  mis-used as normal variables. For instance, look at the following code: 
  5300.  
  5301.      port = 923
  5302.      sNew =  SockAccept(sOld,"addr.")
  5303.      say addr.port
  5304.  
  5305.  You might expect the say statement to write the port number of the accept'ed 
  5306.  socket. Instead it writes the value of the variable addr.923, since the port 
  5307.  variable is SET to a value. 
  5308.  
  5309.  Since you probably don't normally use exclamation points in your variables, 
  5310.  it's unlikely that you will be using the variable "!port" in your program. 
  5311.  
  5312.  Also note, some folk prefer other characters, including "_", "0", and "1" (the 
  5313.  digits are allowed to prefix tail values and are very secure against this kind 
  5314.  of accidental misuse - I don't use them because the characters are hard to 
  5315.  distinguish from O, I, and l). 
  5316.  
  5317.  
  5318. ΓòÉΓòÉΓòÉ 6.2.4. Variables set ΓòÉΓòÉΓòÉ
  5319.  
  5320.      errno 
  5321.       The errno variable is set after every rxSock function call. It will have 
  5322.       one of the following values (or a numeric value if the number isn't one 
  5323.       of these values, probably indicating an errno value the compiler that the 
  5324.       tcp/ip product was written in). Note the value is set even if the 
  5325.       function that was called does not neccessarily set the variable, in which 
  5326.       case the value has no meaning. The value 0 indicates no error occurred. 
  5327.  
  5328.                   "EWOULDBLOCK"
  5329.                   "EINPROGRESS"
  5330.                   "EALREADY"
  5331.                   "ENOTSOCK"
  5332.                   "EDESTADDRREQ"
  5333.                   "EMSGSIZE"
  5334.                   "EPROTOTYPE"
  5335.                   "ENOPROTOOPT"
  5336.                   "EPROTONOSUPPORT"
  5337.                   "ESOCKTNOSUPPORT"
  5338.                   "EOPNOTSUPP"
  5339.                   "EPFNOSUPPORT"
  5340.                   "EAFNOSUPPORT"
  5341.                   "EADDRINUSE"
  5342.                   "EADDRNOTAVAIL"
  5343.                   "ENETDOWN"
  5344.                   "ENETUNREACH"
  5345.                   "ENETRESET"
  5346.                   "ECONNABORTED"
  5347.                   "ECONNRESET"
  5348.                   "ENOBUFS"
  5349.                   "EISCONN"
  5350.                   "ENOTCONN"
  5351.                   "ESHUTDOWN"
  5352.                   "ETOOMANYREFS"
  5353.                   "ETIMEDOUT"
  5354.                   "ECONNREFUSED"
  5355.                   "ELOOP"
  5356.                   "ENAMETOOLONG"
  5357.                   "EHOSTDOWN"
  5358.                   "EHOSTUNREACH"
  5359.                   "ENOTEMPTY"
  5360.  
  5361.      h_errno 
  5362.       The h_errno variable is set after every rxSock function call. It will 
  5363.       have one of the following values (or a numeric value if the number isn't 
  5364.       one of these values). Note the value is set even if the function that was 
  5365.       called does not neccessarily set the variable, in which case the value 
  5366.       has no meaning. The value 0 indicates no error occurred. 
  5367.  
  5368.                   "HOST_NOT_FOUND"
  5369.                   "TRY_AGAIN"
  5370.                   "NO_RECOVERY"
  5371.                   "NO_ADDRESS"
  5372.  
  5373.  
  5374. ΓòÉΓòÉΓòÉ 6.2.5. Function Reference ΓòÉΓòÉΓòÉ
  5375.  
  5376. Most of the functions below correspond to their like-named C functions 
  5377. available in the OS/2 TCP/IP socket library. 
  5378.  
  5379.  
  5380. ΓòÉΓòÉΓòÉ 6.2.5.1. SockLoadFuncs ΓòÉΓòÉΓòÉ
  5381.  
  5382. rc = SockLoadFuncs() 
  5383.  
  5384. Loads all the functions in the rxSock package. 
  5385.  
  5386. If ANY parameters are passed to this function, it will bypass the 
  5387. program/author/copyright information normally displayed. All parameters are 
  5388. ignored (except to determine whether or not to bypass displaying the 
  5389. information). 
  5390.  
  5391.  
  5392. ΓòÉΓòÉΓòÉ 6.2.5.2. SockDropFuncs ΓòÉΓòÉΓòÉ
  5393.  
  5394. rc = SockDropFuncs() 
  5395.  
  5396. Drops all the functions in the rxSock package. 
  5397.  
  5398.  
  5399. ΓòÉΓòÉΓòÉ 6.2.5.3. SockVersion ΓòÉΓòÉΓòÉ
  5400.  
  5401. vers = SockVersion() 
  5402.  
  5403. Prior to version 1.2, this function did not exist. To check to see if a 
  5404. previous version of RxSock is installed, use the following code, after loading 
  5405. the function package with SockLoadFuncs(). 
  5406.  
  5407. /* oldVersion will be '1' if a version of RxSock < 1.2 is loaded */
  5408. oldVersion = (1 = RxFuncQuery("SockVersion"))
  5409.  
  5410.  
  5411. ΓòÉΓòÉΓòÉ 6.2.5.4. SockAccept ΓòÉΓòÉΓòÉ
  5412.  
  5413. Implements C function accept() 
  5414.  
  5415. socket = SockAccept(socket<,address>) 
  5416.  
  5417.  
  5418. ΓòÉΓòÉΓòÉ 6.2.5.5. SockBind ΓòÉΓòÉΓòÉ
  5419.  
  5420. Implements C function bind() 
  5421.  
  5422. rc = SockBind(socket,address) 
  5423.  
  5424.  
  5425. ΓòÉΓòÉΓòÉ 6.2.5.6. SockClose ΓòÉΓòÉΓòÉ
  5426.  
  5427. Implements C function soclose()/close() 
  5428.  
  5429. rc = SockClose(socket) 
  5430.  
  5431. Exactly the same as SockSoClose() 
  5432.  
  5433.  
  5434. ΓòÉΓòÉΓòÉ 6.2.5.7. SockConnect ΓòÉΓòÉΓòÉ
  5435.  
  5436. Implements C function connect() 
  5437.  
  5438. rc = SockConnect(socket,address) 
  5439.  
  5440.  
  5441. ΓòÉΓòÉΓòÉ 6.2.5.8. SockGetHostByAddr ΓòÉΓòÉΓòÉ
  5442.  
  5443. Implements C function gethostbyaddr() 
  5444.  
  5445. rc = SockGetHostByAddr(dotAddress,host<,domain>) 
  5446.  
  5447. Returns 1 for success, 0 for error. 
  5448.  
  5449.  
  5450. ΓòÉΓòÉΓòÉ 6.2.5.9. SockGetHostByName ΓòÉΓòÉΓòÉ
  5451.  
  5452. Implements C function gethostbyname() 
  5453.  
  5454. rc = SockGetHostByName(nameAddress,host) 
  5455.  
  5456. nameAddress should be the textual name of a host, for example 
  5457. "pmuellr.vnet.ibm.com". 
  5458.  
  5459. Returns 1 for success, 0 for error. 
  5460.  
  5461.  
  5462. ΓòÉΓòÉΓòÉ 6.2.5.10. SockGetHostId ΓòÉΓòÉΓòÉ
  5463.  
  5464. Implements C function gethostid() 
  5465.  
  5466. dotAddress = SockGetHostId() 
  5467.  
  5468.  
  5469. ΓòÉΓòÉΓòÉ 6.2.5.11. SockGetPeerName ΓòÉΓòÉΓòÉ
  5470.  
  5471. Implements C function getpeername() 
  5472.  
  5473. rc = SockGetPeerName(socket,address) 
  5474.  
  5475.  
  5476. ΓòÉΓòÉΓòÉ 6.2.5.12. SockGetSockName ΓòÉΓòÉΓòÉ
  5477.  
  5478. Implements C function getsockname() 
  5479.  
  5480. rc = SockGetSockName(socket,address) 
  5481.  
  5482.  
  5483. ΓòÉΓòÉΓòÉ 6.2.5.13. SockGetSockOpt ΓòÉΓòÉΓòÉ
  5484.  
  5485. Implements C function getsockopt() 
  5486.  
  5487. rc = SockGetSockOpt(socket,level,optVar,optVal) 
  5488.  
  5489. The only valid value for level is "SOL_SOCKET" 
  5490.  
  5491. optVar may be one of the following: 
  5492.  
  5493.       "SO_BROADCAST"
  5494.       "SO_DEBUG"
  5495.       "SO_DONTROUTE"
  5496.       "SO_ERROR"
  5497.       "SO_KEEPALIVE"
  5498.       "SO_LINGER"
  5499.       "SO_OOBINLINE"
  5500.       "SO_RCVBUF"
  5501.       "SO_RCVLOWAT"
  5502.       "SO_RCVTIMEO"
  5503.       "SO_REUSEADDR"
  5504.       "SO_SNDBUF"
  5505.       "SO_SNDLOWAT"
  5506.       "SO_SNDTIMEO"
  5507.       "SO_TYPE"
  5508.       "SO_USELOOPBACK"
  5509.  
  5510. optVal is the value of the option. Most of the options' values are integral. 
  5511. The exceptions are: 
  5512.  
  5513.  "SO_LINGER" 
  5514.            expects two blank delimited integers - the first is the l_onoff 
  5515.            value, the second is the l_linger value. 
  5516.  "SO_TYPE" 
  5517.            a string of either "STREAM", "DGRAM", or "RAW" 
  5518.  
  5519.  
  5520. ΓòÉΓòÉΓòÉ 6.2.5.14. SockInit ΓòÉΓòÉΓòÉ
  5521.  
  5522. Implements C function sock_init() 
  5523.  
  5524. rc = SockInit() 
  5525.  
  5526. SockInit() is not strictly needed, as initialization is done for each RxSock 
  5527. function if initialization has not yet occurred. 
  5528.  
  5529.  
  5530. ΓòÉΓòÉΓòÉ 6.2.5.15. SockIoctl ΓòÉΓòÉΓòÉ
  5531.  
  5532. Implements C function ioctl() 
  5533.  
  5534. rc = SockIoctl(socket,ioctlCmd,ioctlData) 
  5535.  
  5536. ioctlCmd is the ioctl command to perform. Valid commands are: 
  5537.  
  5538.       "FIONBIO"
  5539.       "FIONREAD"
  5540.  
  5541. ioctlData is the command specific value. Values are: 
  5542.  
  5543.       "FIONBIO"   - "1" or "0"
  5544.       "FIONREAD"  - name of a variable to contain number of immediately readable bytes
  5545.  
  5546.  
  5547. ΓòÉΓòÉΓòÉ 6.2.5.16. SockListen ΓòÉΓòÉΓòÉ
  5548.  
  5549. Implements C function listen() 
  5550.  
  5551. rc = SockListen(socket,backlog) 
  5552.  
  5553.  
  5554. ΓòÉΓòÉΓòÉ 6.2.5.17. SockRecv ΓòÉΓòÉΓòÉ
  5555.  
  5556. Implements C function recv() 
  5557.  
  5558. rc = SockRecv(socket,var,len<,flags>) 
  5559.  
  5560. var is the name of a rexx variable the data should be received into. 
  5561.  
  5562. len is the maximum amount of data to read. 
  5563.  
  5564. flags is a blank delimited list of options: "MSG_OOB", "MSG_PEEK". 
  5565.  
  5566. Returns the return code from the recv() function. 
  5567.  
  5568.  
  5569. ΓòÉΓòÉΓòÉ 6.2.5.18. SockSelect ΓòÉΓòÉΓòÉ
  5570.  
  5571. Implements C function select() 
  5572.  
  5573. rc = SockSelect(reads,writes,excepts<,timeout>) 
  5574.  
  5575. reads, writes, and excepts are stem variables which are queried and set by this 
  5576. function. The stem.0 variable should contain the number of sockets, stem.1 the 
  5577. first socket, etc. Upon return, the stem variables will be reset to the sockets 
  5578. which are ready. For instance, 
  5579.  
  5580.        r.0 = 2
  5581.        r.1 = 101
  5582.        r.2 = 102
  5583.        w.0 = 1
  5584.        w.1 = 103
  5585.        e.0 = 0
  5586.  
  5587.        rc = SockSelect("r.","w.","e.")
  5588.  
  5589.        do i = 1 to r.0
  5590.           say "socket" r.i "is ready for reading."
  5591.        end
  5592.  
  5593. timeout is the number of seconds to wait before timing out. 0 should be used 
  5594. for polling behaviour (no waiting), and "" should be used to wait indefinitely. 
  5595. If no timeout value is passed, "" is assumed. The number must be integral (no 
  5596. fractional values) - if fractional values are required, this could be 
  5597. implemented - contact me. Non-numeric and negative numbers are considered 0. 
  5598.  
  5599. If any of the stem variables are "", or no parameter is passed, no sockets for 
  5600. that type will be checked. For instance, the SockSelect() call above could have 
  5601. been invoked as either of: 
  5602.  
  5603.        rc = SockSelect("r.","w.","")
  5604.        rc = SockSelect("r.","w.",)
  5605.  
  5606. The function call SockSelect(,,,x) results in the program pausing for x 
  5607. seconds. 
  5608.  
  5609. The return code from SockSelect() is the number of ready sockets or 0 if a 
  5610. timeout occurred. If a timeout occurred, the socket arrays are not modified. 
  5611.  
  5612.  
  5613. ΓòÉΓòÉΓòÉ 6.2.5.19. SockSend ΓòÉΓòÉΓòÉ
  5614.  
  5615. Implements C function send() 
  5616.  
  5617. rc = SockSend(socket,data<,flags>) 
  5618.  
  5619. data is a string of text to be sent on the sock. 
  5620.  
  5621. flags is a blank delimited list of options: 
  5622.  
  5623. "MSG_OOB", "MSG_DONTROUTE".
  5624.  
  5625. Returns the return code from the send() function. 
  5626.  
  5627.  
  5628. ΓòÉΓòÉΓòÉ 6.2.5.20. SockSetSockOpt ΓòÉΓòÉΓòÉ
  5629.  
  5630. Implements C function setsockopt() 
  5631.  
  5632. rc = SockSetSockOpt(socket,level,optVar,optVal) 
  5633.  
  5634. The only valid value for level is "SOL_SOCKET" 
  5635.  
  5636. optVar is the option to set. See SockGetSockOpt() for valid values. Some 
  5637. options listed in SockGetSockOpt() are not valid for SockSetSockOpt(). They 
  5638. are: 
  5639.  
  5640.       "SO_ERROR"
  5641.       "SO_TYPE"
  5642.  
  5643. optVal is the value to set the option to. The formats are the same as that of 
  5644. SockGetSockOpt(), except the actual value should be passed in, instead of a 
  5645. variable name. 
  5646.  
  5647.  
  5648. ΓòÉΓòÉΓòÉ 6.2.5.21. SockShutDown ΓòÉΓòÉΓòÉ
  5649.  
  5650. Implements C function shutdown() 
  5651.  
  5652. rc = SockShutDown(socket,how) 
  5653.  
  5654.  
  5655. ΓòÉΓòÉΓòÉ 6.2.5.22. SockSocket ΓòÉΓòÉΓòÉ
  5656.  
  5657. Implements C function socket() 
  5658.  
  5659. socket = SockSocket(domain,type,protocol) 
  5660.  
  5661. domain must be "AF_INET". 
  5662.  
  5663. type may be one of "SOCK_STREAM", "SOCK_DGRAM", or "SOCK_RAW" 
  5664.  
  5665. protocol may be one of "IPPROTO_UDP", "IPPROTO_TCP", or "0" 
  5666.  
  5667.  
  5668. ΓòÉΓòÉΓòÉ 6.2.5.23. SockSoClose ΓòÉΓòÉΓòÉ
  5669.  
  5670. Implements C function soclose()/close() 
  5671.  
  5672. rc = SockSoClose(socket) 
  5673.  
  5674.  
  5675. ΓòÉΓòÉΓòÉ 6.2.6. Utilities Provided ΓòÉΓòÉΓòÉ
  5676.  
  5677. This section lists the utilities provided with the rxSock package. 
  5678.  
  5679.  
  5680. ΓòÉΓòÉΓòÉ 6.2.6.1. killsock.cmd ΓòÉΓòÉΓòÉ
  5681.  
  5682.  This program takes socket numbers and closes them. Useful for terminating a 
  5683. stubborn server, or cleaning up after accidents. 
  5684.  
  5685.  Use "netstat -s" to get a list of currently open sockets. 
  5686.  
  5687.  
  5688. ΓòÉΓòÉΓòÉ 6.2.6.2. rnr.cmd ΓòÉΓòÉΓòÉ
  5689.  
  5690. A very basic news reader. Used to demonstrate a fairly complex application 
  5691. using rxSock functions. 
  5692.  
  5693.  
  5694. ΓòÉΓòÉΓòÉ 6.2.6.3. test_h.cmd ΓòÉΓòÉΓòÉ
  5695.  
  5696. A test program testing address to hostname conversions. 
  5697.  
  5698.  
  5699. ΓòÉΓòÉΓòÉ 6.2.6.4. test_c.cmd and test_s.cmd ΓòÉΓòÉΓòÉ
  5700.  
  5701. These program are test client/server programs. Start test_s.cmd in one session, 
  5702. and then test_c.cmd in another. The programs exchange data and print some 
  5703. timing information before quitting. The server and client can run across two 
  5704. different hosts. Pass the host name of the server as a parameter to test_c.cmd 
  5705.  
  5706.  
  5707. ΓòÉΓòÉΓòÉ 6.2.6.5. test*.cmd ΓòÉΓòÉΓòÉ
  5708.  
  5709. These test programs test other parts of the RxSock package. Not all that 
  5710. useful, unless you are looking for info on SockSelect(), SockIoctl(), 
  5711. Sock?etSockOpt() functions. 
  5712.  
  5713.  
  5714. ΓòÉΓòÉΓòÉ 6.2.7. History ΓòÉΓòÉΓòÉ
  5715.  
  5716. 08/05/93
  5717.    - version 1.3
  5718.    - fixed stupid bug in SockGetPeerName() and SockGetSockName()
  5719.  
  5720. 07/16/93
  5721.    - version 1.2
  5722.    - added SockVersion(), SockClose(), SockIoctl(), SockSelect(),
  5723.      SockGetSockOpt(), SockSetSockOpt()
  5724.    - changed documentation for SockGetHostByName() and SockGetHostByAddr()
  5725.      to reflect what the code actually does
  5726.    - now return a list of addresses per host instead of just one
  5727.  
  5728. 03/11/93
  5729.    - version 1.1
  5730.    - first release in OS/2 Employee Written Software program
  5731.    - simulataneous (or nearly) release on OS2TOOLS
  5732.  
  5733. distant past
  5734.    - version 1.0
  5735.