home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / RXINFO.ZIP / REXXINFO.TXT < prev   
Text File  |  1992-10-10  |  276KB  |  6,977 lines

  1.                           -----------------------------------
  2.                           THE OS/2 PROCEDURES LANGUAGE 2/REXX
  3.                           -----------------------------------
  4.  
  5.                                        CONTENTS
  6.  
  7.  
  8.      [Section numbers and section dividing lines are not part of the
  9.       REXX Information as presented in OS/2 2.0.  They have been added
  10.       to this file to enhance your ability to locate specific areas
  11.       of interest.]
  12.  
  13.  
  14.  1.0 Getting Started in REXX
  15.      1.1    Writing a REXX Procedure
  16.  
  17.  2.0 Using Fundamental REXX Elements
  18.      2.1    Comments
  19.      2.2    Strings
  20.      2.3    Instructions
  21.      2.4    OS/2 Commands
  22.      2.5    Assignments
  23.      2.6    Labels
  24.  
  25.  3.0 Working with Variables and Arithmetic
  26.      3.1    Variables
  27.      3.2    Value
  28.      3.3    Working with Arithmetic
  29.      3.4    Writing a REXX Arithmetic Procedure
  30.  
  31.  4.0 REXX Features
  32.      4.1    Making Decisions (IF  THEN)
  33.      4.2    The ELSE Instruction
  34.      4.3    SELECT, END, WHEN OTHERWISE, and NOP Instructions
  35.      4.4    True and False Operators
  36.      4.5    The Logical Operators, NOT, AND, OR
  37.  
  38.  5.0 Automating Repetitive Tasks - Using Loops
  39.      5.1    Repetitive Loops
  40.      5.2    Conditional Loops
  41.      5.3    Getting Out of Loops
  42.      5.4    Parsing Words
  43.  
  44.  6.0 Advanced REXX Functions
  45.      6.1    Functions
  46.      6.2    DATATYPE( )
  47.      6.3    SUBSTR( )
  48.      6.4    CALL
  49.      6.5    REXX.CMD File Commands
  50.      6.6    Error Messages
  51.  
  52.  7.0 PMREXX and REXXTRY
  53.      7.1    Starting the PMREXX Program
  54.      7.2    The PMREXX Trace Function
  55.      7.3    The REXXTRY Program
  56.  
  57.  8.0 REXX Utility Functions (RexxUtil)
  58.      8.1    RxMessageBox
  59.      8.2    SysCls
  60.      8.3    SysCurPos
  61.      8.4    SysCurState
  62.      8.5    SysDriveInfo
  63.      8.6    SysDriveMap
  64.      8.7    SysDropFuncs
  65.      8.8    SysFileDelete
  66.      8.9    SysFileTree
  67.      8.10   SysFileSearch
  68.      8.11   SysGetKey
  69.      8.12   SysGetMessage
  70.      8.13   SysIni
  71.      8.14   SysMkDir
  72.      8.15   SysOS2Ver
  73.      8.16   SysRmDir
  74.      8.17   SysSearchPath
  75.      8.18   SysSleep
  76.      8.19   SysTempFileName
  77.      8.20   SysTextScreenRead
  78.      8.21   SysTextScreenSize
  79.      8.22   SysGetEA
  80.      8.23   SysPutEA
  81.      8.24   SysWaitNamedPipe
  82.      8.25   SysSetIcon
  83.      8.26   SysRegisterObjectClass
  84.      8.27   SysDeregisterObjectClass
  85.      8.28   SysCreateObject
  86.      8.29   SysQueryClassList
  87.  
  88.  9.0 Keyword Instruction
  89.      9.1    ADDRESS
  90.      9.2    ARG
  91.      9.3    CALL
  92.      9.4    DO
  93.      9.5    DROP
  94.      9.6    EXIT
  95.      9.7    IF
  96.      9.8    INTERPRET
  97.      9.9    ITERATE
  98.      9.10   LEAVE
  99.      9.11   NOP
  100.      9.12   NUMERIC
  101.      9.13   OPTIONS
  102.      9.14   PARSE
  103.      9.15   PROCEDURE
  104.      9.16   PULL
  105.      9.17   PUSH
  106.      9.18   QUEUE
  107.      9.19   RETURN
  108.      9.20   SAY
  109.      9.21   SELECT
  110.      9.22   SIGNAL
  111.      9.23   TRACE
  112.  
  113. 10.0 Functions
  114.      10.1   ABBREV
  115.      10.2   ABS (Absolute Value)
  116.      10.3   ADDRESS
  117.      10.4   API Functions
  118.      10.5   ARG
  119.      10.6   BEEP
  120.      10.7   BITAND
  121.      10.8   BITOR
  122.      10.9   BITXOR
  123.      10.10  B2X (Binary to Hexadecimal)
  124.      10.11  CENTER/CENTRE
  125.      10.12  CHARIN
  126.      10.13  CHAROUT
  127.      10.14  CHARS
  128.      10.15  COMPARE
  129.      10.16  CONDITION
  130.      10.17  COPIES
  131.      10.18  C2D (Character to Decimal)
  132.      10.19  C2X (Character to Hexadecimal)
  133.      10.20  DATATYPE
  134.      10.21  DATE
  135.      10.22  DELSTR (Delete String)
  136.      10.23  DELWORD
  137.      10.24  DIGITS
  138.      10.25  D2C (Decimal to Character)
  139.      10.26  D2X (Decimal to Hexadecimal)
  140.      10.27  DIRECTORY
  141.      10.28  ERRORTEXT
  142.      10.29  ENDLOCAL
  143.      10.30  FILESPEC
  144.      10.31  FORM
  145.      10.32  FORMAT
  146.      10.33  FUZZ
  147.      10.34  INSERT
  148.      10.35  LASTPOS
  149.      10.36  LEFT
  150.      10.37  LENGTH
  151.      10.38  LINEIN
  152.      10.39  LINEOUT
  153.      10.40  LINES
  154.      10.41  MAX
  155.      10.42  MIN
  156.      10.43  OVERLAY
  157.      10.44  POS
  158.      10.45  QUEUED
  159.      10.46  RANDOM
  160.      10.47  REVERSE
  161.      10.48  RIGHT
  162.      10.49  SETLOCAL
  163.      10.50  SIGN
  164.      10.51  SOURCELINE
  165.      10.52  SPACE
  166.      10.53  STREAM
  167.      10.54  STRIP
  168.      10.55  SUBSTR
  169.      10.56  SUBWORD
  170.      10.57  SYMBOL
  171.      10.58  TIME
  172.      10.59  TRACE      10.60  TRANSLATE
  173.      10.61  TRUNC
  174.      10.62  VALUE
  175.      10.63  VERIFY
  176.      10.64  WORD
  177.      10.65  WORDINDEX
  178.      10.66  WORDLENGTH
  179.      10.67  WORDPOS
  180.      10.68  WORDS
  181.      10.69  XRANGE
  182.      10.70  X2B (Hexadecimal to Binary)
  183.      10.71  X2C (Hexadecimal to Character)
  184.      10.72  X2D (Hexadecimal to Decimal)
  185.  
  186. 11.0 Queue Interface
  187.      11.1   RXQUEUE Function
  188.  
  189.  
  190.  
  191.  
  192.  
  193.         NOTE:  In the Keyword Instructions section, the flow diagrams are typed using
  194.                a 'V' as a substitute for a down arrowhead.
  195.  
  196.                The PM version of REXX Information contains flow diagrams to illustrate
  197.                the flows in decision and loop programs.  The 'Copy to File' text
  198.                version does not have those diagrams.
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.                 This text copy of REXX Information was transcribed from
  224.                the 'Copy to File'/'Append to File' output options of the
  225.                          OS/2 2.0 IPF for REXX Information by
  226.                       D. MacArthur Eld, Compuserve ID 71064,1215
  227.                                     October 4, 1992
  228. =======================================================================================
  229.                           -----------------------------------
  230.                           THE OS/2 PROCEDURES LANGUAGE 2/REXX
  231.                           -----------------------------------
  232.  
  233. The OS/2* Procedures Language 2/REXX (referred to as REXX for the rest of this
  234. information) is designated as the Systems Application Architecture* Procedures Language
  235. for the Office Vision family of products and the OS/2 operating system.  It was
  236. designed to make programming easier to write and debug.  High-quality programming can
  237. now be achieved using common English words in a natural syntax flow that both beginning
  238. and experienced programmers can understand.
  239.  
  240. REXX uses a few powerful, general-purpose programming functions and common
  241. arithmetical abilities, as well as OS/2 commands, within a simple framework.  Existing
  242. batch files can be converted to REXX procedures, with more power and function.
  243.  
  244. REXX files only operate in OS/2 sessions, must have a file name extension of .CMD,
  245. and must start with a comment line (/*....*/).  As in batch files, it is not necessary
  246. to type the .CMD extension to start a REXX procedure.
  247.  
  248. This Information:
  249.  
  250. This online REXX information is designed to acquaint you with the REXX language, show
  251. you some of its features and capabilities, and give you a  basic understanding of how
  252. it works.  The sections from "Getting Started.." to "PMREXX" are written as an
  253. overview, stressing general concept information, while the sections on "Instructions"
  254. and "Functions" include specific information about all of the instructions and
  255. functions that are part of REXX. For more complete and detailed information about REXX,
  256. see the OS/2 Procedures Language 2/REXX Reference or User's Guide.
  257.  
  258. =======================================================================================
  259. SECTION 1       Getting Started in REXX
  260.  
  261. A REXX procedure is a program that consists of a series of tasks in one common
  262. processing file or batch file.
  263.  
  264. Many languages can be used to write programs. BASIC, which is widely used in home
  265. computing, has very few rules, but it requires writing many lines of code for an
  266. intricate program.  Languages such as PL/1, COBOL, C, APL, and PASCAL have more rules,
  267. but allow you to write more functions in fewer lines.
  268.  
  269. REXX combines the simplicity of a programming language such as BASIC with features
  270. that exist in more powerful languages such as writing fewer lines.  It is easier to
  271. learn, because it uses familiar words and concepts.  REXX allows you to do simple
  272. tasks, yet has the ability to handle complex tasks.
  273.  
  274. To get started in REXX, you need:
  275.  
  276.   A Personal Computer with OS/2 Version 2.0 installed.  REXX works only in OS/2
  277.   sessions.
  278.   Knowledge about using a text editor.
  279.  
  280. Many of us learn by looking at examples, so examples of REXX procedures are provided
  281. in this presentation. First look at the procedure, then study the explanation of the
  282. examples to see what the procedure contains.  If you like, try the procedure to see how
  283. it works.
  284.  
  285.  
  286. =======================================================================================
  287. 1.1    Writing a REXX Procedure
  288.  
  289. We shall write the following REXX procedure using a text editor. To write a REXX
  290. procedure named HELLO.CMD while using the text editor follow these instructions:
  291.  
  292.  1. Create a text file named HELLO.CMD.
  293.  
  294.  2. Type the procedure HELLO.CMD, as follows:
  295.  
  296.     /* An introduction to REXX */
  297.     SAY "Hello! I am REXX"
  298.     SAY "What is your name?"
  299.     PULL who
  300.      IF who = ""
  301.       THEN
  302.       SAY "Hello Stranger"
  303.      ELSE
  304.       SAY "Hello" who
  305.     EXIT
  306.  
  307.  3. Save the file and exit from the text editor.
  308.  
  309. Now you are ready to run the REXX procedure you have written.  Type the name of the
  310. procedure at the OS/2 command prompt and press Enter.
  311.  
  312. hello
  313.  
  314. When the procedure pauses, you can either type your name or press Enter to see the
  315. other response.
  316.  
  317. A brief description of each part of HELLO.CMD follows:
  318.  
  319. /* An introduction to REXX */   A comment explains what the procedure is about.  A
  320. comment starts with a /* and ends with a */.  All REXX procedures must start with a
  321. comment on line one and column one of the file.  The comment tells the command
  322. processor that the procedure being run is a REXX procedure and distinguishes it from
  323. simple batch files.
  324.  
  325. SAY "Hello! I am REXX." SAY "What is your name?"   These instructions cause
  326. the words between the quotation marks to be displayed on your screen.
  327.  
  328. PULL who   The PULL instruction reads the response entered from the keyboard and
  329. puts it into the system's memory.  Who is the name of the place in memory where the
  330. user's response is put.  Any name can be used with the PULL instruction.
  331.  
  332. IF who = " "   The IF instruction tests a condition.  The test in this example
  333. determines if who is empty.  It is empty if the user types a space and presses Enter or
  334. just presses Enter.
  335.  
  336. THEN   Specifies that the instruction that follows is to be run, if the tested
  337. condition is true.
  338.  
  339. SAY "Hello Stranger"   Displays Hello Stranger on the screen.
  340.  
  341. ELSE   Specifies that the instruction that follows is to be run if the tested condition
  342. is not true.
  343.  
  344. SAY "Hello" who   Displays Hello on the screen, followed by whatever is in who.
  345.  
  346. EXIT   This instruction causes the procedure to stop.
  347.  
  348. Here is what would happen if a person named Bill tried the HELLO program:
  349.  
  350. [C:\]hello
  351. Hello! I am REXX.
  352. What is your name?
  353.  
  354. Bill
  355.  
  356. Hello BILL
  357.  
  358. [C:\]
  359. If Bill does not type his name, but types a blank space, this happens:
  360.  
  361. [C:\]hello
  362. Hello! I am REXX.
  363. What is your name?
  364.  
  365. Hello Stranger
  366.  
  367. [C:\]
  368.  
  369. =======================================================================================
  370. SECTION 2       Using Fundamental REXX Elements
  371.  
  372. This section gives you a chance to try some of the elements used in writing REXX
  373. procedures.  Do not worry about making mistakes because you will be guided through
  374. the steps.
  375.  
  376. Note:    When writing a REXX procedure, it is best to use one line for each element. If
  377.          you want an element to span more than one line, you must put a comma (,) at
  378.          the end of the line to indicate that the element continues on the next line. 
  379.          If you want to put more than one element on a line, you must use a semicolon
  380.          (;) to separate the elements.
  381.  
  382.          A REXX procedure can contain any or all of the following elements:
  383.  
  384.   Comments
  385.   Strings
  386.   Instructions
  387.   OS/2 Commands
  388.   Assignments
  389.   Labels
  390.   Internal Functions.
  391.  
  392. =======================================================================================
  393. 2.1    Comments
  394.  
  395. All REXX procedures must begin with a comment starting in column one of line one.
  396. The comment tells the command interpreter it is about to read and run a REXX
  397. procedure. The symbols for a comment are:
  398.  
  399. /*         To mark the start of a comment
  400.  
  401. */         To mark the end of a comment.
  402.  
  403. When the interpreter finds a /*, it stops interpreting; when it encounters a */, it
  404. begins interpreting again with the information following the symbol.  The comment can
  405. be a few words, no words, or several lines, as in the following examples:
  406.  
  407. /* This is a comment. */
  408.  
  409. or,
  410.  
  411. SAY "'Be Prepared!'" /* This comment is on the same line
  412. as the instruction and continues on to the next line */
  413.  
  414. You can use only /* */ to start a REXX procedure, but it is better to put a brief
  415. description of the procedure between the comment symbols.
  416.  
  417. The comment can indicate the purpose of the procedure, the kind of input it can handle,
  418. and the kind of output it produces. Comments help you understand the procedure when
  419. you read it later, perhaps to add to it, improve it, or use it elsewhere in the same
  420. procedure or another procedure.
  421.  
  422. When you write procedures, remember that others may need to use or modify them.  It
  423. is a good idea to add comments to the instructions so that anyone can understand each
  424. step.  If you do not use a procedure often, it is helpful to have reminders to aid your
  425. memory. In general, explain your procedure well enough so that others can understand
  426. it.
  427.  
  428. =======================================================================================
  429. 2.2    Strings
  430.  
  431. A string is any group of characters inside single or double quotation marks.  Either
  432. type of quotation marks can be used, but the beginning and the ending mark must match.
  433. The interpreter stops interpreting when it sees a quotation mark and the characters
  434. that follow remain as they were typed, with uppercase and lowercase letters.  The
  435. interpreter resumes interpreting when it sees a matching quotation mark.  For example:
  436.  
  437. 'The Greatest Show on Earth'
  438. "The President leads his country"
  439.  
  440. are both strings.
  441.  
  442. To use an apostrophe (single quotation mark) or double quotation marks within a string,
  443. use the other quotation mark around the whole string.  For example:
  444.  
  445. "Don't count your chickens before they hatch."
  446.  
  447. or
  448.  
  449. 'Do not count your "chickens" before they hatch.'
  450.  
  451. You also can use a pair of quotation marks (the same as those used to mark the string)
  452. as follows:
  453.  
  454. SAY "Mary said  ""He's here."""
  455.  
  456. This is interpreted by REXX as:
  457.  
  458. Mary said  "He's here."
  459.  
  460. =======================================================================================
  461. 2.3    Instructions
  462.  
  463. An instruction tells the system to do something.  Instructions can contain one or more
  464. assignments, labels, or commands and they usually start on a new line.  The following
  465. are explanations of some of the more common instructions.
  466.  
  467. SAY Instruction - The format for the SAY instruction is:
  468.  
  469. SAY expression
  470.  
  471. The expression can be something you want displayed on the screen or something to be
  472. computed, such as an equation:
  473.  
  474. SAY 5 + 6 "= eleven"
  475.  
  476. This displays
  477.  
  478. 11 = eleven
  479.  
  480. With the SAY instruction, anything not in quotation marks is changed to uppercase or is
  481. processed.  If you want something to appear exactly as it is typed, enclose it in
  482. quotation marks.
  483.  
  484. PULL and PARSE PULL Instructions -
  485.  
  486. In a procedure, the usual sequence of instructions is to use SAY to ask a question and
  487. PULL to receive the answer.  The response typed by the user is put into system memory.
  488. The following procedure does not work correctly if the PULL instruction comes before
  489. the SAY instruction.
  490.  
  491. Question:   What do you think happens when the following procedure, NAME.CMD, is
  492. run?
  493.  
  494. /* Using the PULL Instruction */
  495. SAY "Enter your name"
  496. PULL name          /* Puts response from user into memory */
  497. SAY "Hello" name
  498. EXIT
  499.  
  500. Answer:   NAME.CMD puts a name in memory and then displays that name anywhere in
  501. the file that the word name appears without the protection of single or double
  502. quotation marks.
  503.  
  504. If you tried the NAME procedure, you probably noticed that your name was changed to
  505. uppercase.  To keep the characters as you type them, use the PARSE PULL instruction.
  506. Here is an example called CHITCHAT.CMD that uses the PARSE PULL instruction:
  507.  
  508. /* Using the PARSE PULL Instruction */
  509. SAY "Hello! Are you still there?"
  510. SAY "I forgot your name.  What is it?"
  511. PARSE PULL name
  512. SAY name "Are you going to Richard's seminar?"
  513. PULL answer
  514. IF answer = "YES"
  515.  THEN
  516.  SAY "Good.  See you there!"
  517. IF answer = "NO"
  518.  THEN
  519.  SAY "Sorry,  We will miss your input."
  520. EXIT
  521.  
  522. The PARSE PULL instruction reads everything from the keyboard exactly as it is typed,
  523. in uppercase or lowercase.  In this procedure, the name is displayed just as you type
  524. it. However, answer is changed to uppercase characters because the PULL instruction was
  525. used.  This ensures that if yes, Yes, or YES is typed, the same action is taken.
  526.  
  527. EXIT Instruction
  528.  
  529. The EXIT instruction tells the procedure to end.  The EXIT instruction should be used
  530. in a procedure that contains subroutines.  Although the EXIT instruction is optional in
  531. some procedures, it is good programming practice to use it at the end of every
  532. procedure.
  533.  
  534. =======================================================================================
  535. 2.4    OS/2 Commands
  536.  
  537. A command is a word, phrase, or abbreviation that tells the system to do something.  In
  538. REXX, anything that is not a REXX instruction, assignment, or label is considered a
  539. command.  For example, you can use OS/2 commands such as COPY, BACKUP, PRINT,
  540. TYPE, and so on in your procedures.
  541.  
  542. Here is an example of using the OS/2 command, TYPE, in a REXX procedure:
  543.  
  544. /* Issuing commands in REXX */
  545. TYPE hello.cmd
  546. EXIT
  547.  
  548. This means that REXX will cause TYPE to be run.
  549.  
  550. =======================================================================================
  551. 2.5    Assignments
  552.  
  553. An assignment tells the system that a string should be put in a special place in system
  554. memory.  In the example:
  555.  
  556. Work = "Building 021"
  557.  
  558. the string Building 021 is stored as the value Work in system memory.  Because Work
  559. can have different values (be reassigned to mean different things) in different parts
  560. of the procedure, it is called a Variable.
  561.  
  562. =======================================================================================
  563. 2.6    Labels
  564.  
  565. A label is any word that is followed by a colon (with no space between the word and the
  566. colon) and is not in quotation marks.  For example:
  567.  
  568. MYNAME:
  569.  
  570. A label marks the start of a subroutine.  The following example shows one use of a
  571. label (called error) within a procedure:
  572.  
  573.   .
  574.   .
  575.   .
  576. IF problem  = 'yes' then SIGNAL error
  577.   .
  578.   .
  579.   .
  580. error:
  581.    SAY 'Problem in your data'
  582.    EXIT
  583.  
  584. =======================================================================================
  585. SECTION 3       Working with Variables and Arithmetic
  586.  
  587. In this section, you will see how to use variables and arithmetic and how to add
  588. comments throughout a procedure to describe how it works. Some of the topics in this
  589. section include the following:
  590.  
  591. Variable                     A piece of data given a unique name
  592.  
  593. Value                        Contents of a variable
  594.  
  595. Operators                    Symbols used for arithmetic functions
  596.  
  597. Addition                     + operator
  598.  
  599. Subtraction                  - operator
  600.  
  601. Multiplication               * operator
  602.  
  603. Division                     /, //, % operators
  604.  
  605. =======================================================================================
  606. 3.1    Variables
  607.  
  608. A variable is a piece of data with a varying value. Within a procedure, each variable
  609. is known by a unique name and is always referred to by that name.
  610.  
  611. When you choose a name for a variable, the first character must be one of:
  612.  
  613. A B C...Z ! ? _
  614.  
  615. Lowercase letters are also allowed as a first letter.  The interpreter changes them to
  616. uppercase.
  617.  
  618. The rest of the characters can be any of the preceding characters and also 0 through 9.
  619.  
  620. =======================================================================================
  621. 3.2    Value
  622.  
  623. The value of a variable can change, but the name cannot.  When you name a variable
  624. (give it a value), it is an assignment.  For example, any statement of the form,
  625.  
  626. symbol = expression
  627.  
  628. is an assignment statement.  You are telling the interpreter to compute what the
  629. expression is and put the result into a variable called a symbol.  It is the same as
  630. saying, "Let symbol be made equal to the result of expression" or every time symbol
  631. appears in the text of a SAY string unprotected by single or double quotation marks,
  632. display expression in its place.  The relationship between a variable and a value is
  633. like that between a post-office box and its contents; The box number does not change,
  634. but the contents of the box may be changed at any time.  Another example of an
  635. assignment is:
  636.  
  637. num1 = 10
  638.  
  639. The num1 assignment has the same meaning as the word symbol in the previous
  640. example, and the value 10 has the same meaning as the word expression.
  641.  
  642. One way to give the variable num1 a new value is by adding to the old value in the
  643. assignment: num1 = num1 + 3
  644.  
  645. The value of num1 has now been changed from 10 to 13.
  646.  
  647. A special concept in REXX is that any variable that is not assigned a value assumes the
  648. uppercase version of the variable as its initial value.  For example, if you write in a
  649. procedure,
  650.  
  651. list = 2 20 40
  652. SAY list
  653.  
  654. you see this on your screen:
  655.  
  656. 2 20 40
  657.  
  658. As you can see, list receives the values it is assigned.  But if you do not assign any
  659. value to list and only write,
  660.  
  661. SAY list
  662.  
  663. you see this on your screen:
  664.  
  665. LIST
  666.  
  667. Here is a simple procedure called VARIABLE.CMD that assigns values to variables:
  668.  
  669. /* Assigning a value to a variable */
  670. a = 'abc'
  671. SAY a
  672. b = 'def'
  673. SAY a b
  674. EXIT
  675.  
  676. When you run the VARIABLE procedure, it looks like this on your screen:
  677.  
  678. [C:\]VARIABLE
  679. abc
  680. abc def
  681.  
  682. [C:\]
  683.  
  684. Assigning values is easy, but you have to make sure a variable is not used
  685. unintentionally, as in this example named MEETING.CMD:
  686.  
  687. /* Unintentional interpretation of a variable */
  688. the='no'
  689. SAY Here is the person I want to meet
  690. EXIT
  691.  
  692. When the procedure is run, it looks like this:
  693.  
  694. [C:\]MEETING
  695. HERE IS no PERSON I WANT TO MEET
  696.  
  697. [C:\]
  698.  
  699. To avoid unintentionally substituting a variable for the word, put the sentence in
  700. quotation marks as shown in this example of MEETING.CMD, which assigns a variable
  701. correctly:
  702. /* Correct interpretation of a variable the*/
  703. the= 'no'
  704. SAY "Here is the person I want to meet"
  705. EXIT
  706.  
  707. =======================================================================================
  708. 3.3    Working with Arithmetic
  709.  
  710. Your REXX procedures may need to include arithmetic operations of addition,
  711. subtraction, multiplication, and division.  For example, you may want to assign a
  712. numeric value to two variables and then add the variables.
  713.  
  714. Arithmetic operations are performed the usual way.  You can use whole numbers and
  715. decimal fractions.  A whole number is an integer, or any number that is a natural
  716. number, either positive, negative, or zero, that does not contain a decimal part (for
  717. example, 1, 25, or 50).  A decimal fraction contains a decimal point (for example, 1.45
  718. or 0.6).
  719.  
  720. Before you see how these four operations are handled in a procedure, here is an
  721. explanation of what the operations look like and the symbols used.  These are just a
  722. few of the arithmetic operations used in REXX.
  723.  
  724. Note:    The examples contain a blank space between numbers and operators so that
  725.          you can see the equations better, but the blank is optional.
  726.  
  727. Operators - The symbols used for arithmetic (+ , -, *, /) are called operators because
  728. they operate on the adjacent terms.  In the following example, the operators act on the
  729. numbers (terms) 4 and 2:
  730.  
  731. SAY 4 + 2             /* says "6" */
  732. SAY 4 * 2             /* says "8" */
  733. SAY 4 / 2             /* says "2" */
  734.  
  735. Addition - The operator for addition is the plus sign (+).  An instruction to add two
  736. numbers is:
  737.  
  738. SAY 4 + 2
  739.  
  740. The answer you see on your screen is 6.
  741.  
  742. Subtraction - The operator for subtraction is the minus sign (-).  An instruction to
  743. subtract two numbers is:
  744.  
  745. SAY 8 - 3
  746.  
  747. The answer on your screen is 5.
  748.  
  749. Multiplication - The operator for multiplication is the asterisk (*).  An instruction
  750. to multiply two numbers is:
  751.  
  752. SAY 2 * 2
  753.  
  754. The answer on your screen is 4.
  755.  
  756. Division - For division, there are several operators you can use, depending on whether
  757. or not you want the answer expressed as a whole number.  For example, for a simple
  758. division, the symbol is one slash (/). An instruction to divide is:
  759.  
  760. SAY 7 / 2
  761. The answer on your screen is 3.5.
  762.  
  763. To divide and return just a remainder, the operator is two slashes (//).  To divide,
  764. and return only the whole number portion of an answer and no remainder, the operator is
  765. the percent sign (%).
  766.  
  767. For examples showing you how to perform four arithmetic operations on variables, select
  768. the Examples pushbutton.
  769.  
  770. This sample procedure named MATH.CMD shows you how to perform four arithmetic
  771. operations on variables:
  772.  
  773. /* Performing arithmetic operations on variables */
  774. a = 4
  775. b = 2
  776. c = a + b
  777. SAY 'The result of 'a '+' b 'is' c
  778. SAY
  779. c = a * b
  780. SAY 'The result of ' a '*' b 'is' c
  781. SAY
  782. c = a - b
  783. SAY 'The result of ' a '-' b 'is' c
  784. SAY
  785. c = a / b
  786. SAY 'The result of 'a '/' b 'is' c
  787. EXIT
  788.  
  789. Your screen looks like this:
  790.  
  791. [C:\]MATH
  792. The result of 4 + 2 is 6
  793.  
  794. The result of 4 * 2 is 8
  795.  
  796. The result of 4 - 2 is 2
  797.  
  798. The result of 4 / 2 is 2
  799.  
  800. [C:\]
  801.  
  802. Evaluating Expressions - Expressions are normally evaluated from left to right.  An
  803. equation helps to illustrate this point.  Until now, you have seen equations with only
  804. one operator and two terms, such as 4 + 2.  Suppose you had this equation:
  805.  
  806. 9 - 5 + 4 =
  807.  
  808. The 9 - 5 would be computed first.  The answer, 4, would be added to 4 for a final
  809. value: 8.
  810.  
  811. Some operations are given priority over others.  In general, the rules of algebra apply
  812. to equations.  In this equation, the division is handled before the addition:
  813.  
  814. 10 + 8 / 2 =
  815.  
  816. The value is 14.
  817.  
  818. If you use parentheses in an equation, the interpreter evaluates what is in the
  819. parentheses first.
  820. For example:
  821.  
  822. (10 + 8) / 2 =
  823.  
  824. The value is 9.
  825.  
  826. =======================================================================================
  827. 3.4    Writing a REXX Arithmetic Procedure
  828.  
  829. The following is an exercise that will serve as a review of some of the rules used in
  830. the previous examples.  You are to write a procedure that adds two numbers.  Name the
  831. procedure ADD.CMD.
  832.  
  833. Here is a list of what you need to do in this procedure:
  834.  
  835.  1. Identify and describe the REXX procedure.
  836.  2. Tell the user to type numbers.
  837.  3. Read the numbers typed and put them into system memory.
  838.  4. Add two numbers and display the answer on the screen.
  839.  5.Tell the interpreter to leave the procedure.
  840.  
  841. There are many ways to write procedures to accomplish the same task.  To make it
  842. easier in this procedure, the user is asked for each number separately, then the
  843. numbers are added.  The following is the thought process you might use to write the
  844. procedure for ADD.CMD.
  845.  
  846.  1. First, what identifies a REXX procedure?  If you thought of a comment, you were
  847.     right.
  848.  2. Next, you need to tell the user to enter a number.  The SAY instruction prints a
  849.     message on your screen.
  850.  
  851.  3. If the number is entered, it needs to be put into computer memory. 
  852.     The PULL instruction collects a response and puts it in memory.
  853.  4. An instruction requesting a second number can look just like the first instruction;
  854.     the second number also needs to be put in memory.
  855.  5. The next instruction is similar to one in the MATH procedure.  In one statement, it
  856.     can tell the interpreter to add the two values in memory and display the sum on    
  857.     your screen.  This can be one instruction.  The instruction contains a string and  
  858.     addition operation.
  859.  6. Finally, the EXIT instruction is used to end the procedure.
  860.  7. If you want to test this program, type the procedure listed here and file it.
  861.  
  862.     /* This procedure adds two numbers */
  863.     SAY "Enter the first number."
  864.     PULL num1
  865.     SAY "Enter the second number."
  866.     PULL num2
  867.     SAY "The sum of the two numbers is" num1 + num2
  868.     EXIT
  869.  
  870. To test ADD.CMD, type ADD at the OS/2 command prompt and try some numbers. Here
  871. is what the procedure should look like when it is run, and your numbers are 3 and 12.
  872.  
  873. [C:\]ADD
  874. Enter the first number.
  875.  
  876. 3
  877.  
  878. Enter the second number.
  879.  
  880. 12
  881.  
  882. The sum of the two numbers is 15
  883.  
  884. [C:\]
  885.  
  886. =======================================================================================
  887. SECTION 4       REXX Features
  888.  
  889. Some features of REXX that you can use to write more intricate procedures will be
  890. discussed in this section.  You will see how to have a procedure make decisions by
  891. testing a value with the IF instruction.  You will also see how to compare values and
  892. determine if an expression is true or false. A brief description of the terms covered
  893. in this section follows below:
  894.  
  895. IF                           Used with THEN.  Checks if the expression is true.  Makes
  896.                              a decision about a single instruction.
  897.  
  898. THEN                         Identifies the instruction to be run if the expression is
  899.                              true.
  900.  
  901. ELSE                         Identifies the instruction to be run if the expression is
  902.                              false.
  903.  
  904. SELECT                       Tells the interpreter to select one of a number of        
  905.                      instructions.
  906.  
  907. WHEN                         Used with SELECT.  Identifies an expression to be tested.
  908.  
  909. OTHERWISE                    Used with SELECT.  Indicates the instruction to be run if
  910.                               expressions tested are false.
  911.  
  912. DO-END                       Indicates that a group of instructions should be run.
  913.  
  914. NOP                          Indicates that nothing is to happen for one expression.
  915.  
  916. Comparisons  > <  =          Indicates greater than, less than, equal to.
  917.  
  918. NOT Operator  ¬ or \         Changes the value of a term from true to false, or from   
  919.                           false to true.
  920.  
  921. AND Operator  &              Gives the value of true if both terms are true.
  922.  
  923. OR Operator  |               Gives the value of true unless both terms are false.
  924.  
  925. =======================================================================================
  926. 4.1    Making Decisions (IF  THEN)
  927.  
  928. In the procedures discussed in earlier sections, instructions were run sequentially. 
  929. In this section, you will see how you can control the order in which instructions are
  930. run. Depending upon the user's interaction with your procedure, you may choose not to
  931. run some of your lines of code.
  932.  
  933. Two instructions that let you make decisions in your procedures are the IF and SELECT
  934. instructions.  The IF instruction is similar to the OS/2 IF command-it lets you control
  935. whether the next instruction is run or skipped.  The SELECT instruction lets you choose
  936. one instruction to run from a group of instructions.
  937.  
  938. The IF instruction is used with a THEN instruction to make a decision. The interpreter
  939. runs the instruction if the expression is true; for example:
  940.  
  941. IF answer = "YES"
  942.  THEN
  943.  SAY "OK!"
  944. In the previous example, the SAY instruction is run only if answer has the value of
  945. YES. Grouping Instructions Using DO and END
  946.  
  947. To tell the interpreter to run a list of instructions after the THEN instruction, use:
  948.  
  949. DO
  950.    Instruction1
  951.    Instruction2
  952.    Instruction3
  953. END
  954.  
  955. The DO instruction and its END instruction tell the interpreter to treat any
  956. instructions between them as a single instruction.
  957.  
  958. =======================================================================================
  959. 4.2    The ELSE Instruction
  960.  
  961. ELSE identifies the instruction to be run if the expression is false.  To tell the
  962. interpreter to select from one of two possible instructions, use:
  963.  
  964. IF expression
  965.  THEN instruction1
  966. ELSE instruction2
  967.  
  968. You could include the IF-THEN-ELSE format in a procedure like this:
  969.  
  970. IF answer = 'YES'
  971.  THEN SAY 'OK!'
  972. ELSE SAY 'why not?'
  973. Try the next example, GOING.CMD, to see how choosing between two instructions works.
  974.  
  975. /* Using IF-THEN-ELSE */
  976. SAY "Are you going to the meeting?"
  977. PULL answer
  978. IF answer = "YES"
  979.  THEN
  980.  SAY "I'll look for you."
  981. ELSE
  982.  SAY "I'll take notes for you."
  983. EXIT
  984.  
  985. When this procedure is run, this is what you will see on your screen:
  986.  
  987. [C:\]GOING
  988. Are you going to the meeting?
  989.  
  990. yes
  991.  
  992. I'll look for you.
  993.  
  994. [C:\]
  995.  
  996.  
  997. =======================================================================================
  998. 4.3    SELECT, END, WHEN OTHERWISE, and NOP Instructions
  999.  
  1000. SELECT tells the interpreter to select one of a number of instructions.  It is used
  1001. only with WHEN, THEN, END, and sometimes, OTHERWISE.  The END instruction marks the
  1002. end of every SELECT group.  The SELECT instruction looks like this:
  1003.  
  1004. SELECT
  1005.    WHEN expression1
  1006.       THEN instruction1
  1007.    WHEN expression2
  1008.       THEN instruction2
  1009.    WHEN expression3
  1010.       THEN instruction3
  1011. ...
  1012. OTHERWISE
  1013.    instruction
  1014.    instruction
  1015.    instruction
  1016. END
  1017.  
  1018. Note:    An IF-THEN instruction cannot be used with a SELECT instruction unless it
  1019.          follows a WHEN or OTHERWISE instruction.  You can read this format as
  1020.          follows:
  1021.  
  1022.   If expression1 is true, instruction1 is run.  After this, processing continues with  
  1023.   the instruction following the END.  The END instruction signals the end of the SELECT
  1024.   instruction.
  1025.   If expression1 is false, expression2 is tested.  Then, if expression2 is true,
  1026.   instruction2 is run and processing continues with the instruction following the END.
  1027.   If, and only if, all of the specified expressions are false, then processing  
  1028. continues with the instruction following OTHERWISE.
  1029.  
  1030. This diagram shows the SELECT instruction:
  1031.  
  1032.     [Obviously, you can see that the diagram is not reproduced here.]
  1033.  
  1034. A DO-END instruction could be included inside a SELECT instruction as follows:
  1035.  
  1036. SELECT
  1037.    WHEN expression1 THEN
  1038.       DO
  1039.         instruction1
  1040.         instruction2
  1041.         instruction3
  1042.      END
  1043. .
  1044. .
  1045. .
  1046.  
  1047. You can use the SELECT instruction when you are looking at one variable that can have
  1048. several different values associated with it.  With each different value, you can set a
  1049. different condition.
  1050.  
  1051. For example, suppose you wanted a reminder of weekday activities.  For the variable
  1052. day, you can have a value of Monday through Friday.  Depending on the day of the week
  1053. (the value of the variable), you can list a different activity (instruction).  You
  1054. could use a procedure such as the following, SELECT.CMD, which chooses from several
  1055. instructions.
  1056.  
  1057. Note:    A THEN or ELSE instruction must be followed by an instruction.
  1058.  
  1059. /* Selecting weekday activities */
  1060. SAY 'What day is it today?'
  1061. Pull day
  1062. SELECT
  1063.    WHEN day = 'MONDAY'
  1064.       THEN
  1065.       SAY 'Model A board meeting'
  1066.    WHEN day = 'TUESDAY'
  1067.       THEN
  1068.       SAY "My Team Meeting"
  1069.    WHEN day = 'WEDNESDAY'
  1070.       THEN NOP                 /* Nothing happens here */
  1071.    WHEN day = 'THURSDAY'
  1072.       THEN
  1073.       SAY "My Seminar"
  1074.    WHEN day = 'FRIDAY'
  1075.       THEN
  1076.       SAY "My Book Review"
  1077. OTHERWISE
  1078.    SAY  "It is the weekend, anything can happen!"
  1079. END
  1080. EXIT
  1081.  
  1082. NOP Instruction: If you want nothing to happen for one expression, use the NOP (No
  1083. Operation) instruction, as shown in the previous example for Wednesday.
  1084.  
  1085. =======================================================================================
  1086. 4.4    True and False Operators
  1087.  
  1088. Determining if an expression is true or false is useful in your procedures.  If an
  1089. expression is true, the computed result is 1.  If an expression is false, the computed
  1090. result is 0.  The following shows some ways to check for true or false operators.
  1091.  
  1092. Comparisons - Some operators you can use for comparisons are:
  1093.  
  1094. >            Greater than
  1095.  
  1096. <            Less than
  1097.  
  1098. =            Equal to
  1099.  
  1100. Comparisons can be made with numbers or can be character-to-character.  Some
  1101. numeric comparisons are:
  1102.  
  1103. The value of 5 > 3 is 1      This result is true.
  1104.  
  1105. The value of 2.0 = 002 is 1 This result is true.
  1106.  
  1107. The value of 332 < 299 is 0 This result is false.
  1108.  
  1109. If the terms being compared are not numbers, the interpreter compares characters.  For
  1110. example, the two words (strings) airmail and airplane when compared character for
  1111. character have the first three letters the same.  Since m < p, airmail < airplane.
  1112.  
  1113. Equal - An equal sign (=) can have two meanings in REXX, depending on its position.
  1114. For example,
  1115.  
  1116. amount = 5              /* This is an assignment */
  1117.  
  1118. gives the variable amount, the value of 5. If an equal sign is in a statement other
  1119. than as an assignment, it means the statement is a comparison.  For example,
  1120.  
  1121. SAY amount = 5           /* This is a comparison  */
  1122.  
  1123. compares the value of amount with 5.  If they are the same, a 1 is displayed,
  1124. otherwise, a 0 is displayed.
  1125.  
  1126. For more examples of using comparisons, select the Examples pushbutton.
  1127.  
  1128. The following procedure, TF.CMD, uses comparisons and an equal expression to
  1129. determine if numeric expressions are true or false.
  1130.  
  1131. /* Determine if expression is true or false  */
  1132. /* 1 is true; 0 is false                     */
  1133. a = 4
  1134. b = 2
  1135. c = a > b
  1136. SAY 'The result of' a '>' b 'is' c
  1137. c = a < b
  1138. SAY 'The result of' a '<' b 'is' c
  1139. c = a = b
  1140. SAY 'The result of' a '=' b 'is' c
  1141. EXIT
  1142.  
  1143. When you run the procedure, it gives the following results:
  1144.  
  1145. [C:\]TF
  1146. The result of 4 > 2 is 1
  1147. The result of 4 < 2 is 0
  1148. The result of 4 = 2 is 0
  1149.  
  1150. [C:\]
  1151.  
  1152. =======================================================================================
  1153. 4.5    The Logical Operators, NOT, AND, OR
  1154.  
  1155. Logical operators can return only the values of 1 or 0.  The NOT operator (¬ or \) in
  1156. front of a term reverses its value either from true to false or from false to true.
  1157.  
  1158. SAY  \ 0         /* gives '1'         */
  1159. SAY  \ 1         /* gives '0'         */
  1160. SAY  \ (4 = 4)   /* gives '0'         */
  1161. SAY  \ 2         /* gives  a  syntax error      */
  1162.  
  1163. The AND operator (&) between two terms gives a value of true only if both terms are
  1164. true.
  1165.  
  1166. SAY ( 3 = 3 ) & ( 5 = 5 )   /* gives '1'                     */
  1167. SAY ( 3 = 4 ) & ( 5 = 5 )   /* gives '0'                     */
  1168. SAY ( 3 = 3 ) & ( 4 = 5 )   /* gives '0'                     */
  1169. SAY ( 3 = 4 ) & ( 4 = 5 )   /* gives '0'                     */
  1170.  
  1171. The OR operator ( | ) between two terms gives a value of true unless both terms are
  1172. false. Note:    Depending upon your Personal System keyboard and the code page you are
  1173.          using, you may not have the solid vertical bar to select. For this reason,
  1174.          REXX also recognizes the use of the split vertical bar as a logical OR symbol.
  1175.          Some keyboards may have both characters.  If so, they are not interchangeable;
  1176.          only the character that is equal to the ASCII value of 124 works as the
  1177.          logical OR. This type of mismatch can also cause the character on your screen
  1178.          to be different from the character on your keyboard.
  1179.  
  1180. SAY ( 3 = 3 ) | ( 5 = 5 )   /* gives '1'                     */
  1181. SAY ( 3 = 4 ) | ( 5 = 5 )   /* gives '1'                     */
  1182. SAY ( 3 = 3 ) | ( 4 = 5 )   /* gives '1'                     */
  1183. SAY ( 3 = 4 ) | ( 4 = 5 )   /* gives '0'                     */
  1184.  
  1185. For more examples of using the logical operators, select the Examples pushbutton.
  1186.  
  1187. The following procedure, AND.CMD, shows the AND operator checking for two true
  1188. statements.
  1189.  
  1190. /* Using the AND (&) Operator   */
  1191. /* 0 is false; 1 is true        */
  1192. a = 4
  1193. b = 2
  1194. c = 5
  1195. d = (a > b) & (b > c)
  1196. SAY 'The result of (a > b) & (b > c) is' d
  1197. d = (a > b) & (b < c)
  1198. SAY 'The result of (a > b) & (b < c) is' d
  1199. EXIT
  1200.  
  1201. When run on your system, AND.CMD displays the following on your screen as:
  1202.  
  1203. [C:\]AND
  1204. The result of (a > b) & (b > c) is 0
  1205. The result of (a > b) & (b < c) is 1
  1206.  
  1207. [C:\]
  1208.  
  1209. The following procedure, OR.CMD, shows the OR operator in a true statement unless
  1210. both values are false:
  1211.  
  1212. /* Using the OR (|) Operator    */
  1213. /* 0 is false; 1 is true        */
  1214. a = 4
  1215. b = 2
  1216. c = 5
  1217. d = (a > b) | (b > c)
  1218. SAY 'The result of (a > b) | (b > c) is' d
  1219. d = (a > b) | (b < c)
  1220. SAY 'The result of (a > b) | (b < c) is' d
  1221. EXIT
  1222.  
  1223. When run on your system, the procedure displays the following:
  1224.  
  1225. [C:\]OR
  1226. The result of (a > b) | (b > c) is 1
  1227. The result of (a > b) | (b < c) is 1
  1228.  
  1229. [C:\]
  1230.  
  1231. =======================================================================================
  1232. SECTION 5       Automating Repetitive Tasks - Using Loops
  1233.  
  1234. If you want to repeat several instructions in a procedure, you can use a loop.  Loops
  1235. often are used in programming because they condense many lines of instructions into a
  1236. group that can be run more than once.  Loops make your procedures more concise, and
  1237. with a loop, you can continue asking a user for input until the correct answer is
  1238. given.
  1239.  
  1240. With loops, you can keep adding or subtracting numbers until you want to stop.  You
  1241. can define how many times you want a procedure to handle an operation.  You will see
  1242. how to use simple loops to repeat instructions in a procedure.
  1243.  
  1244. The two types of loops you may find useful are repetitive loops and conditional loops.
  1245. Loops begin with a DO instruction and end with the END instruction.  The following is a
  1246. list of topics in this section:
  1247.  
  1248. DO num loop                  Repeats the loop a fixed number of times.
  1249.  
  1250. DO i=1 to 10 loop            Numbers each pass through the loop.  Sets a starting and
  1251.                              ending value for the variable.
  1252.  
  1253. DO WHILE                     Tests for true or false at the top of the loop. Repeats   
  1254.                           the loop if true.  If false, continues processing after      
  1255.                        END.
  1256.  
  1257. Do UNTIL                     Tests for true or false at the bottom of the loop. Repeats
  1258.                              the loop if false.  If true, continues processing after   
  1259.                           END.
  1260.  
  1261. LEAVE                        Causes the interpreter to exit a loop.
  1262.  
  1263. DO FOREVER                   Repeats instructions until the user says to quit.
  1264.  
  1265. Getting out of loops         Requires that you press the Ctrl+Break keys.
  1266.  
  1267. Parsing words                Assigns a different variable to each word in a group.
  1268.  
  1269. =======================================================================================
  1270. 5.1    Repetitive Loops
  1271.  
  1272. Simple repetitive loops can be run a number of times.  You can specify the number of
  1273. repetitions for the loop, or you can use a variable that has a changing value.
  1274.  
  1275. The following shows how to repeat a loop a fixed number of times.
  1276.  
  1277. DO num
  1278.    instruction1
  1279.    instruction2
  1280.    instruction3
  1281.    ...
  1282. END
  1283.  
  1284. The num is a whole number, which is the number of times the loop is to be run.
  1285.  
  1286. Here is LOOP.CMD, an example of a simple repetitive loop.
  1287.  
  1288. /* A simple loop */
  1289. DO 5
  1290.    SAY 'Thank-you'
  1291. END
  1292. EXIT
  1293.  
  1294. When you run the LOOP.CMD, you see this on your screen:
  1295.  
  1296. [C:\]loop
  1297. Thank-you
  1298. Thank-you
  1299. Thank-you
  1300. Thank-you
  1301. Thank-you
  1302.  
  1303. [C:\]
  1304.  
  1305. Another type of DO instruction is:
  1306.  
  1307. DO XYZ = 1 to 10
  1308.  
  1309. This type of DO instruction numbers each pass through the loop so you can use it as a
  1310. variable.  The value of XYZ changes (by 1) each time you pass through the loop.  The 1
  1311. (or some number) gives the value you want the variable to have the first time through
  1312. the loop.  The 10 (or some number) gives the value you want the variable to have the
  1313. last time through the loop.
  1314.  
  1315. NEWLOOP.CMD is an example of another loop:
  1316.  
  1317. /* Another loop */
  1318. sum = 0
  1319. DO XYZ = 1 to 7
  1320.    SAY 'Enter value' XYZ
  1321.    PULL value
  1322.    sum = sum + value
  1323. END
  1324. SAY 'The total is' sum
  1325. EXIT
  1326.  
  1327. Here are the results of the NEWLOOP.CMD procedure:
  1328.  
  1329. [C:\]newloop
  1330. Enter value 1
  1331.  
  1332. 2
  1333.  
  1334. Enter value 2
  1335.  
  1336. 4
  1337.  
  1338. Enter value 3
  1339.  
  1340. 6
  1341.  
  1342. Enter value 4
  1343.  
  1344. 8
  1345. Enter value 5
  1346.  
  1347. 10
  1348.  
  1349. Enter value 6
  1350.  
  1351. 12
  1352.  
  1353. Enter value 7
  1354.  
  1355. 14
  1356.  
  1357. The total is 56
  1358.  
  1359. [C:\]
  1360.  
  1361. When a loop ends, the procedure continues with the instruction following the end of the
  1362. loop, which is identified by END.
  1363.  
  1364. =======================================================================================
  1365. 5.2    Conditional Loops
  1366.  
  1367. Conditional loops are run when a true or false condition is met.  We will now look at
  1368. some instructions used for conditional loops:
  1369.  
  1370. DO WHILE and DO UNTIL: The DO WHILE and DO UNTIL instructions are run while or
  1371. until some condition is met.  A DO WHILE loop is:
  1372.  
  1373. DO WHILE expression
  1374.    instruction1
  1375.    instruction2
  1376.    instruction3
  1377. END
  1378.  
  1379. The DO WHILE instruction tests for a true or false condition at the top of the loop;
  1380. that is, before processing the instructions that follow. If the expression is true, the
  1381. instructions are performed.  If the expression is false, the loop ends and moves to the
  1382. instruction following END.
  1383.  
  1384. The following diagram shows the DO WHILE instruction:
  1385.  
  1386.     [Obviously, you can see that the diagram is not reproduced here.]
  1387.  
  1388. To see a procedure using a DO WHILE loop, select the Examples pushbutton.
  1389.  
  1390. A procedure using a DO WHILE loop is DOWHILE.CMD.  It tests for a true or false
  1391. condition at the top of the loop.
  1392.  
  1393. /* Using a DO WHILE loop */
  1394. SAY 'Enter the amount of money available'
  1395. PULL salary
  1396. spent = 0
  1397. DO WHILE spent < salary
  1398.    SAY 'Type in cost of item'
  1399.    PULL cost
  1400.    spent = spent + cost
  1401. END
  1402. SAY 'Empty pockets.'
  1403. EXIT
  1404. After running the DOWHILE procedure, you see this on your screen:
  1405.  
  1406. [C:\]dowhile
  1407. Enter the amount of money available
  1408. 100
  1409. Type in cost of item
  1410. 57
  1411. Type in cost of item
  1412. 24
  1413. Type in cost of item
  1414. 33
  1415. Empty pockets.
  1416. [C:\]
  1417.  
  1418. DO UNTIL: A DO UNTIL instruction differs from the DO WHILE because it processes the
  1419. body of instructions first, then evaluates the expression.  If the expression is false,
  1420. the instructions are repeated (a loop).  If the expression is true, the procedure ends
  1421. or moves to the next step outside the loop.
  1422.  
  1423. The DO UNTIL instruction tests at the bottom of the loop; therefore, the instructions
  1424. within the DO loop are run at least once.
  1425.  
  1426. An example of a DO UNTIL loop follows:
  1427.  
  1428. DO UNTIL expression
  1429.    instruction1
  1430.    instruction2
  1431.    instruction3
  1432.  
  1433. END
  1434.  
  1435. +The following diagram shows the DO UNTIL instruction:
  1436.  
  1437.     [Obviously, you can see that the diagram is not reproduced here.]
  1438.  
  1439. To see a procedure that uses a DO UNTIL loop, select the Examples pushbutton.
  1440.  
  1441. A procedure using a DO UNTIL loop is DOUNTIL.CMD.  It tests for a true or false
  1442. condition at the bottom of the loop:
  1443.  
  1444. /* Using a DO UNTIL loop */
  1445. SAY 'Enter the amount of money available'
  1446. PULL salary
  1447. spent = 0          /* Sets spent to a value of 0 */
  1448. DO UNTIL spent > salary
  1449.    SAY 'Type the cost of item'
  1450.    PULL cost
  1451.    spent = spent + cost
  1452. END
  1453. SAY 'Empty pockets.'
  1454. EXIT
  1455.  
  1456. When run, DOUNTIL.CMD displays on your screen as:
  1457.  
  1458. [C:\] DOUNTIL
  1459. Enter the amount of money available
  1460. 50
  1461. Type the cost of item
  1462. 37
  1463. Type the cost of item 14
  1464. Empty pockets.
  1465. [C:\]
  1466.  
  1467. LEAVE: You may want to end a loop before the ending conditions are met. You can
  1468. accomplish this with the LEAVE instruction.  This instruction ends the loop and
  1469. continues processing with the instruction following END. The following procedure,
  1470. LEAVE.CMD, causes the interpreter to end the loop.
  1471.  
  1472. /* Using the LEAVE instruction in a loop */
  1473. SAY 'enter the amount of money available'
  1474. PULL salary
  1475. spent = 0        /* Sets spent to a value of 0 */
  1476. DO UNTIL spent > salary
  1477.    SAY 'Type in cost of item or END to quit'
  1478.    PULL cost
  1479.       IF cost = 'END'
  1480.       THEN
  1481.       LEAVE
  1482.    spent = spent + cost
  1483. END
  1484. SAY 'Empty pockets.'
  1485. EXIT
  1486.  
  1487. DO FOREVER: There may be situations when you do not know how many times to
  1488. repeat a loop.  For example, you may want the user to type specific numeric data
  1489. (numbers to add together), and have the loop perform the calculation until the user
  1490. says to stop.  For such a procedure, you can use the DO FOREVER instruction with the
  1491. LEAVE instruction.
  1492.  
  1493. The following shows the simple use of a DO FOREVER ending when the user stops.
  1494.  
  1495. /* Using a DO FOREVER loop to add numbers */
  1496. sum = 0
  1497. DO FOREVER
  1498.    SAY 'Enter number or END to quit'
  1499.    PULL value
  1500.    IF value = 'END'
  1501.       THEN
  1502.       LEAVE  /* procedure quits when the user enters "end" */
  1503.    sum = sum + value
  1504. END
  1505. SAY 'The sum is ' sum
  1506. EXIT
  1507.  
  1508. =======================================================================================
  1509. 5.3    Getting Out of Loops
  1510.  
  1511. To stop most REXX procedures, press the Ctrl+Break keys. REXX recognizes Ctrl+Break
  1512. after finishing the current instruction. Occasionaly, if you try a procedure such as
  1513. the one that follows, you need to press Ctrl+Break and then Enter to get out of the
  1514. loop. 
  1515.  
  1516. /* Guess the secret password !  */
  1517. DO UNTIL answer = "Sesame"
  1518.    SAY "Please enter the password . . ."
  1519.    PULL answer
  1520. END
  1521. EXIT
  1522. If you are still unable to end the procedure, press the Alt+Esc keys to end the OS/2
  1523. session and stop the procedure.
  1524.  
  1525. =======================================================================================
  1526. 5.4    Parsing Words
  1527.  
  1528. The PULL instruction collects a response and puts it into system memory as a variable.
  1529. PULL also can be used to put each word from a group of words into a different variable.
  1530. In REXX, this is called parsing.  The variable names used in the next example are:
  1531. first, second, third, and rest.
  1532.  
  1533. SAY 'Please enter three or more words'
  1534. PULL first second third rest
  1535.  
  1536. Suppose you enter this as your response:
  1537.  
  1538. garbage in garbage out
  1539.  
  1540. When you press the Enter key, the procedure continues.  However, the variables are
  1541. assigned as follows:
  1542.  
  1543. The variable first is given the value GARBAGE.
  1544. The variable second is given the value IN.
  1545. The variable third is given the value GARBAGE.
  1546. The variable rest is given the value OUT.
  1547.  
  1548. In general, each variable receives a word, without blanks, and the last variable
  1549. receives the rest of the input, if any, with blanks. If there are more variables than
  1550. words, the extra variables are assigned the null, or empty, value.
  1551.  
  1552. =======================================================================================
  1553. SECTION 6       Advanced REXX Functions
  1554.  
  1555. As you become more skilled at programming, you may want to create procedures that do
  1556. more and run more efficiently.  Sometimes this means adding a special function to a
  1557. procedure or calling a subroutine.
  1558.  
  1559. In this section, we shall see how these functions can help to build a better foundation
  1560. in
  1561. REXX.
  1562.  
  1563. Functions                        Perform a computation and return a result.
  1564.  
  1565. DATATYPE( )                      An internal function that verifies that the data is a
  1566. specific
  1567.                                   type.
  1568.  
  1569. SUBSTR( )                        An internal function that selects part of a string.
  1570.  
  1571. CALL                             Causes the procedure to look for a subroutine label
  1572. and
  1573.                                   begin running the instructions following the label.
  1574.  
  1575. REXX.CMD File Commands           Treat commands as expressions.
  1576.  
  1577. Error Messages                   Tell you if the command runs correctly. If the
  1578. procedure
  1579.                                   runs correctly, no message is displayed.
  1580.  
  1581.  
  1582. =======================================================================================
  1583. 6.1    Functions
  1584.  
  1585. In REXX, a function call can be written anywhere in an expression.  The function
  1586. performs the requested computation and returns a result.  REXX then uses the result in
  1587. the expression in place of the function call.
  1588.  
  1589. Think of a function as:  You are trying to find someone's telephone number.  You call
  1590. the telephone operator and ask for the number.  After receiving the number, you call
  1591. the person.  The steps you have completed in locating and calling the person could be
  1592. labeled a function.
  1593.  
  1594. Generally, if the interpreter finds this in an expression,
  1595.  
  1596. name(expression)
  1597.  
  1598. it assumes that name is the name of a function being called.  There is no space
  1599. between the end of the name and the left parenthesis.  If you leave out the right
  1600. parenthesis, it is an error.
  1601.  
  1602. The expressions inside the parentheses are the arguments. An argument can itself be
  1603. an expression; the interpreter computes the value of this argument before passing it to
  1604. the function.  If a function requires more than one argument, use commas to separate
  1605. each argument.
  1606.  
  1607. Built-in Functions - Rexx has more than 50 built-in functions.  A dictionary of
  1608. built-in functions is in the Procedures Language 2/REXX Reference.
  1609.  
  1610. MAX is a built-in function that you can use to obtain the greatest number of a set of
  1611. numbers:
  1612.  
  1613. MAX(number, number, ...)
  1614.  
  1615. For example:
  1616.  
  1617.    MAX(2,4,8,6) = 8
  1618.    MAX(2,4+5,6) = 9
  1619.  
  1620. Note that in the second example, the 4+5 is an expression. A function call, like any
  1621. other expression, usually is contained in a clause as part of an assignment or
  1622. instruction.
  1623.  
  1624. =======================================================================================
  1625. 6.2    DATATYPE( )
  1626.  
  1627. When attempting to perform arithmetic on data entered from the keyboard, you can use
  1628. the DATATYPE( ) function to check that the data is valid.
  1629.  
  1630. This function has several forms.  The simplest form returns the word, NUM, if the
  1631. expression inside the parentheses ( ) is accepted by the interpreter as a number that
  1632. can be used in the arithmetic operation. Otherwise, it returns the word, CHAR. For
  1633. example:
  1634.  
  1635. The value of DATATYPE(56) is NUM
  1636. The value of DATATYPE(6.2) is NUM
  1637. The value of DATATYPE('$5.50') is CHAR
  1638. In the following procedure, DATATYPE.CMD, the internal REXX function, DATATYPE( ), is
  1639. used and the user is asked to keep typing a valid number until a correct one is typed.
  1640.  
  1641. /* Using the DATATYPE( ) Function */
  1642. DO UNTIL datatype(howmuch) = 'NUM'
  1643.  SAY 'Enter a number'
  1644.  PULL howmuch
  1645.   IF datatype (howmuch) = 'CHAR'
  1646.    THEN
  1647.    SAY 'That was not a number.  Try again!'
  1648. END
  1649. SAY 'The number you entered was' howmuch
  1650. EXIT
  1651.  
  1652. If you want the user to type only whole numbers, you could use another form of the
  1653. DATATYPE( ) function:
  1654.  
  1655. DATATYPE (number, whole)
  1656.  
  1657. The arguments for this form are:
  1658.  
  1659.   number -  refers to the data to be tested.
  1660.   whole -  refers to the type of data to be tested.  In this example, the data must be
  1661.   a whole number.
  1662.  
  1663. This form returns a 1 if number is a whole number, or a 0 otherwise.
  1664.  
  1665. =======================================================================================
  1666. 6.3    SUBSTR( )
  1667.  
  1668. The value of any REXX variable can be a string of characters.  To select a part of a
  1669. string, you can use the SUBSTR( ) function.  SUBSTR is an abbreviation for substring.
  1670. The first three arguments are:
  1671.  
  1672.   The string from which a part is taken.
  1673.   The position of the first character that is to be contained in the result (characters
  1674.   are numbered 1,2,3...in the string).
  1675.   The length of the result.
  1676. For example:
  1677.  
  1678. S = 'reveal'
  1679. SAY substr(S,2,3) /* Says 'eve'. Beginning with the second  */
  1680.                   /*  character, takes three characters.    */
  1681. SAY substr(S,3,4) /* Says 'veal'. Beginning with the third  */
  1682.                   /*  character, takes four characters.     */
  1683.  
  1684. =======================================================================================
  1685. 6.4    CALL
  1686.  
  1687. The CALL instruction causes the interpreter to search your procedure until a label is
  1688. found that marks the start of the subroutine. Remember, a label (word) is a symbol
  1689. followed by a colon (:).  Processing continues from there until the interpreter finds a
  1690. RETURN or an EXIT instruction.
  1691.  
  1692. A subroutine can be called from more than one place in a procedure. When the
  1693. subroutine is finished, the interpreter always returns to the instruction following the
  1694. CALL instruction from which it came.
  1695.  
  1696. Often each CALL instruction supplies data (called arguments or expressions) that the
  1697. subroutine is to use.  In the subroutine, you can find out what data has been supplied
  1698. by using the ARG instruction.
  1699.  
  1700. The CALL instruction is written in the following form:
  1701.  
  1702. CALL name  Argument1, Argument2 ...
  1703.  
  1704. For the name, the interpreter looks for the corresponding label (name) in your
  1705. procedure. If no label is found, the interpreter looks for a built-in function or a
  1706. .CMD file with that name.
  1707.  
  1708. The arguments are expressions.  You can have up to 20 arguments in a CALL
  1709. instruction.  An example of a procedure that calls a subroutine follows.  Note that the
  1710. EXIT instruction causes a return to the operating system. The EXIT instruction stops
  1711. the main procedure from continuing into the subroutine.
  1712.  
  1713. In the following example, REXX.CMD, the procedure calls a subroutine from a main
  1714. procedure.
  1715.  
  1716. /* Calling a subroutine from a procedure */
  1717. DO 3
  1718.   CALL triple 'R'
  1719.   CALL triple 'E'
  1720.   CALL triple 'X'
  1721.   CALL triple 'X'
  1722.   SAY
  1723. END
  1724. SAY 'R...!' SAY 'E...!'
  1725. SAY 'X...!'
  1726. SAY 'X...!'
  1727. SAY ' '
  1728. SAY 'REXX!'
  1729. EXIT          /* This ends the main procedure. */
  1730. /*                                                     */
  1731. /* Subroutine starts here to repeat REXX three times.  */
  1732. /* The first argument is displayed on screen three     */
  1733. /* times, with punctuation.                            */
  1734. /*                                                     */
  1735. TRIPLE:
  1736. SAY ARG(1)"    "ARG(1)"   "ARG(1)"!"
  1737. RETURN           /* This ends the subroutine.          */
  1738.  
  1739. When REXX.CMD is run on your system, the following is displayed:
  1740.  
  1741. [C:\]REXX
  1742. R   R   R!
  1743. E   E   E!
  1744. X   X   X!
  1745. X   X   X!
  1746.  
  1747. R   R   R!
  1748. E   E   E!
  1749. X   X   X!
  1750. X   X   X!
  1751.  
  1752. R   R   R!
  1753. E   E   E!
  1754. X   X   X!
  1755. X   X   X!
  1756.  
  1757. R...!
  1758. E...!
  1759. X...!
  1760. X...!
  1761.  
  1762. REXX!
  1763.  
  1764. [C:\]
  1765.  
  1766. =======================================================================================
  1767. 6.5    REXX.CMD File Commands
  1768.  
  1769. In a REXX procedure, anything not recognized as an instruction, assignment, or label is
  1770. considered a command.  The statement recognized as a command is treated as an
  1771. expression.  The expression is evaluated first, then the result is passed to the
  1772. operating
  1773. system.
  1774.  
  1775. The following example, COPYLIST.CMD, shows how a command is treated as an
  1776. expression.  Note how the special character (*) is put in quotation marks.
  1777. COPYLIST.CMD copies files from drive A to drive B.
  1778.  
  1779. /* Issuing a command from a procedure.  This example copies  */
  1780. /* all files that have an extension of.LST from              */
  1781. /* drive A to drive B.                                       */
  1782. SAY
  1783. COPY "a:*.lst b:"           /* This statement is treated as  */
  1784.                             /* an expression.                */
  1785.                             /* The result is passed to OS/2. */
  1786. EXIT
  1787.  
  1788. Note:    In the preceding example, the whole OS/2 command except for COPY is in
  1789.          quotation marks for the following reasons:
  1790.  
  1791.   If the colon (:) were not in quotation marks, the REXXSAA interpreter would treat a:
  1792.   and b: as labels.
  1793.   If the asterisk (*) were not in quotation marks, the REXXSAA interpreter would    
  1794. attempt to multiply the value of a: by .LST.
  1795.   It is also acceptable to include the entire OS/2 command in quotation marks so that
  1796.   "COPY a:*.LST b:" is displayed.
  1797.  
  1798. =======================================================================================
  1799. 6.6    Error Messages
  1800.  
  1801. There are two basic reasons errors occur when REXX is processing a procedure.
  1802.  
  1803. One reason is because of the way the procedure is written; for example, unmatched
  1804. quotation marks or commas in the wrong place.  Maybe an IF instruction was entered
  1805. without a matching THEN. When such an error occurs, a REXX error message is issued.
  1806.  
  1807. A second reason for an error to occur is because of an OS/2 command that the REXX
  1808. procedure has issued.  For example, a COPY command can fail because the user's disk
  1809. is full or a file cannot be found.  In this case, a regular OS/2 error message is
  1810. issued. When you write commands in your procedures, consider what might happen if the
  1811. command fails to run correctly.
  1812.  
  1813. When a command is issued from a REXX procedure, the command interpreter gets a
  1814. return code and stores it in the REXX special variable, RC (return code).  When you
  1815. write a procedure, you can test for these variables to see what happens when the
  1816. command is issued.
  1817.  
  1818. Here is how you discover a failure.  When commands finish running, they always provide
  1819. a return code.  A return code of 0 nearly always means that all is well.  Any other
  1820. number usually means that something is wrong. If the command worked normally (the
  1821. return code was 0), you see the command prompt:
  1822.  
  1823. [C:\]
  1824.  
  1825. and you return to the screen you ran your program from in Presentation Manager, or in
  1826. the PMREXX application you see printed under the last line of the procedure,
  1827.  
  1828. The REXX procedure has ended.
  1829.  
  1830. In the following example, ADD.CMD, there is an error in line 6; the plus sign (+) has
  1831. been typed incorrectly as an ampersand (&).
  1832.  
  1833. /* This procedure adds two numbers */
  1834. SAY "Enter the first number."
  1835. PULL num1
  1836. SAY "Enter the second number."
  1837. PULL num2
  1838. SAY "The sum of the two numbers is" num1 & num2
  1839. EXIT
  1840.  
  1841. When the above procedure, ADD.CMD, is run, the following error message is displayed.
  1842.  
  1843.     6+++ SAY "The sum of the two numbers is" num1 & num2
  1844. REX0034: Error 34 running C:\REXX\ADD.CMD,line 6:logical value not 0 or 1
  1845.  
  1846. To get help on the error message, type:
  1847.  
  1848. HELP REX0034
  1849.  
  1850. When help is requested, an error message such as the following is displayed:
  1851.  
  1852. REX0034 ***Logical Value not 0 or 1***
  1853.  
  1854. Explanation: The expression in an IF, WHEN, DO WHILE, or DO UNTIL
  1855.              phrase must result in a '0' or a '1', as must any
  1856.              term operated on by a logical operator.
  1857.  
  1858. Any command that is valid at the command prompt is valid in a REXX procedure.  The
  1859. command interpreter treats the command statement the same way as any other
  1860. expression, substituting the values of variables, and so on.  (The rules are the same
  1861. as for commands entered at the command prompt.)
  1862.  
  1863. Return Codes: When the command interpreter has issued a command and the
  1864. operating system has finished running it, the command interpreter gets the return code
  1865. and stores it in the REXX special variable RC (return code).  In your procedure, you
  1866. should test this variable to see what happens when the command is run.
  1867.  
  1868. The following example shows a few lines from a procedure where the return code is
  1869. tested:
  1870.  
  1871. /* Testing the Return Code in a Procedure. */
  1872. 'COPY a:*.lst b:'
  1873. IF rc = 0   /* RC contains the return code from the COPY command */
  1874. THEN
  1875.  SAY 'All *lst files copied'
  1876. ELSE
  1877.  SAY 'Error occurred copying files' =======================================================================================
  1878. SECTION 7       PMREXX and REXXTRY
  1879.  
  1880. PMREXX is a windowed Presentation Manager* application that enables you to browse
  1881. the output of your REXX procedures.  REXXTRY is a command that lets you interactively
  1882. run one or more REXX instructions.
  1883.  
  1884. By using PMREXX, you add the following features to REXX:
  1885.  
  1886.   A window for the display of the output of a REXX procedure, such as:
  1887.  
  1888.    -The SAY instruction output
  1889.    -The STDOUT and STDERR outputs from secondary processes started from a REXX
  1890.      procedures file
  1891.    -The REXX TRACE output (not to be confused with OS/2 tracing).
  1892.  
  1893.   An input window for:
  1894.  
  1895.    -The PULL instruction in all of its forms
  1896.    -The STDIN data for secondary processes started from a REXX procedures file.
  1897.  
  1898.   A browsing, scrolling, and clipboard capability for REXX output.
  1899.   A selection of fonts for the output window.
  1900.   A simple environment for experimenting with REXX instructions through the use of the
  1901.   REXXTRY.CMD program.  REXXTRY interactively interprets REXX instructions and can
  1902.   be started by typing REXXTRY or PMREXX REXXTRY at an OS/2 command prompt
  1903.  
  1904. =======================================================================================
  1905. 7.1    Starting the PMREXX Program
  1906.  
  1907. You can start the PMREXX program and a REXX procedure from an OS/2 command
  1908. prompt.  You do this by typing PMREXX and a target procedure name that generates an
  1909. output or input function, as follows:
  1910.  
  1911. PMREXX  filename.CMD arguments
  1912.  
  1913. where the arguments and .CMD extension are optional.
  1914.  
  1915. Here is a REXX program named SAMPLE.CMD that calls for system environment
  1916. variables to be displayed when the various arguments are indicated.
  1917.  
  1918. /**/
  1919. '@ECHO OFF'
  1920. env = 'OS2ENVIRONMENT'
  1921. Parse Arg all
  1922. Do i=1 to words(all)
  1923.    word = translate(word(all,i))
  1924.    Say
  1925.    If value(word,,env)=''
  1926.      Then Say '"'word'" is not in the environment!.'
  1927.      Else Say word'="'value(word,,env)'".'
  1928. End
  1929.  
  1930. To display the current PATH and DPATH statements in the CONFIG.SYS file in a
  1931. PMREXX window, type the following:
  1932.  
  1933. PMREXX Sample PATH DPATH
  1934.  
  1935. Note:    You can move or size the PMREXX.EXE window or select menu-bar choices,
  1936.          the same way that you do with other windows. Once the output of the REXX procedure is displayed in PMREXX, you can select the
  1937. menu-bar choices to take advantage of the following PMREXX browsing features:
  1938.  
  1939. Menu-Bar Choice            Description
  1940.  
  1941. File                       Save, Save As, and Exit the process
  1942.  
  1943. Edit                       Copy, Paste to the input, Clear the output, and Select All
  1944. lines
  1945.  
  1946. Options                    Restart the process, Interactive Trace, and Set font
  1947.  
  1948. Actions                    Halt procedure, Trace next clause, Redo the last clause, and
  1949.                             Set Trace off
  1950.  
  1951. Help                       Help index, General help, Keys help, and Using help.
  1952.  
  1953. =======================================================================================
  1954. 7.2    The PMREXX Trace Function
  1955.  
  1956. The trace function in PMREXX turns on interactive tracing for the currently operating
  1957. REXX procedure.  This is done by adding the /T parameter to the PMREXX command
  1958. before typing the file name at an OS/2 command prompt.
  1959.  
  1960. TRACE lets you see just how REXX evaluates expressions while the program is actually
  1961. running. To start the trace function from the command prompt, type the command as
  1962. follows:
  1963.  
  1964. PMREXX /T filename arguments
  1965.  
  1966. =======================================================================================
  1967. 7.3    The REXXTRY Program
  1968.  
  1969. REXXTRY is a REXX program.  As with other REXX programs, REXXTRY can be run in
  1970. an OS/2 full-screen or window session, or with PMREXX.
  1971.  
  1972. You can use REXXTRY to run different REXX instructions and observe the results.
  1973. REXXTRY is also useful when you want to perform a REXX operation only once, since it
  1974. is easier than creating, running, and erasing a .CMD file.
  1975.  
  1976. Here are some examples of how to use the REXXTRY command:
  1977.  
  1978. REXXTRY say 1+2
  1979.  
  1980. The operation is performed and 3 is displayed.
  1981.  
  1982. REXXTRY say 2+3; say 3+4
  1983.  
  1984. 5 and 7 are displayed.
  1985.  
  1986. =======================================================================================
  1987. SECTION 8       REXX Utility Functions (RexxUtil)
  1988.  
  1989. RexxUtil is a Dynamic Link Library (DLL) which provides the OS/2* REXX programmer
  1990. with many versatile functions.  Primarily, these functions deal with the following:
  1991.  
  1992.   OS/2 system commands.
  1993.  
  1994.   User or text screen input/output (I/O).
  1995.  
  1996.   OS/2 INI file I/O.
  1997.  
  1998. RexxUtil requires that you are already running under OS/2 2.0 with OS/2 Procedures
  1999. Language 2/REXX installed.
  2000.  
  2001. To be able to use a RexxUtil function in a REXX program, you must first add the
  2002. function using the built-in function RxFuncAdd.
  2003.  
  2004. Example:
  2005.  
  2006. call RxFuncAdd 'SysCls', 'RexxUtil', 'SysCls'
  2007.  
  2008. The above example would add the SysCls function so that it can be used.
  2009.  
  2010. The RexxUtil function, SysLoadFuncs, will automatically load all RexxUtil functions. 
  2011. To do this from within a program, add the following instructions:
  2012.  
  2013. call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  2014. call SysLoadFuncs
  2015.  
  2016. Once the RexxUtil functions are loaded by SysLoadFuncs they are usable by all OS/2
  2017. sessions.
  2018.  
  2019. The RexxUtil functions are listed when you select the + sign beside this topic in the
  2020. Contents.
  2021.  
  2022. =======================================================================================
  2023. 8.1    RxMessageBox
  2024.  
  2025. Function: RxMessageBox
  2026.  
  2027. Syntax:  action = RxMessageBox(text, [title], [button], [icon])
  2028.  
  2029.    text     The text of the message that appears in the message box.
  2030.  
  2031.    title    The title of the message box.  The default title is "Error".
  2032.  
  2033.    The style of buttons used with the message box.  The allowed styles are:
  2034.  
  2035.       OK                   A single OK button.
  2036.  
  2037.       OKCANCEL             An OK button and a Cancel button.
  2038.  
  2039.       CANCEL               A single Cancel button.
  2040.  
  2041.       ENTER                A single Enter button.
  2042.  
  2043.       ENTERCANCEL          An Enter button and a Cancel button.
  2044.  
  2045.       RETRYCANCEL          A Retry button and a Cancel button.       ABORTRETRYCANCEL     An Abort button, a Retry button and a Cancel button.
  2046.  
  2047.       YESNO                A Yes button and a No button.
  2048.  
  2049.       YESNOCANCEL          A Yes button, a No button and a Cancel button.
  2050.  
  2051.                     The default button style is OK.
  2052.  
  2053.    icon     The style of icon displayed in the message box.  The allowed styles are:
  2054.  
  2055.       NONE               No icon is displayed.
  2056.  
  2057.       HAND               The hand icon is displayed.
  2058.  
  2059.       QUESTION           A question mark icon is displayed.
  2060.  
  2061.       EXCLAMATION        An exclamation mark icon is displayed.
  2062.  
  2063.       ASTERISK           An asterisk icon is displayed.
  2064.  
  2065.       INFORMATION        The information icon is displayed.
  2066.  
  2067.       QUERY              The query icon is displayed.
  2068.  
  2069.       WARNING            The warning icon is displayed.
  2070.  
  2071.       ERROR              The error icon is displayed.
  2072.  
  2073.    action   The button that was selected on the message box. Possible values are:
  2074.  
  2075.       1        OK key
  2076.  
  2077.       2        Cancel key
  2078.  
  2079.       3        Abort key
  2080.  
  2081.       4        Retry key
  2082.  
  2083.       5        Ignore key
  2084.  
  2085.       6        Yes key
  2086.  
  2087.       7        No key
  2088.  
  2089.       8        Enter
  2090.  
  2091. Purpose: Display a message box from a REXX program running in an OS/2 session (that
  2092.           is, running in PMREXX or called from a Presentation Manager* application).
  2093.  
  2094. Examples:
  2095.  
  2096.                                        /* Give option to quit        */
  2097.   if RxMessageBox("Shall we continue",, "YesNo", "Query") = 7
  2098.     Then Exit                          /* quit option given, exit    */
  2099. @
  2100. @@@@@@@@@@@@@@@@@@@
  2101. 8.2    SysCls
  2102.  
  2103. Function: SysCls
  2104.  
  2105. Syntax:  call SysCls
  2106.  
  2107. Purpose: Clears the screen quickly.
  2108.  
  2109. =======================================================================================
  2110. 8.3    SysCurPos
  2111.  
  2112. Function: SysCurPos
  2113.  
  2114. Syntax:  pos = SysCurPos(row, col)
  2115.  
  2116.    pos      The position of the cursor upon the calling of SysCurPos in the form 'row
  2117.              col'.
  2118.  
  2119.    row      The row on the screen to move to.
  2120.  
  2121.    col      The column on the screen to move to.
  2122.  
  2123.              Note:    Position (0,0) is at the upper left.  You may call SysCurPos
  2124.             without parameters to check the current cursor position without changing
  2125.             it.
  2126.  
  2127. Purpose: Move the cursor to the specified row and column and/or query the
  2128. current/previous cursor position.
  2129.  
  2130.           Example:
  2131.  
  2132.            /* Code */
  2133.            call SysCls
  2134.            parse value SysCurPos() with row col
  2135.            say 'Cursor position is 'row', 'col
  2136.  
  2137.            /* Output */
  2138.            Cursor position is 0, 0
  2139.  
  2140. =======================================================================================
  2141. 8.4    SysCurState
  2142.  
  2143. Function: SysCurState
  2144.  
  2145. Syntax:  SysCurState state
  2146.  
  2147.    state    The desired state which to set the cursor.  Should be one of the following:
  2148.  
  2149.       'ON'     Display the cursor.
  2150.  
  2151.       'OFF'    Hide the cursor.
  2152.  
  2153. Purpose: Use this function to hide or display the cursor.
  2154.  
  2155. =======================================================================================
  2156. 8.5    SysDriveInfo
  2157.  
  2158. Function: SysDriveInfo
  2159.  
  2160. Syntax:  info = SysDriveInfo(drive)
  2161.  
  2162.    info     Drive information returned in the following form: 'drive:  free total
  2163.             label' If the drive is not accessible, then info will equal ''.
  2164.  
  2165.    drive    The drive of interest,  'C:'.
  2166.  
  2167. Purpose: Gives drive information.
  2168.  
  2169.           Example:
  2170.            /* Code */
  2171.            say 'Disk='SysDriveInfo('C:')
  2172.  
  2173.            /* Output */
  2174.            Disk=C: 33392640 83687424 TRIGGER_C
  2175.  
  2176. In the above Output example, the items have the following meaning:
  2177.  
  2178.   The first item is the drive being queried.
  2179.   The first number is the number of bytes that are free.
  2180.   The second number is the number of bytes that are used.
  2181.   The final item is the drive label.
  2182.  
  2183. =======================================================================================
  2184. 8.6    SysDriveMap
  2185. Function: SysDriveMap
  2186.  
  2187. Syntax:  map = SysDriveMap([drive], [opt])
  2188.  
  2189.    map      A string containing all accessible drives.
  2190.  
  2191.    drive    Drive letter with which to start the drive map. The default is C.
  2192.  
  2193.    opt      The drivemap report option.  May be any one of the following:
  2194.  
  2195.       'USED'        Reports drives which are accessible or in use.  This is the 
  2196.                     default. This includes all local and remote drives.
  2197.  
  2198.       'FREE'        Reports drives which are free or not in use.
  2199.  
  2200.       'LOCAL'       Reports only those drives which are local drives.
  2201.  
  2202.       'REMOTE'      Reports only those drives which are remote drives such as
  2203.                     redirected LAN resources, IFS attached drives, and so on.
  2204.  
  2205.       'DETACHED'    Reports drives which are detached LAN resources.
  2206.  
  2207. Purpose: Reports all accessible drives in the form 'C: D: E:...'
  2208.  
  2209.       Example:
  2210.            /* Code */
  2211.            say 'Used drives include:'
  2212.            say SysDriveMap('C:', 'USED')
  2213.  
  2214.            /* Output */
  2215.            Used drives include:
  2216.            C: D: E: F: W:
  2217.  
  2218. =======================================================================================
  2219. 8.7    SysDropFuncs
  2220.  
  2221. Function: SysDropFuncs
  2222.  
  2223. Syntax:  call SysDropFuncs
  2224.  
  2225. Purpose: Use this function to drop all the loaded RexxUtil functions.  Once this
  2226. function is processed by a REXX program, the RexxUtil functions are not accessible in
  2227. any OS/2 sessions.
  2228.  
  2229. =======================================================================================
  2230. 8.8    SysFileDelete
  2231.  
  2232. Function: SysFileDelete
  2233.  
  2234. Syntax:  rc = SysFileDelete(file)
  2235.  
  2236. Purpose: Deletes the specified file.  Does not support wildcards.
  2237.  
  2238. RC:      Return Codes
  2239.  
  2240.    0        File deleted successfully.
  2241.  
  2242.    2        Error.  File not found.
  2243.  
  2244.    3        Error.  Path not found.
  2245.  
  2246.    5        Error.  Access denied.
  2247.  
  2248.    26       Error.  Not DOS disk.
  2249.  
  2250.    32       Error.  Sharing violation.
  2251.  
  2252.    36       Error.  Sharing buffer exceeded.
  2253.  
  2254.    87       Error.  Invalid parameter
  2255.  
  2256.    206      Error.  Filename exceeds range error
  2257.  
  2258. =======================================================================================
  2259. 8.9    SysFileTree
  2260.  
  2261. Function: SysFileTree
  2262.  
  2263. Syntax:  rc = SysFileTree(filespec, stem, [options], [tattrib], [nattrib])
  2264.  
  2265.    filespec The filespec to search for.
  2266.  
  2267.    stem     The name of the stem variable to place the results.
  2268.  
  2269.              Note:    stem.0 contains the number of files and/or directories found.
  2270.  
  2271.    options  Any logical combination of the following:
  2272.  
  2273.       F        Search for files only.       D        Search for directories only.
  2274.  
  2275.       B        Search for both files and directories. (default)
  2276.  
  2277.       S        Scan subdirectories recursively. (non-default).
  2278.  
  2279.       T        Return time and date fields in the form:
  2280.  
  2281.                 YY/MM/DD/HH/MM
  2282.  
  2283.       O        Only report fully qualified file names.  The default is to report date,
  2284.                time, size, attributes and fully qualified file name for each file
  2285.                found.
  2286.  
  2287.    tattrib  The target attribute mask used when searching for filespec matches. Only
  2288.              filespecs which match the mask will be reported.  The default mask is
  2289.              '*****' which means the Archive, Directory, Hidden, Read-Only, and System
  2290.              bits may be either set or clear.  The attributes in the mask are
  2291.              positional dependant and in the alphabetical order 'ADHRS'.
  2292.  
  2293.       Mask Options (Target Mask)
  2294.  
  2295.          *        The specified attribute may be either set or clear.
  2296.  
  2297.          +        The specified attribute must be set.
  2298.  
  2299.          -        The specified attribute must be clear.
  2300.  
  2301.          Examples: (Target Mask)
  2302.  
  2303.             '***+*'  Find all files which have set Read-Only bits.
  2304.  
  2305.             '+**+*'  Find all files which have set Read-Only and Archive bits.
  2306.  
  2307.             '*++**'  Find all hidden subdirectories.
  2308.  
  2309.             '---+-'  Find all files which have only the Read-Only bit set.
  2310.  
  2311.    nattrib  The new attribute mask which will be used to set the attributes of each
  2312.              filespec found to match the target mask.  The default mask is '*****'
  2313.              which means the Archive, Directory, Hidden, Read-Only, and System bits
  2314.              will not be changed.  The attributes in the mask are positional
  2315.              dependant and in the alphabetical order 'ADHRS'.
  2316.  
  2317.       Mask Options (New Atrribute Mask)
  2318.  
  2319.          *        The specified attribute will not be changed.
  2320.  
  2321.          +        The specified attribute will be set.
  2322.  
  2323.          -        The specified attribute will be cleared.
  2324.  
  2325.          Examples: (New Attribute Mask)
  2326.  
  2327.             '***+*'  Set the Read-Only bit on all files.
  2328.  
  2329.             '-**+*'  Set the Read-Only and clear the Archive bits of each file.
  2330.  
  2331.             '+*+++'  Set all attributes on all files, excluding directory attribute.             '-----'  Clear all attribute on all files.
  2332.  
  2333.                       Note:    You cannot set the directory bit on non-directory
  2334.                       filespecs. The attribute field which is displayed in the stem
  2335.                       variable is that of the current attribute setting after any
  2336.                       changes have been applied.
  2337.  
  2338. Purpose: Finds all files which are equal to the specified filespec, and places their
  2339.           descriptions (date time size attr filespec) in a stem variable.
  2340.  
  2341. RC:      Return Codes
  2342.  
  2343.    0        Successful.
  2344.  
  2345.    2        Error.  Not enough memory.
  2346.  
  2347.            Examples:
  2348.  
  2349.             /****<< Syntax Examples.>>***********************/
  2350.  
  2351.             /* Find all subdirectories on C: */
  2352.              call SysFileTree 'c:\*.*', 'file', 'SD'
  2353.  
  2354.             /* Find all Read-Only files */
  2355.              call SysFileTree 'c:\*.*', 'file', 'S', '***+*'
  2356.  
  2357.             /* Clear Archive and Read-Only bits of files which have them set */
  2358.              call SysFileTree 'c:\*.*', 'file', 'S', '+**+*', '-**-*'
  2359.  
  2360.             /****<< Sample Code and Output Example.>>********/
  2361.  
  2362.             /* Code */
  2363.              call SysFileTree 'c:\os2*.', 'file', 'B'
  2364.              do i=1 to file.0
  2365.                say file.i
  2366.              end
  2367.  
  2368.            /* Actual Output */
  2369.           12:15:89  12:00a        4096  A-HRS  C:\OS2LDR
  2370.           12:15:89  12:00a       29477  A-HRS  C:\OS2KRNL
  2371.            5:24:89   4:59p           0  -D---  C:\OS2
  2372.  
  2373. =======================================================================================
  2374. 8.10   SysFileSearch
  2375.  
  2376. Function: SysFileSearch
  2377.  
  2378. Syntax:  call SysFileSearch target, file, stem, [options]
  2379.  
  2380.    target   The string to search for.
  2381.  
  2382.    file     The file to search.
  2383.  
  2384.    stem     The name of the stem variable to place the results.
  2385.  
  2386.              Note:    stem.0 contains the number of lines found.
  2387.  
  2388.    options  Any logical combination of the following:
  2389.  
  2390.       C        Case sensitive search.       N        Give line numbers when reporting hits.
  2391.  
  2392.                 Note:    Default is case insensitive without line numbers.
  2393.  
  2394. Purpose: Finds all lines in specified file which contain a specified target string, and
  2395.           places said lines in a stem variable.
  2396.  
  2397. RC:      Return Codes
  2398.  
  2399.    0        Successful.
  2400.  
  2401.    2        Error.  Not enough memory.
  2402.  
  2403.    3        Error.  Error opening file.
  2404.  
  2405.           Examples:
  2406.  
  2407.            /* Find DEVICE statements in CONFIG.SYS */
  2408.            call SysFileSearch 'DEVICE', 'C:\CONFIG.SYS', 'file.'
  2409.            do i=1 to file.0
  2410.             say file.i
  2411.            end
  2412.  
  2413.            /* Output */
  2414.            DEVICE=C:\OS2\DOS.SYS
  2415.            DEVICE=C:\OS2\PMDD.SYS
  2416.            DEVICE=C:\OS2\COM02.SYS
  2417.            SET VIDEO_DEVICES=VIO_IBM8514A
  2418.            SET VIO_IBM8514A=DEVICE(BVHVGA,BVH8514A)
  2419.            DEVICE=C:\OS2\POINTDD.SYS
  2420.            DEVICE=C:\OS2\MSPS202.SYS
  2421.            DEVICE=C:\OS2\MOUSE.SYS TYPE=MSPS2$
  2422.  
  2423.            /* Find DEVICE statements in CONFIG.SYS (along with */
  2424.            /* line nums) */
  2425.            call SysFileSearch 'DEVICE', 'C:\CONFIG.SYS', 'file.', 'N'
  2426.            do i=1 to file.0
  2427.             say file.i
  2428.            end
  2429.  
  2430.            /* Output */
  2431.            20 DEVICE=C:\OS2\DOS.SYS
  2432.            21 DEVICE=C:\OS2\PMDD.SYS
  2433.            22 DEVICE=C:\OS2\COM02.SYS
  2434.            33 SET VIDEO_DEVICES=VIO_IBM8514A
  2435.            34 SET VIO_IBM8514A=DEVICE(BVHVGA,BVH8514A)
  2436.            40 DEVICE=C:\OS2\POINTDD.SYS
  2437.            41 DEVICE=C:\OS2\MSPS202.SYS
  2438.            42 DEVICE=C:\OS2\MOUSE.SYS TYPE=MSPS2$
  2439.  
  2440. =======================================================================================
  2441. 8.11   SysGetKey
  2442.  
  2443. Function: SysGetKey
  2444.  
  2445. Syntax:  key = SysGetKey([opt])
  2446.  
  2447.    key      The key which was pressed.
  2448.    opt       Any one of the following:
  2449.  
  2450.       'ECHO'   Echo the typed character  (Default)
  2451.  
  2452.       'NOECHO' Do not echo the typed character
  2453.  
  2454. Purpose: Gets the next key from the keyboard buffer, or waits for one if none exist.
  2455.           Works like the C function getch().  Unlike the regular REXX CHARIN() built-in
  2456.           function, SysGetKey() does not require the character to be followed by the
  2457.           Enter key.
  2458.  
  2459. =======================================================================================
  2460. 8.12   SysGetMessage
  2461.  
  2462. Function: SysGetMessage
  2463.  
  2464. Syntax:  msg = SysGetMessage(num, [file] [str1],...[str9])
  2465.  
  2466.    msg      The message associated with the number given.
  2467.  
  2468.    num      The message number.
  2469.  
  2470.    file     The message file to be searched.  The default message file is OSO001.MSG.
  2471.              Message files will be searched for in the system root directory ( C:\),
  2472.              the current directory, and along the DPATH.
  2473.  
  2474.    str1,...str9 Insertion text variables.  If the message contains insertion fields
  2475.              designated by %x, in the range %1 to %9, then the optional parameters str1
  2476.              through str9 may be used to designate the replacement strings.
  2477.  
  2478. Purpose: OS/2 applications commonly use message files to provide National Language
  2479.           Support (NLS).  Message files contain text strings which any application can
  2480.           reference by their associated number.
  2481.  
  2482.           Note:    Use the MKMSGF utility contained in the OS/2 Programmer's Toolkit to
  2483.                    create message files.  MKMSGF is documented in the Building
  2484.                    Programs book included with the toolkit.
  2485.  
  2486.           /*** Sample code segment using SysGetMessage and insertion text vars ***/
  2487.           msg =  SysGetMessage(34, , 'A:', 'diskette labeled "Disk 2"', 'SER0002')
  2488.           say msg
  2489.  
  2490.           /** Output **/
  2491.           The wrong diskette is in the drive.
  2492.           Insert diskette labeled "Disk 2" (Volume Serial Number: SER0002)
  2493.           into drive A:.
  2494.  
  2495. =======================================================================================
  2496. 8.13   SysIni
  2497.  
  2498. Function: SysIni
  2499.  
  2500.    Syntax - Mode 1: Setting single key value.
  2501.  
  2502.              result = SysIni([inifile], app, key, val)
  2503.  
  2504.    Syntax - Mode 2: Querying single key value.
  2505.  
  2506.              result = SysIni([inifile], app, key)
  2507.    Syntax - Mode 3: Deleting a single key.
  2508.  
  2509.              result = SysIni([inifile], app, key, 'DELETE:')
  2510.  
  2511.    Syntax - Mode 4: Deleting an application and all associated keys.
  2512.  
  2513.              result = SysIni([inifile], app, ['DELETE:'])
  2514.  
  2515.    Syntax - Mode 5: Querying names of all keys associated with a certain application.
  2516.  
  2517.              result = SysIni([inifile], app, 'ALL:', 'stem')
  2518.  
  2519.    Syntax - Mode 6: Querying names of all applications.
  2520.  
  2521.              result = SysIni([inifile], 'ALL:', 'stem')
  2522.  
  2523.    result   For successful setting invocations, result will equal ''. For successful
  2524.              querying invocations, result will be given the value of the specified
  2525.              application keyword.  For successful deleting invocations, result will
  2526.              equal ''.
  2527.  
  2528.              The error string 'ERROR:' may be returned if an error occurs:
  2529.  
  2530.              Possible error conditions:
  2531.  
  2532.        An attempt was made to query or delete an application/key pair which does not
  2533.         exist.
  2534.  
  2535.        An error occurred opening the specified INI file. You may have specified the
  2536.         current user or system INI file using a relative filespec. Make sure to use the
  2537.         full filespec, specifying drive, path, and file name.
  2538.  
  2539.    inifile  The name of the INI file which you would like to work with.  This parameter
  2540.              should be a file specification, or one of the following:
  2541.  
  2542.       'USER'   The user INI file (usually C:\OS2\OS2.INI).  This is the default.
  2543.  
  2544.       'SYSTEM' The system INI file (usually C:\OS2\OS2SYS.INI).
  2545.  
  2546.       'BOTH'   For querying invocations, both the user and system INI files will be
  2547.                 searched. For setting invocations, the user INI file will be written
  2548.                 to.
  2549.  
  2550.    app      The application name or some other meaningful value with which you would
  2551.              like to store keywords (some sort of data).
  2552.  
  2553.    key      The name of a keyword which is used to hold data.
  2554.  
  2555.    val      The value to associate with the keyword of the specified application.
  2556.  
  2557.    stem     The name of the stem variable to store the resultant information in.
  2558.              STEM.0 will be set equal to the number of elements.
  2559.  
  2560. Purpose: This function allows limited editing of INI file variables. Variables are
  2561.           stored in the INI file under Application Names and their associated Key Names
  2562.           or keywords.  SysIni can be used to share variables between applications or
  2563.           as a way of implementing GLOBALV in the OS/2 operating system.
  2564.  
  2565.           Note:  This function works on all types of data stored in an INI file (text,
  2566.           numeric, or binary).           /* Sample code segments */
  2567.  
  2568.            /***  Save the user entered name under the key 'NAME' of *****
  2569.            ****  the application 'MYAPP'.                           ****/
  2570.            pull name .
  2571.            call SysIni , 'MYAPP', 'NAME', name /* Save the value        */
  2572.            say  SysIni(, 'MYAPP', 'NAME')      /* Query the value       */
  2573.            call SysIni , 'MYAPP'               /* Delete all MYAPP info */
  2574.            exit
  2575.  
  2576.            /****  Type all OS2.INI file information to the screen  *****/
  2577.           call rxfuncadd sysloadfuncs, rexxutil, sysloadfuncs
  2578.           call sysloadfuncs
  2579.              call SysIni 'USER', 'All:', 'Apps.'
  2580.              if Result \= 'ERROR:' then
  2581.                do i = 1 to Apps.0
  2582.                  call SysIni 'USER', Apps.i, 'All:', 'Keys'
  2583.                  if Result \= 'ERROR:' then
  2584.                   do j=1 to Keys.0
  2585.                     val = SysIni('USER', Apps.i, Keys.j)
  2586.                     say left(Apps.i, 20) left(Keys.j, 20),
  2587.                           'Len=x'''Left(d2x(length(val)),4) left(val, 20)
  2588.                   end
  2589.                end
  2590.  
  2591. =======================================================================================
  2592. 8.14   SysMkDir
  2593.  
  2594. Function: SysMkDir
  2595.  
  2596. Syntax:  rc = SysMkDir(dirspec)
  2597.  
  2598.    dirspec  The directory that should be created.
  2599.  
  2600. Purpose: Creates a specified directory quickly.  In case of failure, one of many return
  2601.           codes is given so that the exact reason for failure can be determined.
  2602.  
  2603. RC:      Return Codes
  2604.  
  2605.    0        Directory creation was successful.
  2606.  
  2607.    2        Error.  File not found.
  2608.  
  2609.    3        Error.  Path not found.
  2610.  
  2611.    5        Error.  Access denied.
  2612.  
  2613.    26       Error.  Not a DOS disk.
  2614.  
  2615.    87       Error.  Invalid parameter.
  2616.  
  2617.    108      Error.  Drive locked.
  2618.  
  2619.    206      Error.  Filename exceeds range.
  2620.  
  2621. Example: call SysMkDir 'c:\rexx'
  2622.  
  2623. =======================================================================================
  2624. 8.15   SysOS2Ver
  2625.  
  2626. Function: SysOS2Ver
  2627.  
  2628. Syntax:  ver = SysOS2Ver( )
  2629.  
  2630.    ver      String containing OS/2 version info in the form 'x.xx'
  2631.  
  2632. Purpose: Returns the OS/2 version information.
  2633.  
  2634. =======================================================================================
  2635. 8.16   SysRmDir
  2636.  
  2637. Function: SysRmDir
  2638.  
  2639. Syntax:  rc = SysRmDir(dirspec)
  2640.  
  2641.    dirspec  The directory that should be deleted.
  2642.  
  2643. Purpose: Deletes a specified directory quickly.  In case of failure, one of many return
  2644.           codes is given so that the exact reason for failure can be determined.
  2645.  
  2646. RC:      Return Codes
  2647.  
  2648.    0        Directory removal was successful.
  2649.  
  2650.    2        Error.  File not found.
  2651.  
  2652.    3        Error.  Path not found.
  2653.  
  2654.    5        Error.  Access denied.
  2655.  
  2656.    16       Error.  Current directory.
  2657.  
  2658.    26       Error.  Not a DOS disk.
  2659.  
  2660.    87       Error.  Invalid parameter.
  2661.  
  2662.    108      Error.  Drive locked.
  2663.  
  2664.    206      Error.  Filename exceeds range.
  2665.  
  2666. Example: call SysRmDir 'c:\rexx'
  2667.  
  2668. =======================================================================================
  2669. 8.17   SysSearchPath
  2670.  
  2671. Function: SysSearchPath
  2672.  
  2673. Syntax:  filespec = SysSearchPath(path, filename)
  2674.  
  2675.    filespec The complete filespec of the file found, or '' if the filename was not
  2676.              located along the path.
  2677.  
  2678.    path     Any environment variable that resembles a path, such as 'PATH', 'DPATH',
  2679.              and so on.
  2680.  
  2681.    filename The file to search the path for. Purpose: Searches the specified path for the specified file and returns the full
  2682. filespec of the file if found, otherwise it returns. 
  2683.  
  2684. Example:
  2685.  
  2686.            /* Code */
  2687.            fspec = SysSearchPath('PATH', 'CMD.EXE')
  2688.            say fspec
  2689.  
  2690.            /* Output */
  2691.            C:\OS2\CMD.EXE
  2692.  
  2693. =======================================================================================
  2694. 8.18   SysSleep
  2695.  
  2696. Function: SysSleep
  2697.  
  2698. Syntax:  call SysSleep secs
  2699.  
  2700.    secs     The number of seconds to sleep.
  2701.  
  2702. Purpose: Sleep a specified number of seconds.
  2703.  
  2704. =======================================================================================
  2705. 8.19   SysTempFileName
  2706.  
  2707. Function: SysTempFileName
  2708.  
  2709. Syntax:  file = SysTempFileName(template, [filter])
  2710.  
  2711.    template The template that describes the temporary file or directory name to be
  2712.              returned.  The template should resemble a valid file or directory 
  2713.              with up to 5 filter characters.
  2714.  
  2715.    filter   The filter character found in the template.  Each filter character found in
  2716.              template is replaced with a numeric value.  The resulting string a
  2717.              file or directory that does not exist.  The default filter character is ?.
  2718.  
  2719.    file     A file or directory that does not currently exist.  If an error occurred or
  2720.              no unique file or directory exists given the template provided, a null is
  2721.              returned.
  2722.  
  2723. Purpose: Returns a unique file or directory name given a certain template.  Useful when
  2724.           a program requires a temporary file but is not to overwrite an existing file.
  2725.  
  2726.           Examples:
  2727.  
  2728.            /* Code */
  2729.            say SysTempFileName('C:\TEMP\MYEXEC.???')
  2730.            say SysTempFileName('C:\TEMP\??MYEXEC.???')
  2731.            say SysTempFileName('C:\MYEXEC@.@@@', '@')
  2732.  
  2733.            /* Output */
  2734.            C:\TEMP\MYEXEC.251
  2735.            C:\TEMP\10MYEXEC.392
  2736.            C:\MYEXEC6.019
  2737.  
  2738.           Note:
  2739.                     Since it is not required that the filter characters be contiguous
  2740.                     within the template, it is impossible to quickly determine the
  2741.                     number of files already residing in the target directory that would
  2742.                     fit the template description.
  2743.  
  2744.                     SysTempFileName uses a random number algorithm to determine a
  2745.                     number to replace the filter characters with.  It then tests if the
  2746.                     resulting file exists.  If it does not, it increments the number,
  2747.                     replaces the filter characters, and tests for the existence of the
  2748.                     new file, and so on.  This continues until a free file is found or
  2749.                     all possibilities have been exhausted.
  2750.  
  2751. =======================================================================================
  2752. 8.20   SysTextScreenRead
  2753.  
  2754. Function: SysTextScreenRead
  2755.  
  2756. Syntax:  string = SysReadScreen(row, col, [len])
  2757.  
  2758.    row      The row from which to start reading.
  2759.  
  2760.    col      The column from which to start reading.
  2761.  
  2762.    len      The number of characters to read.  The default is to read up to the end of
  2763.              the screen.
  2764.  
  2765.    string   The character reads from the screen.  This includes carriage return and
  2766.              linefeed characters which comprise the end of lines should the number of
  2767.              character reads span multiple lines.
  2768.  
  2769. Purpose: Reads a specified number of characters from a specified location of the
  2770.           screen.
  2771.  
  2772. Limitations:  This function only reads in characters and does not consider the color
  2773. attributes of each character read.  When restoring the character string to the screen
  2774. with or charout, the previous color settings will be lost.
  2775.  
  2776. /* Example which reads in the entire screen */
  2777.  screen = SysTextScreenRead( 0, 0 )
  2778.  
  2779. /* Example which reads in one line */
  2780.  line = SysTextScreenRead( 2, 0, 80 )
  2781.  
  2782. =======================================================================================
  2783. 8.21   SysTextScreenSize
  2784.  
  2785. Function: SysTextScreenSize
  2786.  
  2787. Syntax:  result = SysTextScreenSize()
  2788.  
  2789.    result   The size of the screen.  The format of the result string is 'row col'.
  2790.  
  2791. Purpose: This function returns the size of the screen.
  2792.  
  2793. /* Example */
  2794. call RxFuncAdd 'SysTextScreenSize', 'RexxUtil', 'SysTextScreenSize'
  2795. parse value SysTextScreenSize() with row col
  2796. say 'Rows='row', Columns='col
  2797. =======================================================================================
  2798. 8.22   SysGetEA
  2799.  
  2800. Function: SysGetEA
  2801.  
  2802. Syntax:  result = SysGetEA(file, name, variable)
  2803.  
  2804.    file     The file containing the extended attribute.
  2805.  
  2806.    name     The name of the extended attribute.
  2807.  
  2808.    variable The name of a REXX variable in which the extended attribute value is
  2809.              placed.
  2810.  
  2811.    result   The function result. If the result is 0, the extended attribute has been
  2812.              retrieved and placed in a variable.  A non-zero result is the OS/2 return
  2813.              code of the failing function.
  2814.  
  2815. Purpose: Read a named extended attribute from a file.
  2816.  
  2817. Examples:
  2818.  
  2819.   /* Code    */
  2820.   if (SysGetEA("C:\CONFIG.SYS", ".type", "TYPEINFO") = 0 then
  2821.     parse var typeinfo 11 type
  2822.     say type
  2823.  
  2824.   /* Output */
  2825.   OS/2 Command File
  2826.  
  2827. =======================================================================================
  2828. 8.23   SysPutEA
  2829.  
  2830. Function: SysPutEA
  2831.  
  2832. Syntax:  result = SysPutEA(file, name, value)
  2833.  
  2834.    file     The file where the extended attribute will be written.
  2835.  
  2836.    name     The name of the extended attribute.
  2837.  
  2838.    value    The new value of the extended attribute.
  2839.  
  2840.    result   The function result. If the result is 0, the extended attribute has been
  2841.              written to the file. A non-zero result is the OS/2 return code of the
  2842.              failing function. 
  2843. Purpose: Write a named extended attribute to a file.
  2844.  
  2845. Examples:
  2846.  
  2847.   /* Code    */
  2848.   type = "OS/2 Command File"
  2849.   typeinfo = "DFFF00000100FDFF'x || d2c(length(type)) || '00'x || type
  2850.   call SysPutEA "C:\CONFIG.SYS", "TYPE", typeinfo
  2851.  
  2852. =======================================================================================
  2853. 8.24   SysWaitNamedPipe
  2854.  
  2855. Function: SysWaitNamedPipe
  2856.  
  2857. Syntax:  result = SysWaitNamedPipe(name, [timeout])
  2858.  
  2859.    name     The name of the named pipe.  Named pipe names must be of the form
  2860.              "\PIPE\pipename".
  2861.  
  2862.    timeout  The number of microseconds to wait on the pipe.  If timeout is omitted or
  2863.              is zero, the default timeout value is be used. A value of -1 can be used
  2864.              to wait until the pipe is no longer busy.
  2865.  
  2866.    result   The return code from DosWaitNmPipe. The following return codes are of
  2867.              particular interest:
  2868.  
  2869.       0        The named pipe is no longer busy.
  2870.  
  2871.       2        The named pipe was not found.
  2872.  
  2873.       231      The wait timed out before the pipe became available.
  2874.  
  2875. Purpose: Perform a timed wait on a named pipe.
  2876.  
  2877. Examples:
  2878.  
  2879.   /* Code    */
  2880.    Parse value stream(PipeName,'C','OPEN') with PipeState ':' OS2RC
  2881.    If OS2RC=231 then call SysWaitNamedPipe(PipeName, -1)
  2882.  
  2883. =======================================================================================
  2884. 8.25   SysSetIcon
  2885.  
  2886. Function: SysSetIcon
  2887.  
  2888. Syntax:  result = SysSetIcon(filename, iconfilename)
  2889.  
  2890.    filename         The name of the file to have the icon set.
  2891.  
  2892.    iconfilename     The name of a .ICO file containing icon data.
  2893.  
  2894.    result           The return code from WinSetIcon. This returns 1 (TRUE) if the icon
  2895.                      was set and 0 (FALSE) if the new icon was not set.
  2896.  
  2897.    Purpose:         Associate an icon file with a specified file.
  2898.  
  2899.           Examples:
  2900.  
  2901.             /* Code    */
  2902.              if SysSetIcon(file, "NEW.ICO") then
  2903.                say 'Install successfully completed for' file
  2904.  
  2905.          Get   SysRegisterObjectClass
  2906.  
  2907. Function: SysRegisterObjectClass
  2908.  
  2909. Syntax:  result = SysRegisterObjectClass(classname, modulename)
  2910.  
  2911.    classname        The name of the new object class.
  2912.  
  2913.    modulename       The name of the module containing the object definition.
  2914.  
  2915.    result           The return code from WinRegisterObjectClass.  This returns 1 (TRUE)
  2916.                      if the class was registered and 0 (FALSE) if the new class was not
  2917.                      registered.
  2918.  
  2919.    Purpose:         Register a new object class definition to the system.
  2920.  
  2921.           Examples:
  2922.  
  2923.             /* Code    */
  2924.              if SysRegisterObjectClass("NewObject","NEWDLL") then
  2925.                say 'Install successfully completed for NewObject'
  2926.  
  2927. =======================================================================================
  2928. 8.27   SysDeregisterObjectClass
  2929.  
  2930. Function: SysDeregisterObjectClass
  2931.  
  2932. Syntax:  result = SysDeregisterObjectClass(classname)
  2933.  
  2934.    classname        The name of the object class to deregister.
  2935.  
  2936.    result           The return code from WinDeregisterObjectClass.  This returns 1
  2937.                      (TRUE) if the class was deregistered and 0 (FALSE) if the class
  2938.                      was not deregistered.
  2939.  
  2940.    Purpose:         Deregister an object class definition from the system.
  2941.  
  2942.           Examples:
  2943.  
  2944.             /* Code    */
  2945.              call SysDeregisterObjectClass "OldObject","NEWDLL"
  2946.  
  2947. =======================================================================================
  2948. 8.28   SysCreateObject
  2949.  
  2950. Function: SysCreateObject
  2951.  
  2952. Syntax:  result = SysCreateObject(classname, title, location <,setup>)
  2953.  
  2954.    classname        The name of the object class.
  2955.  
  2956.    title            The object title.
  2957.  
  2958.    location         The object location.  This can be specified as either a descriptive
  2959.                      path (for example, OS/2 System Folder\System Configuration) or a
  2960.                      file system path (for example, C:\bin\mytools).
  2961.  
  2962.    setup            A WinCreateObject setup string.
  2963.  
  2964.    result           The return code from WinCreateObject.  This returns 1 (TRUE) if the
  2965.                      object was created and 0 (FALSE) if the object was not created.
  2966.    Purpose:         Create a new instance of an object class.
  2967.  
  2968.           Examples:
  2969.  
  2970.             /* Code    */
  2971.              if \SysCreateObject("Program","NEWDLL") then
  2972.                say 'Install successfully completed for NewObject'
  2973.  
  2974. =======================================================================================
  2975. 8.29   SysQueryClassList
  2976.  
  2977. Function: SysQueryClassList
  2978.  
  2979. Syntax:  call  SysQueryClassList stem
  2980.  
  2981.    stem     The name of a stem variable in which the entire set of registered classes
  2982.              is placed.
  2983.  
  2984.    Purpose: Retrieve the complete list of registered object classes.
  2985.  
  2986.           Examples:
  2987.  
  2988.             /* Code    */
  2989.              call SysQueryClassList "list."
  2990.              do i = 1 to list.0
  2991.                say 'Class' i 'is' list.i
  2992.              end
  2993.  
  2994. =======================================================================================
  2995. SECTION 9       Keyword Instructions
  2996.  
  2997. A keyword instruction is one or more clauses, the first of which starts with a keyword
  2998. that identifies the instruction.  If the instruction has more than one clause, the
  2999. clauses separated by a delimiter, in this case a semicolon (;).
  3000.  
  3001. Some keyword instructions, such as those starting with the keyword DO, can include
  3002. nested instructions.
  3003.  
  3004. In the syntax diagrams, symbols (words) in upper case letters denote keywords; other
  3005. words (such as expression) denote a collection of symbols. Keywords are not case
  3006. dependent: the symbols if, If, and iF would all invoke the instruction IF. Also, you
  3007. usually omit most of the clause delimiters (;) shown because they are implied by the
  3008. end of a line.
  3009.  
  3010. =======================================================================================
  3011. 9.1    ADDRESS
  3012.  
  3013.    >>──ADDRESS─────┬────────────────────────────┬──;───><
  3014.                    ├─environment─┬────────────┬─┤
  3015.                    │             └─expression─┘ │
  3016.                    └┬───────┬───expression1─────┘
  3017.                     └─VALUE─┘
  3018.  
  3019. Address is used to send a single command to a specified environment, code an
  3020. environment, a literal string, or a single symbol, which is taken to be a constant,
  3021. followed by an expression. The expression is evaluated, and the resulting command
  3022. string is routed to environment. After the command is executed, environment is set back
  3023. to whatever it was before, thus temporarily changing the destination for a single
  3024. command.
  3025.  
  3026. Example:
  3027.  
  3028. ADDRESS CMD "DIR C:\STARTUP.CMD"   /*   OS/2   */
  3029.  
  3030. If only environment is specified, a lasting change of destination occurs: all commands
  3031. that follow (clauses that are neither REXX instructions nor assignment instructions)
  3032. will be routed to the given command environment, until the next ADDRESS instruction is
  3033. executed. The previously selected environment is saved.
  3034.  
  3035. Example:
  3036.  
  3037. Suppose that the environment for a text editor is registered by the name EDIT:
  3038.  
  3039. address CMD
  3040. 'DIR C:\STARTUP.CMD'
  3041. if rc=0 then 'COPY STARTUP.CMD *.TMP'
  3042. address EDIT
  3043.  
  3044. Subsequent commands are passed to the editor until the next ADDRESS instruction.
  3045.  
  3046. Similarly, you can use the VALUE form to make a lasting change to the environment.
  3047. Here expression1 (which may be just a variable name) is evaluated, and the result forms
  3048. the name of the environment.  The subkeyword VALUE can be omitted as long as
  3049. expression1 starts with a special character (so that it cannot be mistaken for a symbol
  3050. or string).
  3051.  
  3052. Example:
  3053.  
  3054. ADDRESS ('ENVIR'||number)
  3055.  
  3056. With no arguments, commands are routed back to the environment that was selected
  3057. before the previous lasting change of environment was made, and the current
  3058. environment name is saved. Repeated execution of ADDRESS alone, therefore, switches
  3059. the command destination between two environments alternately. A null string for the
  3060. environment name (" ") is the same as the default environment.
  3061.  
  3062. =======================================================================================
  3063. 9.2    ARG
  3064.  
  3065.    >>────ARG───────┬────────────┬────;───────────><
  3066.                    └──template──┘
  3067.  
  3068. ARG is used to retrieve the argument strings provided to a program or internal routine
  3069. and assign them to variables.  It is a short form of the following instruction:
  3070.  
  3071.    >>──PARSE UPPER ARG─┬────────────────┬──;───><
  3072.                        └────template────┘
  3073.  
  3074. Template is a list of symbols separated by blanks or patterns.
  3075.  
  3076. Unless a subroutine or internal function is being run, the interpreter reads the
  3077. arguments given on the program invocation, translates them to uppercase (for example,
  3078. a lowercase a-z to an uppercase A-Z), and then parses them into variables. Use the
  3079. PARSE ARG instruction if you do not want uppercase translation.
  3080.  
  3081. If a subroutine or internal function is being run, the data used will be the argument
  3082. strings passed to the routine.
  3083.  
  3084. The ARG (and PARSE ARG) instructions can be run as often as desired (typically with
  3085. different templates) and always parse the same current input strings. There are no
  3086. restrictions on the length or content of the data parsed except those imposed by the
  3087. caller.
  3088.  
  3089. Example:
  3090.  
  3091. /* String passed is "Easy Rider"  */
  3092.  
  3093. Arg adjective noun
  3094.  
  3095. /* Now:  "ADJECTIVE"  contains 'EASY'           */
  3096. /*       "NOUN"       contains 'RIDER'          */
  3097.  
  3098. If more than one string is expected to be available to the program or routine, each can
  3099. be selected in turn by using a comma in the parsing template.
  3100.  
  3101. Example:
  3102.  
  3103. /* function is invoked by  FRED('data X',1,5)   */
  3104.  
  3105. Fred:  Arg string, num1, num2
  3106.  
  3107. /* Now:  "STRING" contains 'DATA X'             */
  3108. /*       "NUM1"   contains '1'                  */
  3109. /*       "NUM2"   contains '5'                  */
  3110.  
  3111. Notes:
  3112.  
  3113.   The argument strings to a REXX program or internal routine can also be retrieved or
  3114.   checked by using the ARG built-in function.
  3115.  
  3116.   The source of the data being processed is also made available on entry to the
  3117.   program.  See the PARSE instruction (SOURCE option) for details.
  3118.  
  3119. =======================================================================================
  3120. 9.3    CALL
  3121.  
  3122.    >>────CALL───┬───name────┬──────────────────────────┬─────;─><
  3123.                 │           │   ┌──────,───────┐       │
  3124.                 │           │   V              │       │
  3125.                 │           └───┴──expression──┴───────┤
  3126.                 │                                      │
  3127.                 ├───OFF─────┬──ERROR──────┬────────────┤
  3128.                 │           ├──FAILURE────┤            │
  3129.                 │           ├──HALT───────┤            │
  3130.                 │           └──NOTREADY───┘            │
  3131.                 │                                      │
  3132.                 └──ON──┬─ERROR────┬─┬───────────────┬──┘
  3133.                        ├─FAILURE──┤ └─NAME─trapname─┘
  3134.                        ├─HALT─────┤
  3135.                        └─NOTREADY─┘
  3136.  
  3137. CALL is used to invoke a routine (if you specify name) or to control the trapping of
  3138. certain conditions (if ON or OFF is specified)
  3139.  
  3140. To control trapping, specify OFF or ON and the condition you want to trap.  OFF turns
  3141. off the specified condition trap.  ON turns on the specified condition trap.
  3142.  
  3143. To invoke a routine, specify name, which is a symbol or literal string that is taken as
  3144. a constant.  The name must be a valid symbol. The routine invoked can be any of the
  3145. following:
  3146.  
  3147.   An internal routine
  3148.   An external routine
  3149.   A built-in function.
  3150.  
  3151. If a string is used for name (that is, name is specified in quotation marks) the search
  3152. for internal labels is bypassed, and only a built-in function or an external routine is
  3153. invoked.  Note that the names of built-in functions (and generally the names of
  3154. external routines too) are in uppercase; therefore, the name in the literal string
  3155. should be in uppercase.
  3156.  
  3157. The routine can optionally return a result and is functionally identical to the clause:
  3158.  
  3159.   >>─result=name(─┬────────────────────┬─)──;──><
  3160.                   │ ┌──────,────────┐  │
  3161.                   │ V               │  │
  3162.                   └─┴┬────────────┬─┴──┘
  3163.                      └─expression─┘
  3164.  
  3165. The exception is that the variable result becomes uninitialized if no result is
  3166. returned by the routine invoked.
  3167.  
  3168. The name given in the CALL instruction must be a valid symbol.
  3169.  
  3170. The OS/2 interpreter supports the specification of up to 20 expressions, separated by
  3171. commas. The expressions are evaluated in order from left to right, and form the
  3172. argument strings during execution of the routine. Any ARG or PARSE ARG instructions or
  3173. ARG built-in function in the called routine will access these strings rather than those
  3174. previously active in the calling program.  You can omit expressions, if appropriate, by
  3175. including extra commas.
  3176.  
  3177. The CALL then causes a branch to the routine called name using the same mechanism
  3178. as function calls. The order in which these are searched for is described in the
  3179. section on functions.  A brief summary follows:
  3180.  
  3181. Internal routines: These are sequences of instructions inside the same program,
  3182.                     starting at the label that matches name in the CALL instruction. If
  3183.                     the routine name is specified in quotation marks, then an internal
  3184.                     routine is not considered for that search order.
  3185.  
  3186. Built-in routines: These are routines built in to the language processor for providing
  3187.                     various functions.  They always return a string containing the
  3188.                     result of the function.
  3189.  
  3190. External routines: Users can write or make use of routines that are external to the
  3191.                     language processor and the calling program. An external routine can
  3192.                     be written in any language, including REXX, that supports the
  3193.                     system-dependent interfaces.  If an external routine, written in
  3194.                     REXX, is invoked as a subroutine by the CALL instruction, you can
  3195.                     retrieve any argument strings with the ARG or PARSE ARG
  3196.                     instructions or the ARG built-in function.
  3197.  
  3198. =======================================================================================
  3199. 9.4    DO
  3200.  
  3201.   >>─DO─┬───────────┬─┬─────────────┬─;─┬───────────────┬END─┬──────┬;──>
  3202.         └─repetitor─┘ └─conditional─┘   │┌─────────────┐│    └─name─┘
  3203.                                         │V             ││
  3204.                                         └┴─instruction─┴┘
  3205.  
  3206. repetitor:
  3207.  
  3208.    >─┬─name=expri─┬────────┬─┬────────┬─┬─────────┬─┬────><
  3209.      │            └TO─exprt┘ └BY─exprb┘ └FOR─exprf┘ │
  3210.      ├──FOREVER─────────────────────────────────────┤
  3211.      └──exprr───────────────────────────────────────┘
  3212.  
  3213. conditional:
  3214.  
  3215.    >───┬─WHILE─exprw──┬────><
  3216.        └─UNTIL─expru──┘
  3217.  
  3218. DO is used to group instructions together and optionally to execute them repetitively.
  3219. During repetitive execution, a control variable (name) can be stepped through some
  3220. range of values.
  3221.  
  3222. Syntax Notes:
  3223.  
  3224.   The exprr, expri, exprb, exprt, and exprf options (if any are present) are any
  3225.   expressions that evaluate to a number. The exprr and exprf options are further
  3226.   restricted to result in a nonnegative whole number. If necessary, the numbers will be
  3227.   rounded according to the setting of NUMERIC DIGITS.
  3228.  
  3229.   The exprw or expru options (if present) can be any expression that evaluates
  3230.   to 1 or 0.
  3231.  
  3232.   The TO, BY, and FOR phrases can be in any order, if used.
  3233.  
  3234.   The instructions can include assignments, commands, and keyword instructions
  3235.   (including any of the more complex constructs such as IF, SELECT, and the DO
  3236.   instruction itself).
  3237.  
  3238.   The subkeywords TO, BY, FOR, WHILE, and UNTIL are reserved within a DO
  3239.   instruction, in that they cannot name variables in the expressions but they can be
  3240.   used as the name of the control variable. FOREVER is similarly reserved, but only if
  3241.   it immediately follows the keyword DO.
  3242.  
  3243.   The exprb option defaults to 1, if relevant.
  3244.  
  3245. Simple DO Group:
  3246.  
  3247. If neither repetitor nor conditional is given, the construct merely groups a number of
  3248. instructions together.  These are executed once. Otherwise, the group of instructions
  3249. is repetitive DO loop, and they are executed according to the repetitor phrase,
  3250. optionally modified by the conditional phrase.
  3251.  
  3252. In the following example, the instructions are executed once.
  3253.  
  3254. Example:
  3255.  
  3256. /* The two instructions between DO and END will both */
  3257. /* be executed if A has the value 3.                 */
  3258. If a=3 then Do
  3259.             a=a+2
  3260.             Say 'Smile!'
  3261.             End
  3262.  
  3263. Simple Repetitive Loops:
  3264.  
  3265. If repetitor is omitted but there is a conditional or the repetitor is FOREVER, the
  3266. group of instructions will nominally be executed forever, that is, until the condition
  3267. is satisfied or a REXX instruction is executed that ends the loop (for example, LEAVE).
  3268.  
  3269. In the simple form of a repetitive loop, exprr is evaluated immediately (and must
  3270. result in a nonnegative whole number), and the loop is then executed that many times.
  3271.  
  3272. Example:
  3273.  
  3274. /* This displays "Hello" five times */
  3275. Do 5
  3276.   say 'Hello'
  3277.   end
  3278.  
  3279. Note that, similar to the distinction between a command and an assignment, if the first
  3280. character of exprr is a symbol and the second is an "=" character, the controlled form
  3281. of
  3282. repetitor is expected.
  3283.  
  3284. Controlled Repetitive Loops:
  3285.  
  3286. The controlled form specifies a control variable, name, which is assigned an initial
  3287. value (the result of expri, formatted as though 0 had been added). The variable is then
  3288. stepped (that is, the result of exprb is added at the bottom of the loop) each time the
  3289. group of instructions is run. The group is run repeatedly while the end condition
  3290. (determined by the result of exprt) is not met. If exprb is positive or zero, the loop
  3291. will be terminated when name is greater than exprt. If negative, the loop is terminated
  3292. when name is less than exprt.
  3293.  
  3294. The expri, exprt, and exprb options must result in numbers.  They are evaluated once
  3295. only, before the loop begins and before the control variable is set to its initial
  3296. value. The default value for exprb is 1. If exprt is omitted, the loop is run
  3297. indefinitely unless some other condition terminates it.
  3298.  
  3299. Example:
  3300.  
  3301. Do I=3 to -2 by -1        /* Would display:   */
  3302.   say i                   /*      3           */
  3303.   end                     /*      2           */
  3304.                           /*      1           */
  3305.                           /*      0           */
  3306.                           /*      -1          */
  3307.                           /*      -2          */
  3308.  
  3309. The numbers do not have to be whole numbers.
  3310.  
  3311. Example:
  3312.  
  3313. X=0.3                     /* Would display:   */
  3314. Do Y=X to X+4 by 0.7      /*     0.3          */
  3315.   say Y                   /*     1.0          */
  3316.   end                     /*     1.7          */
  3317.                           /*     2.4          */
  3318.                           /*     3.1          */
  3319.                           /*     3.8          */
  3320.  
  3321. The control variable can be altered within the loop, and this may affect the iteration
  3322. of the loop. Altering the value of the control variable is not normally considered good
  3323. programming practice, though it may be appropriate in certain circumstances.
  3324.  
  3325. Note that the end condition is tested at the start of each iteration (and after the
  3326. control variable is stepped, on the second and subsequent iterations). Therefore, the
  3327. group of instructions can be skipped entirely if the end condition is met immediately.
  3328. Note also that the control variable is referred to by name. If, for example, the
  3329. compound name A.I is used for the control variable, altering I within the loop causes a
  3330. change in the control variable.
  3331.  
  3332. The processing of a controlled loop can be bounded further by a FOR phrase. In this
  3333. case, exprf must be given and must evaluate to a nonnegative whole number. This acts
  3334. just like the repetition count in a simple repetitive loop, and sets a limit to the
  3335. number of iterations around the loop if no other condition terminates it. Similar to
  3336. the TO and BY expressions, it is evaluated once only-when the DO instruction is first
  3337. executed and before the control variable is given its initial value. Like the TO
  3338. condition, the FOR condition is checked at the start of each iteration.
  3339.  
  3340. Example:
  3341.  
  3342. Do Y=0.3 to 4.3 by 0.7 for 3  /* Would display:    */
  3343.   say Y                       /*     0.3           */
  3344.   end                         /*     1.0           */
  3345.                               /*     1.7           */
  3346.  
  3347. In a controlled loop, the name describing the control variable can be specified on the
  3348. END clause. This name must match name in the DO clause in all respects except case
  3349. (note that no substitution for compound variables is carried out); a syntax error
  3350. results if it does not. This enables the nesting of loops to be checked automatically,
  3351. with minimal overhead.
  3352.  
  3353. Example:
  3354.  
  3355. Do K=1 to 10
  3356.   ...
  3357.   ...
  3358.   End k  /* Checks that this is the END for K loop */
  3359.  
  3360. Note:    The values taken by the control variable may be affected by the NUMERIC       
  3361.          settings, since normal REXX arithmetic rules apply to the computation of      
  3362.          stepping the control variable. 
  3363.  
  3364. Conditional Phrases (WHILE and UNTIL):
  3365.  
  3366. Any of the forms of repetitor (none, FOREVER, simple, or controlled) can be followed by
  3367. a conditional phrase, which may cause termination of the loop. If you specify WHILE or
  3368. UNTIL, exprw or expru, respectively, is evaluated each time around the loop using the
  3369. latest values of all variables (and must evaluate to either 0 or 1). The group of
  3370. instructions is repeatedly processed either while the result is 1 or until the result
  3371. is 1.
  3372.  
  3373. For a WHILE loop, the condition is evaluated at the top of the group of instructions;
  3374. for an UNTIL loop, the condition is evaluated at the bottom, before the control
  3375. variable has been stepped.
  3376.  
  3377. Example:
  3378.  
  3379. Do I=1 to 10 by 2 until i>6
  3380.   say i
  3381.   end
  3382. /* Will display: 1, 3, 5, 7 */
  3383.  
  3384. Note:    The processing of repetitive loops can also be modified by using the LEAVE or
  3385.          ITERATE instructions.
  3386.  
  3387. =======================================================================================
  3388. 9.5    DROP
  3389.  
  3390.                 ┌───────────┐
  3391.                 V           │
  3392.    >>────DROP───┴───name────┴────;─────────────────><
  3393.  
  3394. Each name is a valid variable symbol, optionally enclosed in parentheses (to denote a
  3395. subsidiary list), and separated from any other name by one or more blanks or comments.
  3396.  
  3397. DROP is used to unassign variables; that is, to restore them to their original
  3398. uninitialized state.
  3399.  
  3400. Each variable specified is dropped from the list of known variables. If a single name
  3401. is enclosed in parentheses, then its value is used as a subsidiary list of variables to
  3402. drop. This stored list must follow the same rules as for the main list (that is, valid
  3403. variable names, separated by blanks) but with no parentheses and no leading or trailing
  3404. blanks. The variables are dropped in sequence from left to right. It is not an error to
  3405. specify a name more than once, or to DROP a variable that is not known. If an exposed
  3406. variable is named (see the PROCEDURE instruction), the variable itself in the older
  3407. generation is dropped.
  3408.  
  3409. Example:
  3410.  
  3411. j=4
  3412. Drop  a x.3 x.j
  3413. /* would reset the variables: A, X.3, and X.4 */
  3414. /* so that reference to them returns their name.    */
  3415.  
  3416. Here, a variable name in parentheses is used as a subsidiary list.
  3417.  
  3418. Example:
  3419.  
  3420. x=4;y=5;z=6;
  3421. a='x y z'
  3422. DROP (a)    /* will drop x,y, and z */
  3423.  
  3424. If a stem is specified (that is, a symbol that contains only one period, as the last
  3425. character), all variables starting with that stem are dropped.
  3426.  
  3427. Example:
  3428.  
  3429. Drop  x.
  3430. /* would reset all variables with names starting with X. */
  3431.  
  3432. =======================================================================================
  3433. 9.6    EXIT
  3434.  
  3435.    >>────EXIT───┬──────────────┬───;───────────────><
  3436.                 └──expression──┘
  3437.  
  3438. EXIT is used to leave a program unconditionally. Optionally, EXIT returns a data string
  3439. to the caller. The program is terminated immediately, even if an internal routine is
  3440. currently being run.  If no internal routine is active, RETURN and EXIT are identical
  3441. in their effect on the program that is being run.
  3442.  
  3443. If you specify expression, it is evaluated and the string resulting from the evaluation
  3444. is then passed back to the caller when the program terminates.
  3445.  
  3446. Example:
  3447.  
  3448. j=3
  3449. Exit j*4
  3450. /* Would exit with the string '12' */
  3451.  
  3452. If you do not specify expression, no data is passed back to the caller. If the program
  3453. was called as an external function, this is detected as an error, either immediately
  3454. (if RETURN was used), or on return to the caller (if EXIT was used).
  3455.  
  3456. "Running off the end" of the program is always equivalent to the EXIT instruction, in
  3457. that it terminates the whole program and returns no result string.
  3458.  
  3459. Note:    The language processor does not distinguish between invocation as a
  3460.          command on the one hand, and invocation as a subroutine or function on the
  3461.          other. If the program was invoked through a command interface, an attempt is
  3462.          made to convert the returned value to a return code acceptable by the REXX
  3463.          caller.  The returned string must be a whole number whose value will fit in a
  3464.          16-bit signed integer (within the range -2**15 to 2**15-1).
  3465.  
  3466. =======================================================================================
  3467. 9.7    IF
  3468.  
  3469.    >>──IF─expression─┬─┬THEN─┬─┬instruction─┬────────────────────┬───><
  3470.                      └;┘     └;┘            └─ELSE─┬─┬instruction┘
  3471.                                                    └;┘
  3472.  
  3473. IF is used to conditionally process an instruction or group of instructions depending
  3474. on the evaluation of the expression. The expression must evaluate to 0 or 1.
  3475.  
  3476. The instruction after the THEN is processed only if the result of the evaluation is 1.
  3477. If you specify an ELSE clause, the instruction after ELSE is processed only if the
  3478. result of the evaluation is 0.
  3479.  
  3480. Example:
  3481.  
  3482. if answer='YES' then say 'OK!'
  3483.                 else say 'Why not?'
  3484.  
  3485. Remember that if the ELSE clause is on the same line as the last clause of the THEN
  3486. part, you need a semicolon to terminate that clause. Example:
  3487.  
  3488. if answer='YES' then say 'OK!';  else say 'Why not?'
  3489.  
  3490. The ELSE binds to the nearest IF at the same level. The NOP instruction can be used to
  3491. eliminate errors and possible confusion when IF constructs are nested, as in the
  3492. following example.
  3493.  
  3494. Example:
  3495.  
  3496. If answer = 'YES' Then
  3497.    If name = 'FRED' Then
  3498.       say 'OK, Fred.'
  3499.    Else
  3500.       nop
  3501. Else
  3502.    say 'Why not?'
  3503.  
  3504. Notes:
  3505.  
  3506.  1. The instruction can be any assignment, command, or keyword instruction, including
  3507.     any of the more complex constructs such as DO, SELECT, or the IF instruction
  3508.     itself. A null clause is not an instruction; so putting an extra semicolon after
  3509.     the THEN or ELSE is not equivalent to putting a dummy instruction (as it would be
  3510.     in C). The NOP instruction is provided for this purpose.
  3511.  
  3512.  2. The symbol THEN cannot be used within expression, because the keyword THEN is
  3513.     treated differently, in that it need not start a clause.  This allows the
  3514.     expression on the IF clause to be terminated by the THEN, without a semicolon being
  3515.     required.  If this were not so, users of other computer languages would experience
  3516.     considerable difficulties.
  3517.  
  3518. =======================================================================================
  3519. 9.8    INTERPRET
  3520.  
  3521.    >>────INTERPRET────expression────;──────────────><
  3522.  
  3523. INTERPRET is used to process instructions that have been built dynamically by
  3524. evaluating expression.
  3525.  
  3526. The expression is evaluated, and is then processed (interpreted) as though the
  3527. resulting string was a line inserted into the input file (and bracketed by a DO; and an
  3528. END;).
  3529.  
  3530. Any instructions (including INTERPRET instructions) are allowed, but note that
  3531. constructions such as DO ... END and SELECT ... END must be complete. For example,
  3532. a string of instructions being interpreted cannot contain a LEAVE or ITERATE
  3533. instruction (valid only within a repetitive DO loop) unless it also contains the whole
  3534. repetitive DO ... END construct.
  3535.  
  3536. A semicolon is implied at the end of the expression during processing, as a service to
  3537. the user.
  3538.  
  3539. Example:
  3540.  
  3541. data='FRED'
  3542. interpret data '= 4'
  3543. /* Will a) build the string  "FRED = 4"         */
  3544. /*      b) execute  FRED = 4;                   */
  3545. /* Thus the variable "FRED" will be set to "4"  */ Example:
  3546.  
  3547. data='do 3; say "Hello there!"; end'
  3548. interpret data        /* Would display:         */
  3549.                       /*  Hello there!          */
  3550.                       /*  Hello there!          */
  3551.                       /*  Hello there!          */
  3552.  
  3553. Notes:
  3554.  
  3555.  1. Labels within the interpreted string are not permanent and are therefore ignored.
  3556.     Therefore, executing a SIGNAL instruction from within an interpreted string causes
  3557.     immediate exit from that string before the label search begins.
  3558.  
  3559.  2. If you are new to the concept of the INTERPRET instruction and are getting results
  3560.     that you do not understand, you might find that executing the instruction with
  3561.     TRACE R or TRACE I set is helpful.
  3562.  
  3563.     Example:
  3564.  
  3565.     /* Here we have a small program. */
  3566.     Trace Int
  3567.     name='Kitty'
  3568.     indirect='name'
  3569.     interpret 'say "Hello"' indirect'"!"'
  3570.  
  3571.     when run, the following trace is displayed:
  3572.  
  3573.     [C:\]kitty
  3574.     kitty
  3575.          3 *-* name='Kitty'
  3576.            >L>   "Kitty"
  3577.          4 *-* indirect='name'
  3578.            >L>   "name"
  3579.          5 *-* interpret 'say "Hello"' indirect'"!"'
  3580.            >L>   "say "Hello""
  3581.            >V>   "name"
  3582.            >O>   "say "Hello" name"
  3583.            >L>   ""!""
  3584.            >O>   "say "Hello" name"!""
  3585.            *-*  say "Hello" name"!"
  3586.            >L>    "Hello"
  3587.            >V>    "Kitty"
  3588.            >O>    "Hello Kitty"
  3589.            >L>    "!"
  3590.            >O>    "Hello Kitty!"
  3591.     Hello Kitty!
  3592.     [C:\]
  3593.  
  3594.     Lines 3 and 4 set the variables used in line 5. Execution of line 5 then proceeds
  3595.     in two stages. First the string to be interpreted is built up, using a literal
  3596.     string, a variable (INDIRECT), and another literal. The resulting pure character
  3597.     string is then interpreted, as though it were actually part of the original
  3598.     program. Since it is a new clause, it is traced as such (the second *-* trace flag
  3599.     line 5) and is then executed. Again a literal string is concatenated to the value
  3600.     of a variable (NAME) and another literal, and the final result is then displayed as
  3601.     follows: 
  3602.  
  3603.     Hello Kitty!
  3604.  3. For many purposes, the VALUE function can be used instead of the INTERPRET
  3605.     instruction.  Line 5 in the last example could therefore have been replaced by:
  3606.  
  3607.     say "Hello" value(indirect)"!"
  3608.  
  3609.     INTERPRET is usually only required in special cases, such as when more than one
  3610.     statement is to be interpreted at once.
  3611.  
  3612. =======================================================================================
  3613. 9.9    ITERATE
  3614.  
  3615.    >>────ITERATE──┬────────┬───;─────────────────><
  3616.                   └──name──┘
  3617.  
  3618. ITERATE is used to alter the flow within a repetitive DO loop (that is, any DO
  3619. construct other than that with a simple DO loop).
  3620.  
  3621. Processing of the group of instructions stops, and control is passed to the DO
  3622. instruction just as though the END clause had been encountered. The control variable
  3623. (if any) is incremented and tested, as normal, and the group of instructions is
  3624. processed again, unless the loop is terminated by the DO instruction.
  3625.  
  3626. If name is not specified, ITERATE steps the innermost active repetitive loop. If name
  3627. is specified, it must be the name of the control variable of a currently active loop
  3628. which may be the innermost loop; this is the loop that is stepped. Any active loops
  3629. inside the one selected for iteration are terminated (as though by a LEAVE
  3630. instruction).
  3631.  
  3632. Example:
  3633.  
  3634. do i=1 to 4
  3635.   if i=2 then iterate
  3636.   say i
  3637.   end
  3638. /* Would display the numbers:   1, 3, 4  */
  3639.  
  3640. Notes:
  3641.  
  3642.  1. If specified, name must match the name on the DO instruction in all respects except
  3643.     case. No substitution for compound variables is carried out when the comparison is
  3644.     made.
  3645.  
  3646.  2. A loop is active if it is currently being processed. If during execution of a loop,
  3647.     a subroutine is called or an INTERPRET instruction is processed, the loop becomes
  3648.     inactive until the subroutine has returned or the INTERPRET instruction has
  3649.     completed. ITERATE cannot be used to step an inactive loop.
  3650.  
  3651.  3. If more than one active loop uses the same control variable, the innermost loop is
  3652.     the one selected by ITERATE.
  3653.  
  3654. =======================================================================================
  3655. 9.10   LEAVE
  3656.  
  3657.    >>────LEAVE────┬────────┬────;────────────────><
  3658.                   └──name──┘
  3659.  
  3660. LEAVE is used to cause an immediate exit from one or more repetitive DO loops (that is,
  3661. any DO construct other than a simple DO loop).
  3662.  
  3663. Processing of the group of instructions is terminated, and control is passed to the
  3664. instruction following the END clause as though the END clause had been encountered
  3665. and the termination condition had been met normally.  However, on exit, the control
  3666. variable, if any, will contain the value it had when the LEAVE instruction was
  3667. processed.
  3668.  
  3669. If name is not specified, LEAVE terminates the innermost active repetitive loop. If
  3670. name is specified, it must be the name of the control variable of a currently active
  3671. loop which may be the innermost loop; that loop (and any active loops inside it) is
  3672. then terminated. Control then passes to the clause following the END clause that
  3673. matches the DO clause of the selected loop.
  3674.  
  3675. Example:
  3676.  
  3677. do i=1 to 5
  3678.   say i
  3679.   if i=3 then leave
  3680.   end
  3681. /* Would display the numbers:   1, 2, 3  */
  3682.  
  3683. Notes:
  3684.  
  3685.  1.  If specified, name must match the one on the DO instruction in all respects except
  3686.     case. No substitution for compound variables is carried out when the comparison is
  3687.     made.
  3688.  
  3689.  2. A loop is active if it is currently being processed. If during execution of a loop,
  3690.     a subroutine is called or an INTERPRET instruction is processed, the loop becomes
  3691.     inactive until the subroutine has returned or the INTERPRET instruction has
  3692.     completed. LEAVE cannot be used to terminate an inactive loop.
  3693.  
  3694.  3. If more than one active loop uses the same control variable, the innermost one is
  3695.     the one selected by LEAVE.
  3696.  
  3697. =======================================================================================
  3698. 9.11   NOP
  3699.  
  3700.    >>────NOP────;────────────────────────────────><
  3701.  
  3702. NOP is a dummy instruction that has no effect.  It can be useful as the target of a
  3703. THEN
  3704. or ELSE clause.
  3705.  
  3706. Example:
  3707.  
  3708. Select
  3709.    when a=b then nop           /* Do nothing */
  3710.    when a>b then say 'A > B'
  3711.    otherwise     say 'A < B'
  3712. end
  3713.  
  3714. Note:    Using an extra semicolon instead of the NOP inserts a null clause, which is
  3715.          ignored. The second WHEN clause is seen as the first instruction expected
  3716.          after the THEN clause, and therefore is treated as a syntax error. NOP is a
  3717.          true instruction, however, and is a valid target for the THEN clause.
  3718.  
  3719. =======================================================================================
  3720. 9.12   NUMERIC
  3721.  
  3722.    >>──NUMERIC─────┬──DIGITS─┬─────────────┬─────────┬──;──><
  3723.                    │         └─expression──┘         │
  3724.                    ├──FORM──┬──────────────────────┬─┤
  3725.                    │        ├─SCIENTIFIC───────────┤ │
  3726.                    │        ├─ENGINEERING──────────┤ │
  3727.                    │        └─┬───────┬─expression─┘ │
  3728.                    │          └─VALUE─┘              │
  3729.                    └──FUZZ──┬──────────────┬─────────┘
  3730.                             └──expression──┘
  3731.  
  3732. The NUMERIC instruction is used to change the way in which arithmetic operations are
  3733. carried out. The options of this instruction are described in detail in the OS/2
  3734. Procedures Language 2/REXX Reference.
  3735.  
  3736. NUMERIC DIGITS controls the precision to which arithmetic operations and arithmetic
  3737. built-in functions are evaluated. If expression is omitted, then the default value of 9
  3738. is used.  Otherwise the result of the expression is rounded, if necessary, according to
  3739. the current setting of NUMERIC DIGITS. The value used must be a positive whole number
  3740. that is larger than the current NUMERIC FUZZ setting.
  3741.  
  3742. There is no limit to the value for DIGITS (except the amount of storage available), but
  3743. note that high precisions are likely to require a good deal of processor time. It is
  3744. recommended that you use the default value wherever possible.
  3745.  
  3746. You can retrieve the current setting of NUMERIC DIGITS with the DIGITS built-in
  3747. function.
  3748.  
  3749. NUMERIC FORM controls the form of exponential notation used by REXX for the result of
  3750. arithmetic operations and arithmetic built-in functions. This may be either SCIENTIFIC
  3751. (in which case only one, nonzero digit appears before the decimal point), or
  3752. ENGINEERING (in which case the power of ten is always a multiple of three). The default
  3753. is SCIENTIFIC. The FORM is set either directly by the subkeywords SCIENTIFIC or
  3754. ENGINEERING or is taken from the result of evaluating the expression following VALUE.
  3755. The result in this case must be either SCIENTIFIC or ENGINEERING. You can omit the
  3756. subkeyword VALUE if the expression does not begin with a symbol or a literal string
  3757. (for example, if it starts with a special character, such as an operator or
  3758. parenthesis).
  3759.  
  3760. You can retrieve the current setting of NUMERIC FORM with the FORM built-in function
  3761.  
  3762. NUMERIC FUZZ controls how many digits, at full precision, are ignored during a numeric
  3763. comparison operation. If expression is omitted, the default is 0 digits.  Otherwise
  3764. expression must evaluate to 0 or a positive whole number rounded, if necessary,
  3765. according to the current setting of NUMERIC DIGITS before it is used. The value used
  3766. must be a positive whole number that is smaller than the current NUMERIC DIGITS
  3767. setting.
  3768.  
  3769. FUZZ temporarily reduces the value of DIGITS by the FUZZ value before every numeric
  3770. comparison operation. The numbers being compared are subtracted from each other
  3771. under a precision of DIGITS minus FUZZ digits and this result is then compared with 0.
  3772.  
  3773. You can retrieve the current NUMERIC FUZZ setting with the FUZZ built-in function
  3774.  
  3775. Note:    The three numeric settings are automatically saved across subroutine and
  3776.          internal function calls.  See the CALL instruction for more details.
  3777.  
  3778. =======================================================================================
  3779. 9.13   OPTIONS
  3780.  
  3781.    >>────OPTIONS─────expression────;─────────────><
  3782.  
  3783. OPTIONS is used to pass special requests or parameters to the language processor.
  3784. For example, they can be language processor options or they can define a special
  3785. character set.
  3786.  
  3787. The expression is evaluated, and the result is examined one word at a time.  If the
  3788. words are recognized by the language processor, then they are obeyed.  Words that are
  3789. not recognized are ignored and assumed to be instructions to a different processor.
  3790.  
  3791. The following words are recognized by the language processors:
  3792.  
  3793. ETMODE           Specifies that literal strings containing double-byte character set
  3794. (DBCS)
  3795.                   characters can be used in the program.
  3796.  
  3797. NOETMODE         Specifies that literal strings containing DBCS characters cannot be
  3798. used
  3799.                   in the program. NOETMODE is the default.
  3800.  
  3801. EXMODE           Specifies that DBCS data in mixed strings is handled on a logical
  3802.                   character basis by instructions, operators and functions. DBCS data
  3803.                   integrity is maintained.
  3804.  
  3805. NOEXMODE         Specifies that any data in strings is handled on a byte basis. The
  3806.                   integrity of any DBCS characters might be lost. NOEXMODE is the
  3807.                   default.
  3808. Notes:
  3809.  
  3810.  1. Because of the scanning procedures of the language processor, you are advised to
  3811.     place an OPTIONS ETMODE instruction as the first instruction of a program
  3812.     containing DBCS literal strings.
  3813.  
  3814.  2. To ensure proper scanning of a program containing DBCS literals, type the words
  3815.     ETMODE, NOETMODE, EXMODE, and NOEXMODE as literal strings (that is, enclosed
  3816.     in quotation marks) in the OPTIONS instruction.
  3817.  
  3818.  3. The OPTIONS ETMODE and OPTIONS EXMODE settings are saved and restored
  3819.     across subroutine and function calls.
  3820.  
  3821.  4. The words ETMODE, EXMODE, NOEXMODE, and NOETMODE can occur several times
  3822.     within the result. The word that takes effect is determined by the last valid one
  3823.     specified between the pairs ETMODE/NOETMODE and EXMODE/NOEXMODE.
  3824.  
  3825. =======================================================================================
  3826. 9.14   PARSE
  3827.  
  3828.    >>──PARSE─┬───────┬─┬──ARG───────────────────────┬─┬────────────┬─;─><
  3829.              └─UPPER─┘ ├──PULL──────────────────────┤ └──template──┘
  3830.                        ├──SOURCE────────────────────┤      list
  3831.                        ├──VALUE─┬────────────┬─WITH─┤
  3832.                        │        └─expression─┘      │
  3833.                        ├──VAR──name─────────────────┤
  3834.                        └──VERSION───────────────────┘
  3835.  
  3836. PARSE is used to assign data from various sources to one or more variables according
  3837. to the rules and templates described in the section on parsing in the OS/2 Procedures
  3838. Language 2/REXX Reference.
  3839.  
  3840. If specified, a template is a list of symbols separated by blanks or patterns.
  3841.  
  3842. If template is not specified, no variables are set but action is taken to get the data
  3843. ready for parsing if necessary. Thus, for PARSE PULL, a data string is removed from the
  3844. current data queue; for PARSE LINEIN (and PARSE PULL if the current queue is empty),
  3845. a line is taken from the default character input stream; and for PARSE VALUE,
  3846. expression is evaluated. For PARSE VAR, the specified variable is accessed. If it does
  3847. not have a value, the NOVALUE condition is raised, if it is enabled.
  3848.  
  3849. If the UPPER option is specified, the data to be parsed is first translated to
  3850. uppercase (for example, a lowercase a-z to an uppercase A-Z). Otherwise, no uppercase
  3851. translation takes place during the parsing.
  3852.  
  3853. The data used for each variant of the PARSE instruction is as follows:
  3854.  
  3855. PARSE ARG - The strings passed to the program, subroutine, or function as the input
  3856. argument list, are parsed. See the ARG instruction for details and examples.
  3857.  
  3858. Note:    The argument strings to a REXX program or internal routine can also be
  3859.          retrieved or checked by using the ARG built-in function.
  3860.  
  3861. PARSE LINEIN - The next line from the default character input stream is parsed. (See
  3862. the OS/2 Procedures Language 2/REXX Reference for a discussion of the REXX input
  3863. model.) PARSE LINEIN is a shorter form of the following instruction:
  3864.  
  3865.    >>──PARSE─VALUE─LINEIN()─WITH─┬──────────┬────;──><
  3866.                                  └─template─┘
  3867.  
  3868. If no line is available, program execution will normally pause until a line is
  3869. complete. Note that PARSE LINEIN should only be used when direct access to the
  3870. character input stream is necessary. Normal line-by-line dialogue with the user should
  3871. be carried out with the PULL or PARSE PULL instructions, to maintain generality and
  3872. programmability.  To check if any lines are available in the default character input
  3873. stream, use the built-in function LINES.
  3874.  
  3875. PARSE PULL - The next string from the queue is parsed.  If the queue is empty, lines
  3876. will be read from the default input, typically the user's keyboard.  You can add data
  3877. to the head or tail of the queue by using the PUSH and QUEUE instructions respectively.
  3878. You can find the number of lines currently in the queue by using the QUEUED built-in
  3879. function. The queue remains active as long as the language processor is active. The
  3880. queue can be altered by other programs in the system and can be used as a means of
  3881. communication between these programs and programs written in REXX.
  3882.  
  3883. Note:    PULL and PARSE PULL read first from the current data queue; if the queue is
  3884.          empty, they read from the default input stream, STDIN (typically, the
  3885.          keyboard).
  3886.  
  3887. PARSE SOURCE - The data parsed describes the source of the program being run.
  3888.  
  3889. The source string contains the characters OS/2, followed by either COMMAND,
  3890. FUNCTION, or SUBROUTINE, depending on whether the program was invoked as a host
  3891. command or from a function call in an expression or using the CALL instruction. These
  3892. two tokens are followed by the complete path specification of the program file.
  3893.  
  3894. The string parsed might, therefore, be displayed as:
  3895.  
  3896. OS/2 COMMAND C:\OS2\REXTRY.CMD
  3897.  
  3898. PARSE VALUE - The expression is evaluated, and the result is the data that is parsed.
  3899. Note that WITH is a subkeyword in this context and so cannot be used as a symbol
  3900. within expression.  For example:
  3901.  
  3902. PARSE VALUE time() WITH  hours ':' mins ':' secs
  3903.  
  3904. gets the current time and splits it up into its constituent parts.
  3905.  
  3906. PARSE VAR name - The value of the variable specified by name is parsed.  The name
  3907. must be a symbol that is valid as a variable name; that is, it can not start with a
  3908. period or a digit.  Note that the variable name is not changed unless it appears in the
  3909. template. For example:
  3910.  
  3911. PARSE VAR string word1 string
  3912.  
  3913. removes the first word from string and puts it in the variable word1, and assigns the
  3914. remainder back to string.  Similarly:
  3915.  
  3916. PARSE UPPER VAR string word1 string
  3917.  
  3918. also translates the data from string to uppercase before it is parsed.
  3919.  
  3920. PARSE VERSION - Information describing the language level and the date of the
  3921. language processor is parsed.  This consists of five words (delimited by blanks): first
  3922. the string "REXXSAA", then the language level description ("4.00"), and finally the
  3923. release date ("13 June 1989").
  3924.  
  3925. Note:    PARSE VERSION information should be parsed on a word basis rather than on
  3926.          an absolute column position basis.
  3927.  
  3928. =======================================================================================
  3929. 9.15   PROCEDURE
  3930.  
  3931.    >>───PROCEDURE──┬────────────────────┬───;──────><
  3932.                    │          ┌───────┐ │
  3933.                    │          V       │ │
  3934.                    └──EXPOSE──┴─name──┴─┘
  3935.  
  3936. The PROCEDURE instruction can be used within an internal routine (subroutine or
  3937. function) to protect all the existing variables by making them unknown to the
  3938. instructions that follow. On executing a RETURN instruction, the original variables
  3939. environment is restored and any variables used in the routine (which were not exposed)
  3940. are dropped.
  3941.  
  3942. The EXPOSE option modifies this.  Any variable specified by name is exposed, so that
  3943. any reference to it (including setting and dropping) is made to the environment of the
  3944. variables that the caller owns. With the EXPOSE option, you must specify at least one
  3945. name, a symbol separated from any other name with one or more blanks. Optionally, you
  3946. can enclose a single name in parentheses to denote a subsidiary variable list. Any
  3947. variables not specified by name on a PROCEDURE EXPOSE instruction are still
  3948. protected.  Hence, some limited set of the caller's variables can be made accessible,
  3949. and these variables can be changed (or new variables in this set can be created).  All
  3950. these changes will be visible to the caller upon RETURN from the routine.
  3951.  
  3952. The variables are exposed in sequence from left to right. It is not an error to specify
  3953. a name more than once, or to specify a name that has not been used as a variable by the
  3954. caller.
  3955.  
  3956. Example:
  3957.  
  3958. /* This is the main program */
  3959. j=1; x.1='a'
  3960. call toft
  3961. say j k m       /* would display "1 7 M" */
  3962. exit
  3963.  
  3964. toft: procedure expose j k x.j
  3965.    say j k x.j  /* would display "1 K a"   */
  3966.    k=7; m=3     /* note "M" is not exposed */
  3967.    return
  3968.  
  3969. Note that if X.J in the EXPOSE list had been placed before J, the caller's value of J
  3970. would not have been visible at that time, so X.1 would not have been exposed.
  3971.  
  3972. If name is enclosed in parentheses (blanks are not necessary either inside or outside
  3973. the parentheses but can be added if desired) then, after that variable is exposed, the
  3974. value of the variable is immediately used as a subsidiary list of variables.  This list
  3975. of variables must follow the same rules as the main list except that no parentheses or
  3976. leading or trailing blanks are allowed. The variables named in a subsidiary list are
  3977. also exposed from left to right.
  3978.  
  3979. Example:
  3980.  
  3981. j=1;k=6;m=9
  3982. a ='j k m'
  3983. test:procedure expose (a)   /* will expose j, k, and x */
  3984.  
  3985. If a stem is specified in names, all possible compound variables whose names begin
  3986. with that stem are exposed. (A stem is a symbol containing only one period, which is
  3987. the last character.
  3988.  
  3989. Example:
  3990.  
  3991. lucky7:Procedure Expose i j a. b.
  3992. /* This exposes "I", "J", and all variables whose */
  3993. /* names start with "A." or "B."                  */
  3994. A.1='7'  /* This will set "A.1" in the caller's   */
  3995.          /* environment, even if it did not       */
  3996.          /* previously exist.                     */
  3997.  
  3998. Variables can be exposed through several generations of routines, if desired, by
  3999. ensuring that they are included on all intermediate PROCEDURE instructions.
  4000.  
  4001. Only one PROCEDURE instruction in each level of routine call is allowed; all others
  4002. (and those met outside of internal routines) are in error.
  4003.  
  4004. Notes:
  4005.  1. An internal routine need not include a PROCEDURE instruction, in which case the
  4006.     variables it is manipulating are those the caller owns.
  4007.  2. The PROCEDURE instruction must be the first instruction executed after the CALL or
  4008.     function invocation, that is, it must be the first instruction following the label.
  4009.  
  4010. See the CALL instruction for details and examples of how routines are invoked.
  4011. =======================================================================================
  4012. 9.16    PULL
  4013.  
  4014.    >>────PULL──────┬────────────┬─────;──────────><
  4015.                    └──template──┘
  4016.  
  4017. PULL is used to read a string from the head of the currently active REXX data queue. It
  4018. is a short form of the instruction:
  4019.  
  4020.    >>──PARSE UPPER PULL──┬─────────────┬─;────><
  4021.                          └──template───┘
  4022.  
  4023. The current head-of-queue is read as one string.  If no template is specified, no
  4024. further action is taken, and the string is effectively discarded.  If specified, a
  4025. template is a list of symbols separated by blanks or patterns. The string is translated
  4026. to uppercase (for example, a lowercase a-z to an uppercase A-Z), and then parsed into
  4027. variables according to the rules described in the section on parsing in the OS/2
  4028. Procedures Language 2/REXX Reference.  Use the PARSE PULL instruction if you do not
  4029. want uppercase translation.
  4030.  
  4031. Note:    If the current data queue is empty, PULL reads instead from STDIN (typically,
  4032.          the keyboard). The length of data read by the PULL instruction is restricted
  4033.          to the length of strings contained by variables.
  4034.  
  4035. Example:
  4036.  
  4037. Say 'Do you want to erase the file?  Answer Yes or No:'
  4038. Pull answer .
  4039. if answer='NO' then Say 'The file will not be erased.'
  4040.  
  4041. Here the dummy placeholder "." is used on the template to isolate the first word the
  4042. user enters.
  4043.  
  4044. The number of lines currently in the queue can be found with the QUEUED built-in
  4045. function.
  4046.  
  4047. =======================================================================================
  4048. 9.17   PUSH
  4049.  
  4050.    >>────PUSH──────┬──────────────┬─────;──────────><
  4051.                    └──expression──┘
  4052.  
  4053. PUSH is used to stack the string resulting from the evaluation of expression in LIFO
  4054. (last in, first out) format onto the currently active REXX data queue. If you do not
  4055. specify expression, a null string is stacked.
  4056.  
  4057. Example:
  4058.  
  4059. a='Fred'
  4060. push       /* Puts a null line onto the queue */
  4061. push a 2   /* Puts "Fred 2"    onto the queue */
  4062.  
  4063. The number of lines currently in the queue can be found with the QUEUED built-in
  4064. function.
  4065.  
  4066. =======================================================================================
  4067. 9.18   QUEUE
  4068.  
  4069.    >>────QUEUE─────┬──────────────┬────;───────────><
  4070.                    └──expression──┘
  4071.  
  4072. QUEUE is used to append the string resulting from expression to the tail of the
  4073. currently active REXX data queue. That is, it is added in FIFO (first in, first out)
  4074. format.
  4075.  
  4076. If you do not specify expression, a null string is queued.
  4077.  
  4078. Example:
  4079.  
  4080. a='Toft'
  4081. queue a 2  /* Enqueues "Toft 2" */
  4082. queue      /* Enqueues a null line behind the last */
  4083.  
  4084. The number of lines currently in the queue can be found with the QUEUED built-in
  4085. function.
  4086.  
  4087. =======================================================================================
  4088. 9.19   RETURN
  4089.  
  4090.    >>────RETURN────┬──────────────┬───;────────────><
  4091.                    └──expression──┘
  4092.  
  4093. RETURN is used to return control (and possibly a result) from a REXX program or
  4094. internal routine to the point of its invocation.
  4095.  
  4096. If no internal routine (subroutine or function) is active, RETURN and EXIT are
  4097. identical in their effect on the program that is being run.
  4098.  
  4099. If a subroutine is being processed (see the CALL instruction), expression (if any) is
  4100. evaluated, control passes back to the caller, and the REXX special variable RESULT is
  4101. set to the value of expression. If expression is omitted, the special variable RESULT
  4102. is dropped (becomes uninitialized). The various settings saved at the time of the CALL
  4103. (tracing, addresses, and so on) are also restored.
  4104.  
  4105. If a function is being processed, the action taken is identical, except that expression
  4106. must be specified on the RETURN instruction. The result of expression is then used in
  4107. the original expression at the point where the function was invoked.
  4108.  
  4109. If a PROCEDURE instruction was processed within the routine (subroutine or internal
  4110. function), all variables of the current generation are dropped (and those of the
  4111. previous generation are exposed) after expression is evaluated and before the result is
  4112. used or assigned to RESULT.
  4113.  
  4114. =======================================================================================
  4115. 9.20   SAY
  4116.  
  4117.    >>────SAY──────┬──────────────┬────;───────────><
  4118.                   └──expression──┘
  4119.  
  4120. SAY is used to write to the output stream the result of evaluating expression.  The
  4121. result is usually displayed to the user, but the output destination can depend on the
  4122. implementation. The result of expression can be of any length.
  4123.  
  4124. Notes:
  4125.  
  4126.  1. Data from the SAY instruction is sent to the default output stream (STDOUT:)
  4127.     However, the standard OS/2 rules for redirecting output apply to SAY output.
  4128.  
  4129.  2. The SAY instruction does not format data; line wrapping is handled by the operating
  4130.     system and the hardware. However formatting is accomplished, the output data
  4131.     remains a single logical line.
  4132.  
  4133. Example:
  4134.  
  4135. data=100
  4136. Say data 'divided by 4 =>' data/4
  4137. /* Would display: "100 divided by 4 => 25"  */
  4138.  
  4139. =======================================================================================
  4140. 9.21   SELECT
  4141.  
  4142.                ┌──────────────────────────────────────────┐
  4143.                V                                          │
  4144.    >>──SELECT;─┴WHEN─expression─┬─┬─THEN─┬─┬───instruction┴──>
  4145.                                 └;┘      └;┘
  4146.  
  4147.     >─────┬────────────────────────────────────┬───END;─────><
  4148.           └─OTHERWISE─┬─┬─┬───────────────────┬┘
  4149.                       └;┘ │  ┌─────────────┐  │
  4150.                           │  V             │  │
  4151.                           └──┴─instruction─┴──┘
  4152.  
  4153. SELECT is used to conditionally process one of several alternative instructions.
  4154.  
  4155. Each expression after a WHEN clause is evaluated in turn and must result in 0 or 1. If
  4156. the result is 1, the instruction following the THEN clause, which can be a complex
  4157. instruction such as IF, DO, or SELECT, is processed and control then passes to the END
  4158. clause. If the result is 0, control passes to the next WHEN clause.
  4159.  
  4160. If none of the WHEN expressions evaluate to 1, control passes to the instructions, if
  4161. any, after OTHERWISE. In this situation, the absence of OTHERWISE causes an error.
  4162.  
  4163. Example:
  4164.  
  4165.   balance = balance - check
  4166.   Select
  4167.     when balance > 0 then
  4168.       say 'Congratulations! You still have' balance 'dollars left.'
  4169.     when balance = 0 then do
  4170.       say 'Warning, Balance is now zero!  STOP all spending.'
  4171.       say "You cut it close this month! Hope you don't have any"
  4172.       say "checks left outstanding."
  4173.       end
  4174.     Otherwise
  4175.       say "You have just overdrawn your account."
  4176.       say "Your balance now shows" balance "dollars."
  4177.       say "Oops!  Hope the bank doesn't close your account."
  4178.   end  /* Select */
  4179.  
  4180. Notes:
  4181.  
  4182.  1. The instruction can be any assignment, command, or keyword instruction, including
  4183.     any of the more complex constructs such as DO, IF, or the SELECT instruction
  4184.     itself.
  4185.  
  4186.  2. A null clause is not an instruction, so putting an extra semicolon after a WHEN
  4187.     clause is not equivalent to putting a dummy instruction. The NOP instruction is
  4188.     provided for this purpose.
  4189.  
  4190.  3. The symbol THEN cannot be used within expression, because the keyword THEN is
  4191.     treated differently, in that it need not start a clause.  This allows the
  4192.     expression on the WHEN clause to be terminated by the THEN without a ; (delimiter)
  4193.     being required. 
  4194.  
  4195. =======================================================================================
  4196. 9.22   SIGNAL
  4197.  
  4198.    >>──SIGNAL───┬─ labelname ──────────────────────────┬─────;─><
  4199.                 ├─┬───────┬─ expression ───────────────┤
  4200.                 │ └ VALUE ┘                            │
  4201.                 ├── OFF ────┬─ ERROR ─────┬────────────┤
  4202.                 │           ├─ FAILURE ───┤            │
  4203.                 │           ├─ HALT ──────┤            │
  4204.                 │           ├─ NOVALUE ───┤            │
  4205.                 │           ├─ SYNTAX ────┤            │
  4206.                 │           └─ NOTREADY ──┘            │
  4207.                 │                                      │
  4208.                 └─ ON ─┬─ ERROR ───┬┬─────────────────┬┘
  4209.                        ├─ FAILURE ─┤└ NAME ─ trapname ┘
  4210.                        ├─ HALT ────┤
  4211.                        ├─ NOVALUE ─┤
  4212.                        ├─ SYNTAX ──┤
  4213.                        └─ NOTREADY ┘
  4214.  
  4215. SIGNAL is used to cause an abnormal change in the flow of control, or, if ON or OFF is
  4216. specified, controls the trapping of certain conditions.
  4217.  
  4218. To control trapping, you specify OFF or ON and the condition you want to trap. OFF
  4219. turns off the specified condition trap.  ON turns on the specified condition trap.
  4220.  
  4221. Note:    For information on condition traps, see the OS/2 Procedures Language 2/REXX
  4222.          Reference.
  4223.  
  4224. To change the flow of control, a label name is derived from labelname or taken from the
  4225. result of evaluating the expression after VALUE. The labelname you specify must be a
  4226. symbol, treated literally, or a literal string that is taken as a constant. The
  4227. subkeyword VALUE can be omitted if expression does not begin with a symbol or literal
  4228. string (for example, if it starts with a special character, such as an operator or
  4229. parenthesis).  All active pending DO, IF, SELECT, and INTERPRET instructions in the
  4230. current routine are then terminated; that is, they cannot be reactivated. Control then
  4231. passes to the first label in the program that matches the required string, as though
  4232. the search had started from the top of the program.
  4233.  
  4234. Example:
  4235.  
  4236. Signal fred;  /* Jump to label "FRED" below */
  4237.   ....
  4238.   ....
  4239. Fred: say 'Hi!' Because the search effectively starts at the top of the program, if duplicates are
  4240. present, control always passes to the first occurrence of the label in the program
  4241.  
  4242. When control reaches the specified label, the line number of the SIGNAL instruction is
  4243. assigned to the special variable SIGL. This can aid debugging because SIGNAL can
  4244. determine the source of a jump to a label.
  4245.  
  4246. Using SIGNAL with the INTERPRET Instruction
  4247.  
  4248. If, as the result of an INTERPRET instruction, a SIGNAL instruction is issued or a
  4249. trapped event occurs, the remainder of the strings being interpreted are not searched
  4250. for the given label. In effect, labels within interpreted strings are ignored.
  4251.  
  4252. =======================================================================================
  4253. 9.23   TRACE
  4254.  
  4255.   >>─ TRACE ─┬──────────────────┬──────────┬────────┬─;─><
  4256.              │ ┌───────────┐    └─ number ─┘        │
  4257.              │ V           │                        │
  4258.              └─┴─┬───────┬─┴─┬────────────────────┬─┘
  4259.                  └───?───┘   ├── All ─────────────┤
  4260.                              ├── Commands ────────┤
  4261.                              ├── Error ───────────┤
  4262.                              ├── Failure ─────────┤
  4263.                              ├── Intermediates ───┤
  4264.                              ├── Labels ──────────┤
  4265.                              ├── Normal ──────────┤
  4266.                              ├── Off ─────────────┤
  4267.                              └── Results ─────────┘
  4268.  
  4269. Or, alternatively:
  4270.  
  4271.   >>──TRACE───┬──────────────────────────┬───;───────><
  4272.               ├──────string──────────────┤
  4273.               ├──────symbol──────────────┤
  4274.               └──┬───────┬──expression───┘
  4275.                  └─VALUE─┘
  4276.  
  4277. TRACE is used for debugging.  It controls the tracing action taken (that is, how much
  4278. is displayed to the user) during execution of a REXX program.  The syntax of TRACE is
  4279. more concise than other REXX instructions.  The economy of key strokes for this
  4280. instruction is especially convenient since TRACE is usually entered manually during
  4281. interactive debugging.
  4282.  
  4283. The number is a whole number.
  4284.  
  4285. The string or expression evaluates to:
  4286.  
  4287.   A number option
  4288.   One of the valid prefix, alphabetic character (word) options, or both, shown in this
  4289.   panel
  4290.   Null.
  4291.  
  4292. The symbol is taken as a constant and is:
  4293.  
  4294.   A number option
  4295.   One of the valid prefix, alphabetic character (word) options, or both, shown in this
  4296.   panel.
  4297.  
  4298. The tracing action is determined from the option specified following TRACE or from the
  4299. result of evaluating expression. If expression is used, you can omit the subkeyword
  4300. VALUE as long as expression starts with a special character or operator (so it is not
  4301. mistaken for a symbol or string).
  4302.  
  4303. Alphabetic Character (Word) Options
  4304.  
  4305. Although it is acceptable to enter the word in full, only the uppercase letter is
  4306. significant; all other letters are ignored. That is why these are referred to as
  4307. alphabetic character options.
  4308.  
  4309. TRACE actions correspond to the alphabetic character options as follows:
  4310.  
  4311. All                  All clauses are traced (that is, displayed) before execution.
  4312.  
  4313. Commands             All host commands are traced before execution, and any error
  4314.                       return code is displayed.
  4315.  
  4316. Error                Any host command resulting in an error return code is traced after
  4317.                       execution.
  4318.  
  4319. Failure              Any host command resulting in a failure is traced after execution.
  4320.                       This is the same as the Normal option.
  4321.  
  4322. Intermediates        All clauses are traced before execution. Intermediate results
  4323.                       during evaluation of expressions and substituted names are also
  4324.                       traced.
  4325.  
  4326. Labels               Labels passed during execution are traced. This is especially
  4327.                       useful with debug mode, when the language processor pauses after
  4328.                       each label.  It is also convenient for the user to make note of
  4329.                       all subroutine calls and signals.
  4330.  
  4331. Normal               Any failing host command is traced after execution. This is the
  4332.                       default setting.
  4333.  
  4334.                       For the default CMD processor in the OS/2 operating system, an
  4335.                       attempt to issue an unknown command raises a FAILURE condition.
  4336.                       An attempt to issue a command to an unknown subcommand
  4337.                       environment also raises a FAILURE condition; in such a case, the
  4338.                       variable RC is set to 2, the OS/2 return code for "file not
  4339.                       found".
  4340.  
  4341. Off                  Nothing is traced, and the special prefix actions (see below) are
  4342.                       reset to OFF.
  4343.  
  4344. Results              All clauses are traced before execution.  Final results (contrast
  4345.                       with Intermediates, above) of evaluating an expression are
  4346.                       traced.  Values assigned during PULL, ARG, and PARSE instructions
  4347.                       are also displayed.  This setting is recommended for general
  4348.                       debugging.
  4349.  
  4350. Prefix Option
  4351.  
  4352. The prefix ? is valid either alone or with one of the alphabetic character options. You
  4353. can specify the prefix more than once, if desired.  Each occurrence of a prefix on an
  4354. instruction reverses the action of the previous prefix. The prefix must immediately
  4355. precede the option (no intervening blanks).
  4356.  
  4357. The prefix ? modifies tracing and execution.  ? is used to control interactive debug.
  4358. During normal execution, a TRACE instruction prefixed with ? causes interactive debug
  4359. to be switched on.
  4360.  
  4361. When interactive debug is in effect, you can switch it off by issuing a TRACE
  4362. instruction with a prefix ?.  Repeated use of the ? prefix, therefore, switchs you
  4363. alternately in and out of interactive debug. Or, interactive debug can be turned off at
  4364. any time by issuing TRACE O or TRACE with no options.
  4365.  
  4366. Numeric Options
  4367.  
  4368. If interactive debug is active and if the option specified is a positive whole number
  4369. (or an expression that evaluates to a positive whole number), that number indicates the
  4370. number of debug pauses to be skipped over. However, if the option is a negative whole
  4371. number (or an expression that evaluates to a negative whole number), all tracing,
  4372. including debug pauses, is temporarily inhibited for the specified number of clauses. 
  4373.  
  4374. If interactive debug is not active, numeric options are ignored.
  4375.  
  4376. Format of TRACE Output
  4377.  
  4378. Every clause traced will be displayed with automatic formatting (indentation) according
  4379. to its logical depth of nesting and so on, and the results (if requested) are indented
  4380. an extra two spaces and are enclosed in double quotation marks so that leading and
  4381. trailing blanks are apparent. 
  4382.  
  4383. All lines displayed during tracing have a three-character prefix to identify the type
  4384. of data being traced.  The prefixes and their definitions are the following:
  4385.  
  4386. *-*      Identifies the source of a single clause, that is, the data actually in the
  4387.           program.
  4388.  
  4389. +++      Identifies a trace message.  This can be the nonzero return code from a
  4390.           command, the prompt message when interactive debug is entered, an indication
  4391.           of a syntax error when in interactive debug, or the traceback clauses after a
  4392.           syntax error in the program.
  4393.  
  4394. >>>      Identifies the result of an expression (for TRACE R) or the value assigned to
  4395.           a variable during parsing, or the value returned from a subroutine call.
  4396.  
  4397. >.>      Identifies the value assigned to a placeholder during parsing.
  4398.  
  4399. The following prefixes are only used if Intermediates (TRACE I) are being traced:
  4400.  
  4401. >C>      The data traced is the name of a compound variable, traced after substitution
  4402.           and before use, provided that the name had the value of a variable
  4403.           substituted into it.
  4404.  
  4405. >F>      The data traced is the result of a function call.
  4406.  
  4407. >L>      The data traced is a literal (string, uninitialized variable, or constant
  4408.           symbol).
  4409.  
  4410. >O>      The data traced is the result of an operation on two terms.
  4411.  
  4412. >P>      The data traced is the result of a prefix operation.
  4413.  
  4414. >V>      The data traced is the contents of a variable.
  4415.  
  4416. =======================================================================================
  4417. SECTION 10      Functions
  4418.  
  4419. Syntax
  4420.  
  4421. You can include function calls to internal and external routines in an expression
  4422. anywhere that a data term (such as a string) would be valid, using the notation:
  4423.  
  4424.    >>──function─name(─┬──────────────────┬─)────><
  4425.                       │ ┌──────,───────┐ │
  4426.                       │ V              │ │
  4427.                       └─┴┬────────────┬┴─┘
  4428.                          └─expression─┘
  4429.  
  4430. function-name is a literal string or a single symbol, that is taken to be a constant.
  4431.  
  4432. There can be up to a maximum of 20 expressions, separated by commas, between the
  4433. parentheses. These expressions are called the arguments to the function. Each
  4434. argument expression may include further function calls.
  4435.  
  4436. The ( must be adjacent to the name of the function, with no blank in between, or the
  4437. construct is not recognized as a function call. (A blank operator is assumed at this
  4438. point instead.)
  4439.  
  4440. The arguments are evaluated in turn from left to right and they are all then passed to
  4441. the function. This then executes some operation (usually dependent on the argument
  4442. strings passed, though arguments are not mandatory) and eventually returns a single
  4443. character string. This string is then included in the original expression as though the
  4444. entire function reference had been replaced by the name of a variable that contained
  4445. that data.
  4446.  
  4447. For example, the function SUBSTR is built-in to the language processor and could be
  4448. used as:
  4449.  
  4450. N1='abcdefghijk'
  4451. Z1='Part of N1 is: 'Substr(N1,2,7)
  4452. /* would set Z1 to 'Part of N1 is: bcdefgh' */
  4453.  
  4454. A function call without any arguments must always include the parentheses to be
  4455. recognized as a function call.
  4456.  
  4457. date()  /* returns the date in the default format dd mon yyyy */
  4458.  
  4459. Calls to Functions and Subroutines
  4460.  
  4461. The mechanism for calling functions and subroutines is the same. The only difference is
  4462. that functions must return data, whereas subroutines need not. The following types of
  4463. routines can be called as functions:
  4464.  
  4465. Internal If the routine name exists as a label in the program, the current processing
  4466.           status is saved, so that it will later be possible to return to the point of
  4467.           invocation to resume processing. Control is then passed to the first label in
  4468.           the program that matches the name. As with a routine invoked by the CALL
  4469.           instruction, various other pieces of status information (TRACE and NUMERIC
  4470.           settings and so on) are also saved. See the CALL instruction for details of
  4471.           this. If an internal routine is to be called as a function, you must specify
  4472.           an expression in any RETURN instruction to return from the function.  This is
  4473.           not necessary if the function is called only as a subroutine.
  4474.  
  4475.           Example:
  4476.  
  4477.           /* Recursive internal function execution... */
  4478.           arg x
  4479.           say x'! =' factorial(x)
  4480.           exit
  4481.  
  4482.           factorial: procedure   /* calculate factorial by..  */
  4483.             arg n                /*  .. recursive invocation. */
  4484.             if n=0 then return 1
  4485.             return  factorial(n-1) * n
  4486.  
  4487.           FACTORIAL is unusual in that it invokes itself (this is known as recursive
  4488.           invocation).  The PROCEDURE instruction ensures that a new variable n is
  4489.           created for each invocation).
  4490.  
  4491. Built-in These functions are always available and are defined later in this section.
  4492.  
  4493. External You can write or make use of functions that are external to a program and to
  4494.           the language processor. An external function can be written in any language,
  4495.           including REXX, that supports the system-dependent interfaces used by the
  4496.           language processor to invoke it. Again, when called as a function, it must
  4497.           return data to the caller.
  4498.  
  4499. Notes:
  4500.  
  4501.  1. Calling an external REXX program as a function is similar to calling an internal
  4502.     routine.  The external routine is, however, an implicit PROCEDURE in that all the
  4503.     caller variables are always hidden and the status of internal values (NUMERIC
  4504.     settings and so on) start with their defaults (rather than inheriting those of the
  4505.     caller).
  4506.  
  4507.  2. Other REXX programs can be called as functions. You can use either EXIT or
  4508.     RETURN to leave the invoked REXX program; in either case, you must specify an
  4509.     expression.
  4510.  
  4511. Search Order
  4512.  
  4513. The search order for functions is the same as in the preceding list. That is, internal
  4514. labels take first precedence, then built-in functions, and finally external functions.
  4515.  
  4516. Internal labels are not used if the function name is given as a string (that is, is
  4517. specified in quotation marks); in this case the function must be built-in or external.
  4518. This lets you usurp the name of, for example, a built-in function to extend its
  4519. capabilities, but still be able to invoke the built-in function when needed.
  4520.  
  4521. Example:
  4522.  
  4523. /* Modified DATE to return sorted date by default */
  4524. date: procedure
  4525.       arg in
  4526.       if in='' then in='Sorted'
  4527.       return 'DATE'(in)
  4528.  
  4529. Built-in functions have names in uppercase letters.  The name in the literal string
  4530. must be in uppercase for the search to succeed, as in the example.  The same is usually
  4531. true of external functions.
  4532.  
  4533. External functions and subroutines have a system-defined search order.
  4534. REXX searches for external functions in the following order:
  4535.  
  4536.  1. Functions that have been loaded into the macrospace for pre-order execution
  4537.  2. Functions that are part of a function package.
  4538.  3. REXX functions in the current directory, with the current extension
  4539.  4. REXX functions along environment PATH, with the current extension
  4540.  5. REXX functions in the current directory, with the default extension
  4541.  6. REXX functions along environment PATH, with the default extension
  4542.  7. Functions that have been loaded into the macrospace for post-order execution.
  4543.  
  4544. Errors during Execution
  4545.  
  4546. If an external or built-in function detects an error of any kind, the language
  4547. processor is informed, and a syntax error results.  Processing of the clause that
  4548. included the function call is therefore terminated. Similarly, if an external function
  4549. fails to return data correctly,
  4550. this is detected by the language processor and reported as an error. 
  4551. If a syntax error occurs during the processing of an internal function, it can be
  4552. trapped (using SIGNAL ON SYNTAX) and recovery may then be possible. If the error is not
  4553. trapped, the program is terminated.
  4554.  
  4555. Return Values
  4556.  
  4557. A function normally returns a value that is substituted for the function call when the
  4558. expression is evaluated.
  4559.  
  4560. How the value returned by a function (or any REXX routine) is handled depends on
  4561. whether it is called by a function call or called as a subroutine with the CALL
  4562. instruction.
  4563.  
  4564. A routine called as a subroutine: If the routine returns a value, that value is stored
  4565. in the special variable named RESULT. Otherwise, the RESULT variable is dropped, and
  4566. its value is the string "RESULT".
  4567.  
  4568. A routine called as a function: If the function returns a value, that value is
  4569. substituted into the expression at the position where the function was called. 
  4570. Otherwise, REXX stops with an error message.
  4571.  
  4572. Examples:
  4573.  
  4574. /* Different ways to call a REXX procedure */
  4575. call Beep 500, 100         /* Example 1: a subroutine call */
  4576. bc = Beep(500, 100)        /* Example 2: a function call   */
  4577. Beep(500, 100)             /* Example 3: result passed as  */
  4578.                            /*            a command         */
  4579.  
  4580.   In Example 1, the built-in function BEEP is called as a REXX subroutine. The return
  4581.   value from BEEP is placed in the REXX special variable RESULT.
  4582.  
  4583.   Example 2 shows BEEP called as a REXX function. The return value from the function
  4584.   is substituted for the function call. The clause itself is an assignment instruction;
  4585.   the return value from the BEEP function is placed in the variable bc.
  4586.  
  4587.   In Example 3, the BEEP function is processed and its return value is substituted in
  4588.   the expression for the function call, just as in Example 2. In this case, however,
  4589.   the clause as a whole evaluates to a single expression; therefore the evaluated
  4590.   expression is passed to the current default environment as a command.
  4591.  
  4592.   Note:    Many other languages (such as C) throw away the return value of a function
  4593.            if it is not assigned to a variable. In REXX, however, a value returned as
  4594.            in Example 3 is passed on to the current environment or subcommand handler.
  4595.            If that environment is CMD (the default), then this action will result in
  4596.            the operating system performing a disk search for what seems to be a        
  4597.    command.
  4598.  
  4599. Built-in Functions
  4600.  
  4601. REXX provides a rich set of built-in functions. These include character manipulation,
  4602. conversion, and information functions.
  4603.  
  4604. Here are some general notes on the built-in functions:
  4605.  
  4606.   The parentheses in a function are always needed, even if no arguments are required.
  4607.   The first parenthesis must follow the name of the function with no space in between.
  4608.  
  4609.   The built-in functions work internally with NUMERIC DIGITS 9 and NUMERIC FUZZ 0
  4610.   and are unaffected by changes to the NUMERIC settings, except where stated.
  4611.  
  4612.   You can supply a null string where a string is referenced.
  4613.  
  4614.   If an argument specifies a length, it must be a nonnegative whole number. If it
  4615.   specifies a start character or word in a string, it must be a positive whole number,
  4616.   unless otherwise stated.
  4617.  
  4618.   Where the last argument is optional, you can always include a comma to indicate that
  4619.   you have omitted it; for example, DATATYPE(1,), like DATATYPE(1), would return NUM.
  4620.  
  4621.   If you specify a pad character, it must be exactly one character long.
  4622.  
  4623.   If a function has a suboption you can select by specifying the first character of a
  4624.   string, that character can be in uppercase or lowercase letters.
  4625.  
  4626.   Conversion between characters and hexadecimal involves the machine representation
  4627.   of character strings, and hence returns appropriately different results for ASCII and
  4628.   EBCDIC machines.
  4629.  
  4630.   A number of the functions described in this chapter support the
  4631.   double-byte-character-set (DBCS).  A complete list and description of these functions
  4632.   is given in the OS/2 Procedures Language 2/REXX Reference.
  4633.  
  4634. =======================================================================================
  4635. 10.1   ABBREV
  4636.  
  4637.    >>──ABBREV(information,info ─┬──────────┬─)─────────><
  4638.                                 └─,length──┘
  4639.  
  4640. ABBREV returns 1 if info is equal to the leading characters of information and the
  4641. length of info is not less than length. ABBREV returns 0 if neither of these conditions
  4642. is met.
  4643.  
  4644. If specified, length must be a nonnegative whole number. The default for length is the
  4645. number of characters in info.
  4646.  
  4647. Here are some examples:
  4648.  
  4649. ABBREV('Print','Pri')      ->    1
  4650. ABBREV('PRINT','Pri')      ->    0
  4651. ABBREV('PRINT','PRI',4)    ->    0
  4652. ABBREV('PRINT','PRY')      ->    0
  4653. ABBREV('PRINT','')         ->    1
  4654. ABBREV('PRINT','',1)       ->    0
  4655.  
  4656. Note:    A null string will always match if a length of 0 (or the default) is used.
  4657. This
  4658.          allows a default keyword to be selected automatically if desired. For example:
  4659.  
  4660.          say 'Enter option:';   pull option .
  4661.          select  /* keyword1 is to be the default */
  4662.            when abbrev('keyword1',option) then ...
  4663.            when abbrev('keyword2',option) then ...
  4664.            ...
  4665.            otherwise nop;
  4666.          end;
  4667.  
  4668. =======================================================================================
  4669. 10.2   ABS (Absolute Value)
  4670.  
  4671.    >>──ABS(number)──────────────><
  4672.  
  4673. ABS returns the absolute value of number. The result has no sign and is formatted
  4674. according to the current NUMERIC settings.
  4675.  
  4676. Here are some examples:
  4677.  
  4678. ABS('12.3')       ->    12.3
  4679. ABS(' -0.307')    ->    0.307
  4680.  
  4681. =======================================================================================
  4682. 10.3   ADDRESS
  4683.  
  4684.    >>──ADDRESS()────────────────><
  4685.  
  4686. ADDRESS returns the name of the environment to which host commands are currently
  4687. being submitted.  Trailing blanks are removed from the result.
  4688.  
  4689. Here are some examples:
  4690.  
  4691. ADDRESS( )    ->    'CMD'        /* OS/2 environment */
  4692. ADDRESS( )    ->    'EDIT'      /* possible editor */
  4693.  
  4694. =======================================================================================
  4695. 10.4   API Functions
  4696.  
  4697. The following built-in REXX functions can be used in a REXX program to register, drop,
  4698. or query external function packages and to create and manipulate external data queues.
  4699.  
  4700. RXFUNCADD
  4701. +
  4702.    >>─RXFUNCADD(name,module,procedure)────────><
  4703.  
  4704. RXFUNCADD registers the function name, making it available to REXX procedures. A
  4705. zero return value signifies successful registration.
  4706. RXFUNCDROP
  4707.  
  4708.    >>─RXFUNCDROP(name)────────────────────────><
  4709.  
  4710. RXFUNCDROP removes (deregisters) the function name from the list of available
  4711. functions. A zero return value signifies successful removal.
  4712.  
  4713. RXFUNCQUERY
  4714.  
  4715.    >>─RXFUNCQUERY(name)───────────────────────><
  4716.  
  4717. RXFUNCQUERY queries the list of available functions for a registration of the name
  4718. function. The function returns a value of 0 if the function is registered, and a value
  4719. of 1
  4720. if it is not.
  4721.  
  4722. RXQUEUE
  4723.  
  4724.    >>──RXQUEUE(─┬──"Get"───────────────────┬─)─────><
  4725.                 ├──"Set"──────newqueuename─┤
  4726.                 ├──"Delete"───queuename────┤
  4727.                 └──"Create"─┬──────────────┤
  4728.                             └─,queuename───┘
  4729.  
  4730. RXQUEUE is used in a REXX program to create and delete external data queues and to
  4731. set and query their names.
  4732.  
  4733. =======================================================================================
  4734. 10.5   ARG
  4735.  
  4736.    >>──ARG(─┬───────────────────┬─)───────────><
  4737.             └─n──┬───────────┬──┘
  4738.                  └─,option───┘
  4739.  
  4740. ARG returns an argument string, or information about the argument strings to a program
  4741. or internal routine.
  4742.  
  4743. If you do not specify a parameter, the number of arguments passed to the program or
  4744. internal routine is returned.
  4745.  
  4746. If only n is specified, the n th argument string is returned. If the argument string
  4747. does not exist, the null string is returned. n must be a positive whole number.
  4748.  
  4749. If you specify option, ARG tests for the existence of the n th argument string. Valid
  4750. options (of which only the capitalized letter is significant and all others are
  4751. ignored) are:
  4752.  
  4753. Exists     Returns 1 if the n th argument exists; that is, if it was explicitly
  4754. specified
  4755.             when the routine was called. Returns 0 otherwise.
  4756.  
  4757. Omitted    Returns 1 if the nth was omitted; that is, if it was not explicitly
  4758.             specified when the routine was called. Returns 0 otherwise.
  4759.  
  4760. Here are some examples:
  4761.  
  4762. /*  following "Call name;" (no arguments) */
  4763. ARG( )        ->    0
  4764. ARG(1)        ->    ''
  4765. ARG(2)        ->    ''
  4766. ARG(1,'e')    ->    0
  4767. ARG(1,'O')    ->    1
  4768.  
  4769. /*  following "Call name 'a',,'b';" */
  4770. ARG( )        ->    3
  4771. ARG(1)        ->    'a'
  4772. ARG(2)        ->    ''
  4773. ARG(3)        ->    'b'
  4774. ARG(n)        ->    ''    /* for n>=4 */
  4775. ARG(1,'e')    ->    1
  4776. ARG(2,'E')    ->    0
  4777. ARG(2,'O')    ->    1
  4778. ARG(3,'o')    ->    0
  4779. ARG(4,'o')    ->    1
  4780.  
  4781. Notes:
  4782.  
  4783.  1. You can retrieve and directly parse the argument strings to a program or internal
  4784.     routine using the ARG or PARSE ARG instructions.
  4785.  2. Programs called as commands can have only 0 or 1 argument strings. The program
  4786.     has no argument strings if it is called with the name only and has 1 argument
  4787.     string if anything else (including blanks) is included with the command.
  4788.  3. Programs called by the REXXSTART entry point can have multiple argument strings.
  4789.  
  4790. =======================================================================================
  4791. 10.6   BEEP
  4792.  
  4793.    >>──BEEP(frequency,duration)───────><
  4794.  
  4795. BEEP sounds the speaker at frequency (Hertz) for duration milliseconds. The frequency
  4796. can be any number in the range 37 to 32767 Hertz. The duration can be any number in
  4797. the range 1 to 60000 milliseconds.
  4798.  
  4799. This routine is most useful when called as a subroutine. A null string is returned if
  4800. the routine is successful.
  4801.  
  4802. Here is an example:
  4803.  
  4804. /* C scale */
  4805. note.1 = 262    /* middle C */
  4806. note.2 = 294    /*    D     */
  4807. note.3 = 330    /*    E     */
  4808. note.4 = 349    /*    F     */
  4809. note.5 = 392    /*    G     */
  4810. note.6 = 440    /*    A     */
  4811. note.7 = 494    /*    B     */
  4812. note.8 = 524    /*    C     */
  4813. do i=1 to 8
  4814.   call beep note.i,250    /* hold each note for */
  4815.                           /* one-quarter second */
  4816. end
  4817.  
  4818. =======================================================================================
  4819. 10.7   BITAND
  4820.  
  4821.    >>──BITAND(string1─┬───────────────────────┬─)──────><
  4822.                       └─,─┬────────┬─┬──────┬─┘
  4823.                           └─string2┘ └─,pad─┘
  4824.  
  4825. BITAND returns a string composed of the two input strings logically compared, bit by
  4826. bit, using the AND operator. The length of the result is the length of the longer of
  4827. the two strings. If no pad character is provided, the AND operation terminates when the
  4828. shorter of the two strings is exhausted, and the unprocessed portion of the longer
  4829. string is appended to the partial result.  If pad is provided, it is used to extend the
  4830. shorter of the two strings on the right, before carrying out the logical operation. The
  4831. default for string2 is the zero length (null) string.
  4832.  
  4833. Here are some examples:
  4834.  
  4835. BITAND('73'x,'27'x)            ->    '23'x
  4836. BITAND('13'x,'5555'x)          ->    '1155'x
  4837. BITAND('13'x,'5555'x,'74'x)    ->    '1154'x
  4838. BITAND('pQrS',,'DF'x)          ->    'PQRS' /* ASCII only  */
  4839.  
  4840. =======================================================================================
  4841. 10.8   BITOR
  4842.  
  4843.    >>──BITOR(string1─┬───────────────────────┬─)───────><
  4844.                      └─,─┬────────┬─┬──────┬─┘
  4845.                          └─string2┘ └─,pad─┘
  4846.  
  4847. BITOR returns a string composed of the two input strings logically compared, bit by
  4848. bit, using the OR operator. The length of the result is the length of the longer of the
  4849. two strings. If no pad character is provided, the OR operation terminates when the
  4850. shorter of the two strings is exhausted, and the unprocessed portion of the longer
  4851. string is appended to the partial result.  If pad is provided, it is used to extend the
  4852. shorter of the two strings on the right, before carrying out the logical operation. The
  4853. default for string2 is the zero length (null) string.
  4854.  
  4855. Here are some examples:
  4856.  
  4857. BITOR('15'x,'24'x)            ->    '35'x
  4858. BITOR('15'x,'2456'x)          ->    '3556'x
  4859. BITOR('15'x,'2456'x,'F0'x)    ->    '35F6'x
  4860. BITOR('1111'x,,'4D'x)         ->    '5D5D'x
  4861. BITOR('pQrS',,'20'x)          ->    'pqrs' /* ASCII only  */
  4862.  
  4863. =======================================================================================
  4864. 10.9   BITXOR
  4865.  
  4866.    >>──BITXOR(string1─┬───────────────────────┬─)──────><
  4867.                       └─,─┬────────┬─┬──────┬─┘
  4868.                           └─string2┘ └─,pad─┘
  4869.  
  4870. BITXOR returns a string composed of the two input strings logically compared bit by bit
  4871. using the exclusive OR operator. The length of the result is the length of the longer
  4872. of the two strings. If no pad character is provided, the XOR operation terminates when
  4873. the shorter of the two strings is exhausted, and the unprocessed portion of the longer
  4874. string is appended to the partial result.  If pad is provided, it is used to extend the
  4875. shorter of the two strings on the right, before carrying out the logical operation. The
  4876. default for string2 is the zero length (null) string.
  4877. Here are some examples:
  4878.  
  4879. BITXOR('12'x,'22'x)               ->  '30'x
  4880. BITXOR('1211'x,'22'x)             ->  '3011'x
  4881. BITXOR('C711'x,'222222'x,' ')     ->  'E53302'x  /* ASCII  */
  4882. BITXOR('1111'x,'444444'x)         ->  '555544'x
  4883. BITXOR('1111'x,'444444'x,'40'x)   ->  '555504'x
  4884. BITXOR('1111'x,,'4D'x)            ->  '5C5C'x
  4885.  
  4886. =======================================================================================
  4887. 10.10  B2X (Binary to Hexadecimal)
  4888.  
  4889.    >>───B2X(binary_string)──────><
  4890.  
  4891. Converts binary_string, a string of binary (0 or 1) digits, to an equivalent string of
  4892. hexadecimal characters. You can optionally include blanks in binary_string (at
  4893. four-digit boundaries only, not leading or trailing) to aid readability; they are
  4894. ignored.
  4895.  
  4896. The returned string uses uppercase letters for the values A-F, and does not include
  4897. blanks.
  4898.  
  4899. binary_string can be of any length; if it is the null string, then a null string is
  4900. returned.
  4901.  
  4902. If the number of binary digits in the string is not a multiple of four, then up to
  4903. three 0 digits will be added on the left before the conversion to make a total that is
  4904. a multiple of four.
  4905.  
  4906. Here are some examples:
  4907.  
  4908. B2X('11000011')    ==   'C3'
  4909. B2X('10111')       ==   '17'
  4910. B2X('101')         ==   '5'
  4911. B2X('1 1111 0000') ==   '1F0'
  4912.  
  4913. B2X( ) can be combined with the functions X2D( ) and X2C( ) to convert a binary number
  4914. into other forms. For example:
  4915.  
  4916. X2D(B2X('10111'))  ==   '23'   /* decimal 23 */
  4917.  
  4918. =======================================================================================
  4919. 10.11  CENTER/CENTRE
  4920.  
  4921.        ┌─CENTER(─┐
  4922.    >>──┤         ├──string,length ─┬───────┬─)──────><
  4923.        └─CENTRE(─┘                 └─,pad──┘
  4924.  
  4925. CENTER or CENTRE returns a string of length length with string centered in it, with pad
  4926. characters added as necessary to make up length. The default pad character is blank. If
  4927. the string is longer than length, it will be truncated at both ends to fit. If an odd
  4928. number of characters are truncated or added, the right-hand end loses or gains one more
  4929. character than the left-hand end.
  4930.  
  4931. Here are some examples:
  4932.  
  4933. CENTER(abc,7)               ->    '  ABC  '
  4934. CENTER(abc,8,'-')           ->    '--ABC---'
  4935. CENTRE('The blue sky',8)    ->    'e blue s'
  4936. CENTRE('The blue sky',7)    ->    'e blue ' Note:    This function can be called either CENTRE or CENTER, which avoids errors due
  4937. to the difference between the British and American spellings.
  4938.  
  4939. =======================================================================================
  4940. 10.12  CHARIN
  4941.  
  4942.    >>──CHARIN(─┬──────┬──┬──────────────────────────┬─)─────><
  4943.                └─name─┘  └─,─┬───────┬──┬─────────┬─┘
  4944.                              └─start─┘  └─,length─┘
  4945.  
  4946. CHARIN returns a string of up to length characters read from the character input stream
  4947. name. The form of the name is implementation dependent. If name is omitted, characters
  4948. are read from the default input stream, STDIN:. The default length is 1.
  4949.  
  4950. For persistent streams, a read position is maintained for each stream. In the OS/2
  4951. operating system, this is the same as the write position. Any read from the stream will
  4952. by default start at the current read position.  When the read is completed, the read
  4953. position is increased by the number of characters read.  A start value can be given to
  4954. specify an explicit read position.  This read position must be positive and within the
  4955. bounds of the stream, and must not be specified for a transient stream ( a port or
  4956. other serial device).  A value of 1 for start refers to the first character in the
  4957. stream.
  4958.  
  4959. If you specify a length of 0, then the read position will be set to the value of start,
  4960. but no characters are read and the null string is returned.
  4961.  
  4962. In a transient stream, if there are fewer then length characters available, then
  4963. execution of the program will normally stop until sufficient characters do become
  4964. available.  If, however, it is impossible for those characters to become available due
  4965. to an error or other problem, the NOTREADY condition is raised and CHARIN will return
  4966. with fewer than the requested number of characters.
  4967.  
  4968. Here are some examples:
  4969.  
  4970. CHARIN(myfile,1,3)   ->   'MFC'   /* the first 3     */
  4971.                                    /* characters      */
  4972. CHARIN(myfile,1,0)   ->   ''      /* now at start    */
  4973. CHARIN(myfile)       ->   'M'     /* after last call */
  4974. CHARIN(myfile,,2)    ->   'FC'    /* after last call */
  4975.  
  4976. /* Reading from the default input (here, the keyboard) */
  4977. /* User types 'abcd efg' */
  4978. CHARIN( )            ->   'a'      /* default is  */
  4979.                                              /* 1 character */
  4980. CHARIN(,,5)          ->   'bcd e'
  4981.  
  4982. Note 1:
  4983.  
  4984. CHARIN returns all characters that appear in the stream including control characters
  4985. such as line feed, carriage return, and end of file.
  4986.  
  4987. Note 2:
  4988.  
  4989. When CHARIN is used to read from the keyboard, program execution stops until you
  4990. press the Enter key.
  4991.  
  4992. =======================================================================================
  4993. 10.13  CHAROUT
  4994.  
  4995.    >>──CHAROUT(─┬──────┬──┬──────────────────────────┬─)─────><
  4996.                 └─name─┘  └─,─┬────────┬──┬────────┬─┘
  4997.                               └─string─┘  └─,start─┘
  4998.  
  4999. CHAROUT returns the count of characters remaining after attempting to write string to
  5000. the character output stream name. The form of the name is implementation dependent. If
  5001. name is omitted, characters in string will be written to the default output stream,
  5002. STDOUT: (normally the display) in the OS/2 operating system. string can be the null
  5003. string, in which case no characters are written to the stream and 0 is always returned.
  5004.  
  5005. For persistent streams, a write position is maintained for each stream. In the OS/2
  5006. implementation, this is the same as the read position. Any write to the stream starts
  5007. at the current write position by default.  When the write is completed the write
  5008. position is increased by the number of characters written.  The initial write position
  5009. is the end of the stream, so that calls to CHAROUT normally append to the end of the
  5010. stream.
  5011.  
  5012. A start value can be given to specify an explicit write position for a persistent
  5013. stream.
  5014. This write position must be a positive whole number within the bounds of the stream
  5015. (though it can specify the character position immediately after the end of the stream).
  5016. A
  5017. value of 1 for start refers to the first character in the stream.
  5018.  
  5019. Note:    In some environments, overwriting a stream with CHAROUT or LINEOUT can
  5020.          erase (destroy) all existing data in the stream. However, this is not the case
  5021. in
  5022.          the OS/2 environment.
  5023.  
  5024. The string can be omitted for persistent streams. In this case, the write position is
  5025. set to the value of start that was given, no characters are written to the stream, and
  5026. 0 is returned. If neither start nor string are given, the write position is set to the
  5027. end of the stream. This use of CHAROUT can also have the side effect of closing or
  5028. fixing the file in environments which support this concept.  Again, 0 is returned. If
  5029. you do not specify start or string, the stream is closed. Again, 0 is returned.
  5030.  
  5031. Processing of the program normally stops until the output operation is effectively
  5032. complete. If, however, it is impossible for all the characters to be written, the
  5033. NOTREADY condition is raised and CHAROUT returns with the number of characters that
  5034. could not be written (the residual count).
  5035.  
  5036. Here are some examples:
  5037.  
  5038. CHAROUT(myfile,'Hi')     ->   0   /* normally */
  5039. CHAROUT(myfile,'Hi',5)   ->   0   /* normally */
  5040. CHAROUT(myfile,,6)       ->   0   /* now at char 6 */
  5041. CHAROUT(myfile)          ->   0   /* at end of stream */
  5042. CHAROUT(,'Hi')           ->   0   /* normally */
  5043. CHAROUT(,'Hello')        ->   2   /* maybe */
  5044.  
  5045. Note:    This routine is often best called as a subroutine. The residual count is then
  5046.          available in the variable RESULT.  For example:
  5047.  
  5048. Call CHAROUT myfile,'Hello'
  5049. Call CHAROUT myfile,'Hi',6
  5050. Call CHAROUT myfile
  5051. =======================================================================================
  5052. 10.14  CHARS
  5053.  
  5054.    >>──CHARS(─┬──────┬──)─────><
  5055.               └─name─┘
  5056.  
  5057. CHARS returns the total number of characters remaining in the character input stream
  5058. name. The count includes any line separator characters, if these are defined for the
  5059. stream, and in the case of persistent streams, is the count of characters from the
  5060. current read position to the end of the stream. If name is omitted, OS/2 will use
  5061. STDIN: as the default.
  5062.  
  5063. The total number of characters remaining cannot be determined for some streams (for
  5064. example, STDIN:).  For these streams, the CHARS function returns 1 to indicate that
  5065. data is present, or 0 if no data is present. For OS/2 devices, CHARS always returns 1.
  5066.  
  5067. Here are some examples:
  5068.  
  5069. CHARS(myfile)     ->   42   /* perhaps */
  5070. CHARS(nonfile)    ->   0    /* perhaps */
  5071. CHARS()           ->   1    /* perhaps */
  5072.  
  5073. =======================================================================================
  5074. 10.15  COMPARE
  5075.  
  5076.    >>───COMPARE(string1,string2 ─┬───────┬─)──────><
  5077.                                  └─,pad──┘
  5078.  
  5079. COMPARE returns 0 if the strings, string1 and string2, are identical. Otherwise,
  5080. COMPARE returns the position of the first character that does not match. The shorter
  5081. string is padded on the right with pad if necessary.  The default pad character is a
  5082. blank.
  5083.  
  5084. Here are some examples:
  5085.  
  5086. COMPARE('abc','abc')         ->    0
  5087. COMPARE('abc','ak')          ->    2
  5088. COMPARE('ab ','ab')          ->    0
  5089. COMPARE('ab ','ab',' ')      ->    0
  5090. COMPARE('ab ','ab','x')      ->    3
  5091. COMPARE('ab-- ','ab','-')    ->    5
  5092.  
  5093. =======================================================================================
  5094. 10.16  CONDITION
  5095.  
  5096.    >>───CONDITION(─┬────────┬─)────────><
  5097.                    └─option─┘
  5098.  
  5099. CONDITION returns the condition information associated with the current trapped
  5100. condition.  You can request four pieces of information:
  5101.  
  5102.   The name of the current trapped condition
  5103.   Any descriptive string associated with that condition
  5104.   The instruction executed as a result of the condition trap (CALL or SIGNAL)
  5105.   The status of the trapped condition.
  5106.  
  5107. The following options (of which only the capitalized letter is needed, all others are
  5108. ignored) can be used to obtain the following information:
  5109.  
  5110. Condition name   Returns the name of the current trapped condition.
  5111.  
  5112. Description      Returns any descriptive string associated with the current trapped
  5113.                   condition. If no description is available, a null string is returned.
  5114.  
  5115. Instruction      Returns the keyword for the instruction executed when the current
  5116.                   condition was trapped.  The keywords are CALL or SIGNAL. This is the
  5117.                   default if you omit option.
  5118.  
  5119. Status           Returns the status of the current trapped condition.  This can change
  5120.                   during execution, and is either:
  5121.  
  5122.    ON - the condition is enabled
  5123.  
  5124.    OFF - the condition is disabled
  5125.  
  5126.    DELAY - any new occurrence of the condition is delayed.
  5127.  
  5128. If no condition has been trapped (that is, there is no current trapped condition) then
  5129. the CONDITION function returns a null string in all four cases.
  5130.  
  5131. Here are some examples:
  5132.  
  5133. CONDITION()            ->    'CALL'        /* perhaps */
  5134. CONDITION('C')         ->    'FAILURE'
  5135. CONDITION('I')         ->    'CALL'
  5136. CONDITION('D')         ->    'FailureTest'
  5137. CONDITION('S')         ->    'OFF'        /* perhaps */
  5138.  
  5139. Note:    The condition information returned by the CONDITION function is saved and
  5140.          restored across subroutine calls (including those caused by a CALL ON
  5141.          condition trap). Therefore, once a subroutine invoked due to a CALL ON trap
  5142.          has returned, the current trapped condition reverts to the current condition
  5143.          before the CALL took place. CONDITION returns the values it returned before
  5144.          the condition was trapped.
  5145.  
  5146. =======================================================================================
  5147. 10.17  COPIES
  5148.  
  5149.    >>───COPIES(string,n)──────><
  5150.  
  5151. COPIES returns n concatenated copies of string. n must be a nonnegative whole number.
  5152.  
  5153. Here are some examples:
  5154.  
  5155. COPIES('abc',3)    ->    'abcabcabc'
  5156. COPIES('abc',0)    ->    ''
  5157.  
  5158. =======================================================================================
  5159. 10.18  C2D (Character to Decimal)
  5160.  
  5161.    >>───C2D(string ─┬─────┬─)──────><
  5162.                     └─,n──┘
  5163.  
  5164. C2D returns the decimal value of the binary representation of string. If the result
  5165. cannot be expressed as a whole number, an error results. That is, the result must not
  5166. have more digits than the current setting of NUMERIC DIGITS. If string is the null string, then 0 is returned. If n is not specified, string is
  5167. processed as an unsigned binary number.
  5168.  
  5169. Here are some examples:
  5170.  
  5171. C2D('09'X)      ->        9
  5172. C2D('81'X)      ->      129
  5173. C2D('FF81'X)    ->    65409
  5174. C2D('a')        ->       97     /* ASCII */
  5175.  
  5176. If n is specified, the given string is padded on the left with 00x characters (note,
  5177. not sign-extended), or truncated on the left to n characters. The resulting string of n
  5178. hexadecimal digits is taken to be a signed binary number: positive if the leftmost bit
  5179. is OFF, and negative, in two's complement notation, if the leftmost bit is ON. If n is
  5180. 0, then 0 is always returned.
  5181.  
  5182. Here are some examples:
  5183.  
  5184. C2D('81'X,1)      ->     -127
  5185. C2D('81'X,2)      ->      129
  5186. C2D('FF81'X,2)    ->     -127
  5187. C2D('FF81'X,1)    ->     -127
  5188. C2D('FF7F'X,1)    ->      127
  5189. C2D('F081'X,2)    ->    -3967
  5190. C2D('F081'X,1)    ->     -127
  5191. C2D('0031'X,0)    ->        0
  5192.  
  5193. Implementation maximum: The input string cannot have more than 250 characters that
  5194. will be significant in forming the final result.  Leading sign characters (00x and ffx)
  5195. do not count toward this total.
  5196.  
  5197. =======================================================================================
  5198. 10.19  C2X (Character to Hexadecimal)
  5199.  
  5200.    >>───C2X(string)──────><
  5201.  
  5202. C2X converts a character string to its hexadecimal representation. The data to be
  5203. converted can be of any length. The returned string contains twice as many bytes as the
  5204. input string because it is in literal string notation.
  5205.  
  5206. Here are some examples:
  5207.  
  5208. C2X('0123'X)    ->    '0123'
  5209. C2X('ZD8')      ->    '5A4438'     /*   ASCII    */
  5210.  
  5211. =======================================================================================
  5212. 10.20  DATATYPE
  5213.  
  5214.    >>───DATATYPE(string ─┬─────────┬─)──────><
  5215.                          └──,type──┘
  5216.  
  5217. DATATYPE determines whether 'data' is numeric or alphabetic and returns a result of
  5218. NUM or CHAR. If only string is specified, the returned result is NUM if string is a
  5219. valid REXX number (any format); otherwise CHAR will be the returned result.
  5220.  
  5221. If type is specified, the returned result is 1 if string matches the type; otherwise, a
  5222. 0 is returned. If string is null, 0 is returned (except when type is X, which returns
  5223. 1). The following is a list of valid types. Only the capitalized letter is significant
  5224. (all others are ignored).
  5225. Alphanumeric     Returns 1 if string contains only characters from the ranges a-z,
  5226. A-Z,
  5227.                   and 0-9.
  5228.  
  5229. Bits             Returns 1 if string contains only the characters 0 and/or 1.
  5230.  
  5231. C                Returns 1 if string is a mixed SBCS/DBCS string.
  5232.  
  5233. Dbcs             Returns 1 if string is a pure DBCS string.
  5234.  
  5235. Lowercase        Returns 1 if string contains only characters from the range a-z.
  5236.  
  5237. Mixed case       Returns 1 if string contains only characters from the ranges a-z and
  5238.                   A-Z.
  5239.  
  5240. Number           Returns 1 if string is a valid REXX number.
  5241.  
  5242. Symbol           Returns 1 if string contains only characters that are valid in REXX
  5243.                   symbols. Note that both uppercase and lowercase letters are
  5244.                   permitted.
  5245.  
  5246. Uppercase        Returns 1 if string contains only characters from the range A-Z.
  5247.  
  5248. Whole number     Returns 1 if string is a REXX whole number under the current setting
  5249. of
  5250.                   NUMERIC DIGITS.
  5251.  
  5252. heXadecimal      Returns 1 if string contains only characters from the ranges a-f, A-F,
  5253.                   0-9, and blank (so long as blanks only appear between pairs of
  5254.                   hexadecimal characters). Also returns 1 if string is a null string.
  5255.  
  5256. DATATYPE(' 12 ')         ->   'NUM'
  5257. DATATYPE('')             ->   'CHAR'
  5258. DATATYPE('123*')         ->   'CHAR'
  5259. DATATYPE('12.3','N')     ->    1
  5260. DATATYPE('12.3','W')     ->    0
  5261. DATATYPE('Fred','M')     ->    1
  5262. DATATYPE('','M')         ->    0
  5263. DATATYPE('Fred','L')     ->    0
  5264. DATATYPE('?20K','S')     ->    1
  5265. DATATYPE('BCd3','X')     ->    1
  5266. DATATYPE('BC d3','X')    ->    1
  5267.  
  5268. =======================================================================================
  5269. 10.21  DATE
  5270.  
  5271.    >>───DATE(──┬─────────┬─)──────><
  5272.                └─option──┘
  5273.  
  5274. DATE returns, by default, the local date in the format: dd mon yyyy (for example, 27
  5275. Aug 1988), with no leading zero or blank on the day. For mon, the first three
  5276. characters of the English name of the month will be used.
  5277.  
  5278. The following options (of which only the capitalized letter is needed, all others are
  5279. ignored) can be used to obtain alternative formats:
  5280.  
  5281. Basedate       Returns the number of complete days (that is, not including the current
  5282.                 day) since and including the base date, January 1, 0001, in the format:
  5283.                 dddddd (no leading zeros). The expression   DATE(B)//7   returns a
  5284.                 number in the range 0-6, where 0 is Monday and 6 is Sunday.                 Note:    The origin of January 1, 0001 is based on the Gregorian
  5285.                          calendar. Though this calendar did not exist prior to 1582,
  5286.                          Basedate is calculated as if it did: 365 days per year, an
  5287. extra
  5288.                          day every four years except century years, and leap centuries
  5289. if
  5290.                          the century is divisible by 400. It does not take into account
  5291. any
  5292.                          errors in the calendar system that created the Gregorian
  5293. calendar
  5294.                          originally.
  5295.  
  5296. Days           Returns the number of days, including the current day, so far in this
  5297.                 year in the format: ddd (no leading zeros)
  5298.  
  5299. European       Returns date in the format: dd/mm/yy.
  5300.  
  5301. Language       Returns date in an implementation and language dependent or local date
  5302.                 format. In the OS/2 operating system, the Language format is dd Month
  5303.                 yyyy. If no local format is available, the default format is returned.
  5304.  
  5305.                 Note:    This format is intended to be used as a whole; REXX programs
  5306.                          should not make any assumptions about the form or content of
  5307.                          the returned string.
  5308.  
  5309. Month          Returns full English name of the current month, for example, August
  5310.  
  5311. Normal         Returns date in the default format: dd mon yyyy
  5312.  
  5313. Ordered        Returns date in the format: yy/mm/dd (suitable for sorting, and so on.)
  5314.  
  5315. Sorted         Returns date in the format: yyyymmdd (suitable for sorting, and so on.)
  5316.  
  5317. Usa            Returns date in the format: mm/dd/yy
  5318.  
  5319. Weekday        Returns the English name for the day of the week, in mixed case. For
  5320.                 example, Tuesday.
  5321.  
  5322. Here are some examples:
  5323.  
  5324. DATE( )        ->    '27 Aug 1988'  /*  perhaps  */
  5325. DATE('B')      ->    725975
  5326. DATE('D')      ->    240
  5327. DATE('E')      ->    '27/08/88'
  5328. DATE('L')      ->    '27 August 1988'
  5329. DATE('M')      ->    'August'
  5330. DATE('N')      ->    '27 Aug 1988'
  5331. DATE('O')      ->    '88/08/27'
  5332. DATE('S')      ->    '19880827'
  5333. DATE('U')      ->    '08/27/88'
  5334. DATE('W')      ->    'Saturday'
  5335.  
  5336. Note:    The first call to DATE or TIME in one expression causes a time stamp to be
  5337.          made which is then used for all calls to these functions in that expression.
  5338.          Therefore, if multiple calls to any of the DATE and/or TIME functions are made
  5339.          in a single expression, they are guaranteed to be consistent with each other.
  5340.  
  5341. =======================================================================================
  5342. 10.22  DELSTR (Delete String)
  5343.  
  5344.    >>───DELSTR(string,n ─┬───────────┬─)──────><
  5345.                          └──,length──┘
  5346.  
  5347. DELSTR deletes the substring of string that begins at the nth character, and is of
  5348. length length. If length is not specified, the rest of string is deleted. If n is
  5349. greater than the length of string, the string is returned unchanged. n must be a
  5350. positive whole number.
  5351.  
  5352. Here are some examples:
  5353.  
  5354. DELSTR('abcd',3)       ->    'ab'
  5355. DELSTR('abcde',3,2)    ->    'abe'
  5356. DELSTR('abcde',6)      ->    'abcde'
  5357.  
  5358. =======================================================================================
  5359. 10.23  DELWORD
  5360.  
  5361.    >>───DELWORD(string,n ─┬───────────┬─)──────><
  5362.                           └──,length──┘
  5363.  
  5364. DELWORD deletes the substring of string that starts at the n th word. The length option
  5365. refers to the number of blank-delimited words. If length is omitted, it defaults to be
  5366. the remaining words in string. n must be a positive whole number. If n is greater than
  5367. the number of words in string, string is returned unchanged. The string deleted
  5368. includes any blanks following the final word involved.
  5369.  
  5370. Here are some examples:
  5371.  
  5372. DELWORD('Now is the  time',2,2)  ->  'Now time'
  5373. DELWORD('Now is the time ',3)    ->  'Now is '
  5374. DELWORD('Now is the  time',5)    ->  'Now is the  time'
  5375.  
  5376. =======================================================================================
  5377. 10.24  DIGITS
  5378.  
  5379.    >>──DIGITS()─────────────><
  5380.  
  5381. DIGITS returns the current setting of NUMERIC DIGITS.
  5382.  
  5383. Here is an example:
  5384.  
  5385. DIGITS()    ->    9      /* by default */
  5386.  
  5387. =======================================================================================
  5388. 10.25  D2C (Decimal to Character)
  5389.  
  5390.    >>───D2C(wholenumber ─┬─────┬─)──────><
  5391.                          └─,n──┘
  5392.  
  5393. D2C returns a character string that is the ASCII representation of the decimal number.
  5394. If you specify n, it is the length of the final result in characters and leading blanks
  5395. are added to the output character.
  5396.  
  5397. If n is not specified, wholenumber must be a nonnegative number and the resulting
  5398. length is as needed; therefore, the returned result has no leading 00x characters.
  5399.  
  5400. Here are some examples:
  5401.  
  5402. D2C(65)      ->   'A'      /* '41'x is an ASCII 'A'    */
  5403. D2C(65,1)    ->   'A'
  5404. D2C(65,2)    ->   ' A'
  5405. D2C(65,5)    ->   '    A'
  5406. D2C(109)     ->   'm'      /* '6D'x  is an ASCII 'm'   */
  5407. D2C(-109,1)  ->   'ô'      /* '147'x is an ASCII 'ô'   */
  5408. D2C(76,2)    ->   ' L'     /* '76'x  is an ASCII ' L'  */
  5409. D2C(-180,2)  ->   ' L'
  5410.  
  5411. =======================================================================================
  5412. 10.26  D2X (Decimal to Hexadecimal)
  5413.  
  5414.    >>───D2X(wholenumber ─┬─────┬─)──────><
  5415.                          └─,n──┘
  5416.  
  5417. D2X returns a string of hexadecimal characters that is the hexadecimal representation
  5418. of the decimal number.
  5419.  
  5420. If n is not specified, wholenumber must be a nonnegative number and the returned
  5421. result has no leading 0 characters.
  5422.  
  5423. If n is specified, it is the length of the final result in characters; that is, after
  5424. conversion the input string is sign-extended to the required length. If the number is
  5425. too big to fit into n characters, it is shortened on the left.
  5426.  
  5427. Here are some examples:
  5428.  
  5429. D2X(9)         ->    '9'
  5430. D2X(129)       ->    '81'
  5431. D2X(129,1)     ->    '1'
  5432. D2X(129,2)     ->    '81'
  5433. D2X(129,4)     ->    '0081'
  5434. D2X(257,2)     ->    '01'
  5435. D2X(-127,2)    ->    '81'
  5436. D2X(-127,4)    ->    'FF81'
  5437. D2X(12,0)      ->    ''
  5438.  
  5439. Implementation maximum: The output string cannot have more than 250 significant
  5440. hexadecimal characters, though a longer result is possible if it has additional leading
  5441. sign characters (0 and F).
  5442.  
  5443. =======================================================================================
  5444. 10.27  DIRECTORY
  5445.  
  5446.    >>──DIRECTORY(──┬──────────────┬─)─────────><
  5447.                    └─newdirectory─┘
  5448.  
  5449. DIRECTORY returns the current directory, first changing it to newdirectory if an
  5450. argument is supplied and the named directory exists.
  5451.  
  5452. The return string includes a drive letter prefix as the first two characters of the
  5453. directory name. Specifying a drive letter prefix as part of newdirectory causes the
  5454. specified drive to become the current drive. If a drive letter is not specified, then
  5455. the current drive remains unchanged.
  5456.  
  5457. For example, the following program fragment saves the current directory and switches to
  5458. a new directory; it performs an operation there, and then returns to the former
  5459. directory.
  5460.  
  5461. /* get current directory */
  5462. curdir = directory()
  5463. /* go play a game */
  5464. newdir = directory("d:/usr/games")
  5465. if newdir = "d:/usr/games" then
  5466.    do
  5467.    fortune  /* tell a fortune */
  5468. /* return to former directory */
  5469.    call directory curdir
  5470.    end
  5471. else
  5472.    say 'Can't find /usr/games'
  5473.  
  5474. =======================================================================================
  5475. 10.28  ERRORTEXT
  5476.  
  5477.    >>───ERRORTEXT(n)──────><
  5478.  
  5479. ERRORTEXT returns the error message associated with error number n. n must be in
  5480. the range 0-99, and any other value is an error. If n is in the allowed range, but is
  5481. not a defined REXX error number, the null string is returned.
  5482.  
  5483. Here are some examples:
  5484.  
  5485. ERRORTEXT(16)    ->    'Label not found'
  5486. ERRORTEXT(60)    ->    ''
  5487.  
  5488. =======================================================================================
  5489. 10.29  ENDLOCAL
  5490.  
  5491.    >>─ENDLOCAL()─────────────><
  5492.  
  5493. ENDLOCAL restores the drive directory and environment variables in effect before the
  5494. last SETLOCAL function was executed. If ENDLOCAL is not included in a procedure, then
  5495. the initial environment saved by SETLOCAL will be restored upon exiting the procedure.
  5496.  
  5497. ENDLOCAL returns a value of 1 if the initial environment is successfully restored, and
  5498. a value of 0 if no SETLOCAL has been issued or if the actions is otherwise
  5499. unsuccessful.
  5500.  
  5501. Note:    Unlike their counterparts in the OS/2 Batch language (the Setlocal and
  5502.           Endlocal statements), the REXX SETLOCAL and ENDLOCAL functions can be nested.
  5503.  
  5504. Here is an example:
  5505.  
  5506. n = SETLOCAL()          /* saves the current environment    */
  5507.  
  5508.          /* The program can now change environment   */
  5509.          /* variables (with the VALUE function) and  */
  5510.          /* then work in that changed envirnonment.  */
  5511.  
  5512. n = ENDLOCAL()          /* restores the initial environment */
  5513.  
  5514. For additional examples, view the SETLOCAL function.
  5515.  
  5516. =======================================================================================
  5517. 10.30  FILESPEC
  5518.  
  5519.    >>──FILESPEC(option,filespec)──────><
  5520.  
  5521. FILESPEC returns a selected element of filespec, a given file specification, identified
  5522. by one of the following strings for option:
  5523.  
  5524. Drive      The drive letter of the given filespec.
  5525.  
  5526. Path       The directory path of the given filespec.
  5527.  
  5528. Name       The filename of the given filespec.
  5529.  
  5530. If the requested string is not found, then FILESPEC returns a null string (" ").
  5531.  
  5532. Note:    Only the the initial letter of option is needed.
  5533.  
  5534.          Here are some examples:
  5535.  
  5536.          thisfile = "C:\OS2\UTIL\EXAMPLE.EXE"
  5537.          say FILESPEC("drive",thisfile)     /* says "C:"          */
  5538.          say FILESPEC("path",thisfile)      /* says "\OS2\UTIL\"  */
  5539.          say FILESPEC("name",thisfile)      /* says "EXAMPLE.EXE" */
  5540.  
  5541.          part = "name"
  5542.          say FILESPEC(part,thisfile)        /* says "EXAMPLE.EXE" */
  5543.  
  5544. =======================================================================================
  5545. 10.31  FORM
  5546.  
  5547.    >>──FORM()─────────────><
  5548. FORM returns the current setting of NUMERIC FORM.
  5549.  
  5550. Here is an example:
  5551.  
  5552. FORM()    ->    'SCIENTIFIC'  /* by default */
  5553.  
  5554. =======================================================================================
  5555. 10.32  FORMAT
  5556.  
  5557.    >>──FORMAT(number─┬───────────────────────────────────────────┬─)──><
  5558.                      └─,─┬──────┬─┬─────────────────────────────┬┘
  5559.                          └before┘ └,─┬─────┬─┬─────────────────┬┘
  5560.                                      └after┘ └─,─┬────┬─┬─────┬┘
  5561.                                                  └expp┘ └,expt┘
  5562.  
  5563. FORMAT returns number rounded and formatted.
  5564.  
  5565. The number is first rounded and formatted to standard REXX rules, just as though the
  5566. operation number+0 had been carried out. If only number is given, the result is
  5567. precisely that of this operation. If any other options are specified, the number is
  5568. formatted as follows.
  5569.  
  5570. The before and after options describe how many characters are to be used for the
  5571. integer part and decimal part of the result respectively. If either or both of these
  5572. are omitted, the number of characters used for that part is as needed.
  5573.  
  5574. If before is not large enough to contain the integer part of the number, an error
  5575. results. If before is too large, the number is padded on the left with blanks. If after
  5576. is not the same size as the decimal part of the number, the number will be rounded (or
  5577. extended with zeros) to fit. Specifying 0 will cause the number to be rounded to an
  5578. integer.
  5579.  
  5580. Here are some examples:
  5581.  
  5582. FORMAT('3',4)            ->    '   3'
  5583. FORMAT('1.73',4,0)       ->    '   2'
  5584. FORMAT('1.73',4,3)       ->    '   1.730'
  5585. FORMAT('-.76',4,1)       ->    '  -0.8'
  5586. FORMAT('3.03',4)         ->    '   3.03'
  5587. FORMAT(' - 12.73',,4)    ->    '-12.7300'
  5588. FORMAT(' - 12.73')       ->    '-12.73'
  5589. FORMAT('0.000')          ->    '0'
  5590.  
  5591. The first three arguments are as previously described.  In addition, expp and expt
  5592. control the exponent part of the result: expp sets the number of places to be used for
  5593. the exponent part; the default is to use as many as needed. The expt sets the trigger
  5594. point for use of exponential notation. If the number of places needed for the integer
  5595. part exceeds expt, exponential notation is used. Likewise, exponential notation is used
  5596. if the number of places needed for the decimal part exceeds twice expt. The default is
  5597. the current setting of NUMERIC DIGITS. If 0 is specified for expt, exponential notation
  5598. is always used unless the exponent would be 0. The expp must be less than 10, but there
  5599. is no limit on the other arguments. If 0 is specified for the expp field, no exponent
  5600. is supplied, and the number is expressed in simple form with added zeros as necessary
  5601. (this overrides a 0 value of expt). Otherwise, if expp is not large enough to contain
  5602. the exponent, an error results. If the exponent is 0, in this case (a non-zero expp),
  5603. then expp+2 blanks are supplied for the exponent part of the result.
  5604.  
  5605. Here are some examples:
  5606.  
  5607. FORMAT('12345.73',,,2,2)    ->    '1.234573E+04'
  5608. FORMAT('12345.73',,3,,0)    ->    '1.235E+4'
  5609. FORMAT('1.234573',,3,,0)    ->    '1.235'
  5610. FORMAT('12345.73',,,3,6)    ->    '12345.73'
  5611. FORMAT('1234567e5',,3,0)    ->    '123456700000.000'
  5612.  
  5613. =======================================================================================
  5614. 10.33  FUZZ
  5615.  
  5616.    >>──FUZZ()─────────────><
  5617.  
  5618. FUZZ returns the current setting of NUMERIC FUZZ.
  5619.  
  5620. Here is an example:
  5621.  
  5622. FUZZ()    ->    0     /* by default */
  5623.  
  5624. =======================================================================================
  5625. 10.34  INSERT
  5626.  
  5627.    >>──INSERT(new,target─┬─────────────────────────────┬─)─────><
  5628.                          └─,─┬───┬─┬──────────────────┬┘
  5629.                              └─n─┘ └─,─┬──────┬─┬────┬┘
  5630.                                        └length┘ └,pad┘
  5631.  
  5632. INSERT inserts the string new, padded to length length, into the string target after
  5633. the n th character. If specified, n must be a nonnegative whole number. If n is greater than the length of the target string, padding is added there also. The default pad
  5634. character is a blank. The default value for n is 0, which means insert before the
  5635. beginning of the string.
  5636.  
  5637. Here are some examples:
  5638.  
  5639. INSERT(' ','abcdef',3)         ->    'abc def'
  5640. INSERT('123','abc',5,6)        ->    'abc  123   '
  5641. INSERT('123','abc',5,6,'+')    ->    'abc++123+++'
  5642. INSERT('123','abc')            ->    '123abc'
  5643. INSERT('123','abc',,5,'-')     ->    '123--abc'
  5644.  
  5645. =======================================================================================
  5646. 10.35  LASTPOS
  5647.  
  5648.    >>──LASTPOS(needle,haystack──┬─────────┬─)─────><
  5649.                                 └─,start──┘
  5650.  
  5651. LASTPOS returns the position of the last occurrence of one string, needle, in another,
  5652. haystack. If the string needle is not found, 0 is returned. By default the search
  5653. starts at the last character of haystack (that is, start=LENGTH(string)) and scans
  5654. backwards. You can override this by specifying start, as the point at which the
  5655. backward scan starts. start must be a positive whole number, and defaults to
  5656. LENGTH(string) if larger than that value.
  5657.  
  5658. Here are some examples:
  5659.  
  5660. LASTPOS(' ','abc def ghi')      ->    8
  5661. LASTPOS(' ','abcdefghi')        ->    0
  5662. LASTPOS(' ','abc def ghi',7)    ->    4
  5663.  
  5664. =======================================================================================
  5665. 10.36  LEFT
  5666.  
  5667.    >>──LEFT(string,length──┬───────┬─)───────><
  5668.                            └─,pad──┘
  5669.  
  5670. LEFT returns a string of length length, containing the leftmost length characters of
  5671. string. The string returned is padded with pad characters (or truncated) on the right
  5672. as needed. The default pad character is a blank. length must be nonnegative. The LEFT
  5673. function is exactly equivalent to SUBSTR(string,1,length[,pad]).
  5674.  
  5675. Here are some examples:
  5676.  
  5677. LEFT('abc d',8)        ->    'abc d   '
  5678. LEFT('abc d',8,'.')    ->    'abc d...'
  5679. LEFT('abc  def',7)     ->    'abc  de'
  5680.  
  5681. =======================================================================================
  5682. 10.37  LENGTH
  5683.  
  5684.    >>──LENGTH(string)─────────────><
  5685.  
  5686. LENGTH returns the length of string.
  5687.  
  5688. Here are some examples:
  5689.  
  5690. LENGTH('abcdefgh')    ->    8
  5691. LENGTH('abc defg')    ->    8
  5692. LENGTH('')            ->    0 =======================================================================================
  5693. 10.38  LINEIN
  5694.  
  5695.    >>──LINEIN(─┬──────┬──┬────────────────────────┬─)─────><
  5696.                └─name─┘  └─,─┬──────┬──┬────────┬─┘
  5697.                              └─line─┘  └─,count─┘
  5698.  
  5699. LINEIN returns count (0 or 1) lines read from the character input stream name. The form
  5700. of the name is implementation dependent. If name is omitted, the line is read from the
  5701. default input stream, STDIN: in OS/2. The default count is 1.
  5702.  
  5703. For persistent streams, a read position is maintained for each stream. In the OS/2
  5704. operating system, this is the same as the write position. Any read from the stream
  5705. starts at the current read position by default. A call to LINEIN will return a partial
  5706. line if the current read position is not at the start of a line. When the read is
  5707. completed, the read position is moved to the beginning of the next line. The read
  5708. position may be set to the beginning of the stream by giving line a value of 1- the
  5709. only valid value for line in OS/2.
  5710.  
  5711. If a count of 0 is given, then no characters are read and the null string is returned.
  5712.  
  5713. For transient streams, if a complete line is not available in the stream, then
  5714. execution of the program will normally stop until the line is complete. If, however, it
  5715. is impossible for a line to be completed due to an error or other problem, the NOTREADY
  5716. condition is raised and LINEIN returns whatever characters are available.
  5717.  
  5718. Here are some examples:
  5719.  
  5720. LINEIN()                      /* Reads one line from the    */
  5721.                               /* default input stream;      */
  5722.                               /* normally this is an entry  */
  5723.                               /* typed at the keyboard      */
  5724.  
  5725. myfile = 'ANYFILE.TXT'
  5726. LINEIN(myfile)     -> 'Current line' /* Reads one line from  */
  5727.                              /* ANYFILE.TXT, beginning     */
  5728.                              /* at the current read        */
  5729.                              /* position. (If first call,  */
  5730.                              /* file is opened and the     */
  5731.                              /* first line is read.)       */
  5732.  
  5733. LINEIN(myfile,1,1) ->'first line'  /* Opens and reads the first */
  5734.                              /* line of ANYFILE.TXT (if    */
  5735.                              /* the file is already open,  */
  5736.                              /* reads first line); sets    */
  5737.                              /* read position on the       */
  5738.                              /* second line.               */
  5739.  
  5740. LINEIN(myfile,1,0) ->  ''    /* No read; opens ANYFILE.TXT */
  5741.                               /* (if file is already open,  */
  5742.                               /* sets the read position to  */
  5743.                               /* the first line).           */
  5744.  
  5745. LINEIN(myfile,,0)  ->  ''  /* No read; opens ANYFILE.TXT */
  5746.                               /* (no action if the file is  */
  5747.                               /* already open).             */
  5748.  
  5749. LINEIN("QUEUE:") -> 'Queue line' /* Read a line from the queue; */
  5750.                               /* If the queue is empty, the  */
  5751.                               /* program waits until a line  */
  5752.                               /* is put on the queue.        */
  5753.  
  5754. Note:    If the intention is to complete lines from the default character stream, as
  5755.          in a simple dialogue with a user, use the PULL or PARSE PULL instructions
  5756.          instead for simplicity and for improved programmability.  The PARSE LINEIN
  5757.          instruction is also useful in certain cases.
  5758.  
  5759. =======================================================================================
  5760. 10.39  LINEOUT
  5761.  
  5762.    >>──LINEOUT(─┬──────┬──┬─────────────────────────┬─)─────><
  5763.                 └─name─┘  └─,─┬────────┬──┬───────┬─┘
  5764.                               └─string─┘  └─,line─┘
  5765.  
  5766. LINEOUT returns the count of lines remaining after attempting to write string to the
  5767. character output stream name. The count is either 0 (meaning the line was successfully
  5768. written) or 1 (meaning that an error occurred while writing the line). string can be
  5769. the null string, in which case only the action associated with completing a line is
  5770. taken. LINEOUT adds a line-feed and a carriage-return character to the end of string.
  5771.  
  5772. The form of the name is implementation dependent. If name is omitted, the line is
  5773. written to the default output stream, STDOUT: (normally the display) in OS/2.
  5774.  
  5775. For persistent streams, a write position is maintained for each stream. In the OS/2
  5776. operating system, this is the same as the read position. Any write to the stream starts
  5777. at the current write position by default. Characters written by a call to LINEOUT can
  5778. be added to a partial line. LINEOUT conceptually terminates a line at the end of each
  5779. call. When the write is completed, the write position is set to the beginning of the
  5780. line following the one just written. The initial write position is the end of the
  5781. stream, so that calls to LINEOUT normally append lines to the end of the stream.
  5782.  
  5783. You can set the write position to the first character of a persistent stream by giving
  5784. a value of 1 (the only valid value) for line.
  5785.  
  5786. Note:    In some environments, overwriting a stream using CHAROUT or LINEOUT can
  5787.          erase (destroy) all existing data in the stream. This is not, however, the
  5788.          case in the OS/2 environment.
  5789.  
  5790. You can omit the string for persistent streams. If you specify line, the write position
  5791. is set to the beginning of the stream, but nothing is written to the stream, and 0 is
  5792. returned.  If you specify neither line nor string, the write position is set to the end
  5793. of the stream. This use of LINEOUT has the effect of closing the stream in environments
  5794. (such as the OS/2 environment) that support this concept.
  5795.  
  5796. Execution of the program normally stops until the output operation is effectively
  5797. completed. If, however, it is impossible for a line to be written, the NOTREADY
  5798. condition is raised and LINEOUT returns with a result of 1 (that is, the residual count
  5799. of lines written).
  5800.  
  5801. Here are some examples:
  5802.  
  5803. LINEOUT(,'Display this')    /* Writes string to the default   */
  5804.                             /* output stream (normally, the   */
  5805.                             /* display); returns 0 if         */
  5806.                             /* successful                     */
  5807.  
  5808. myfile = 'ANYFILE.TXT'
  5809.  
  5810. LINEOUT(myfile,'A new line')  /* Opens the file ANYFILE.TXT and */
  5811.                               /* appends the string to the end. */
  5812.                               /* If the file is already open,   */
  5813.                               /* the string is written at the   */
  5814.                               /* current write position.        */
  5815.                               /* Returns 0 if successful.       */
  5816.  
  5817. LINEOUT(myfile,'A new start',1)/* Opens the file (if not already */
  5818.                                /* open); overwrites first line   */
  5819.                                /* with a new line.               */
  5820.                                /* Returns 0 if successful.       */
  5821.  
  5822. LINEOUT(myfile,,1)            /* Opens the file (if not already */
  5823.                               /* open). No write; sets write    */
  5824.                               /* position at first character.   */
  5825.  
  5826. LINEOUT(myfile)               /* Closes ANYFILE.TXT             */
  5827.  
  5828. LINEOUT is often most useful when called as a subroutine. The return value is then
  5829. available in the variable RESULT. For example:
  5830.  
  5831. Call LINEOUT 'A:rexx.bat','Shell',1
  5832. Call LINEOUT ,'Hello'
  5833.  
  5834. Note:    If the lines are to be written to the default output stream without the
  5835.           possibility of error, use the SAY instruction instead.
  5836.  
  5837. =======================================================================================
  5838. 10.40  LINES
  5839.  
  5840.    >>──LINES(─┬──────┬──)─────><
  5841.               └─name─┘
  5842.  
  5843. LINES returns 1 if any data remains between the current read position and the end of
  5844. the character input stream name, and returns 0 if no data remains. In effect, LINES
  5845. reports whether a read action performed by CHARIN or LINEIN will succeed.
  5846.  
  5847. The form of the name is implementation dependent. If you omit name, then the presence
  5848. or absence of data in the default input stream (STDIN:) is returned. For OS/2 devices,
  5849. LINES always returns 1.
  5850.  
  5851. Here are some examples:
  5852.  
  5853. LINES(myfile)    ->    0    /* at end of the file   */
  5854.  
  5855. LINES()          ->    1    /* data remains in the  */
  5856.                             /* default input stream */
  5857.                             /* STDIN:         */
  5858.  
  5859. LINES("COM1:")   ->    1     /* An OS/2 device name  */
  5860.                             /* always returns '1'   */
  5861.  
  5862. Note:    The CHARS function returns the number of characters in a persistent stream or
  5863.          the presence of data in a transient stream.
  5864.  
  5865. =======================================================================================
  5866. 10.41  MAX
  5867.  
  5868.    >>──MAX(number─┬───────────┬─)───────><
  5869.                   │┌─────────┐│
  5870.                   │V         ││
  5871.                   └┴─,number─┴┘
  5872.  
  5873. MAX returns the largest number from the list specified, formatted according to the
  5874. current setting of NUMERIC DIGITS. You can specify up to 20 numbers and can nest
  5875. calls to MAX if more arguments are needed.
  5876.  
  5877. Here are some examples:
  5878.  
  5879. MAX(12,6,7,9)                              ->    12
  5880. MAX(17.3,19,17.03)                         ->    19
  5881. MAX(-7,-3,-4.3)                            ->    -3
  5882. MAX(1,2,3,4,5,6,7,8,9,MAX(10,11,12,13))    ->    13
  5883.  
  5884. =======================================================================================
  5885. 10.42  MIN
  5886.  
  5887.    >>──MIN(number─┬───────────┬─)───────><
  5888.                   │┌─────────┐│
  5889.                   │V         ││
  5890.                   └┴─,number─┴┘
  5891.  
  5892. MIN returns the smallest number from the list specified, formatted according to the
  5893. current setting of NUMERIC DIGITS. Up to 20 numbers can be specified, although calls
  5894. to MIN can be nested if more arguments are needed.
  5895.  
  5896. Here are some examples:
  5897.  
  5898. MIN(12,6,7,9)         ->     6
  5899. MIN(17.3,19,17.03)    ->    17.03
  5900. MIN(-7,-3,-4.3)       ->    -7
  5901.  
  5902. =======================================================================================
  5903. 10.43  OVERLAY
  5904.  
  5905.    >>──OVERLAY(new,target ─┬─────────────────────────────┬─)──><
  5906.                            └─,─┬───┬─┬──────────────────┬┘
  5907.                                └─n─┘ └─,─┬──────┬─┬────┬┘
  5908.                                          └length┘ └,pad┘
  5909.  
  5910. OVERLAY returns the string target, which, starting at the nth character, is overlaid
  5911. with the string new, padded or truncated to length length. If length is specified, it
  5912. must be positive or zero. If n is greater than the length of the target string, padding
  5913. is added before the new string. The default pad character is a blank, and the default
  5914. value for n is 1. If you specify n, it must be a positive whole number.
  5915.  
  5916. Here are some examples:
  5917.  
  5918. OVERLAY(' ','abcdef',3)         ->    'ab def'
  5919. OVERLAY('.','abcdef',3,2)       ->    'ab. ef'
  5920. OVERLAY('qq','abcd')            ->    'qqcd'
  5921. OVERLAY('qq','abcd',4)          ->    'abcqq'
  5922. OVERLAY('123','abc',5,6,'+')    ->    'abc+123+++'
  5923.  
  5924. =======================================================================================
  5925. 10.44  POS
  5926.  
  5927.    >>──POS(needle,haystack──┬─────────┬─)─────><
  5928.                             └─,start──┘
  5929.  
  5930. POS returns the position of one string, needle, in another, haystack. (See also the
  5931. LASTPOS function.) If the string needle is not found, 0 is returned. By default, the
  5932. search starts at the first character of haystack (that is, the value of start is 1).
  5933. You can override this by specifying start (which must be a positive whole number) as
  5934. the point at which the search starts.
  5935.  
  5936. Here are some examples:
  5937.  
  5938. POS('day','Saturday')       ->    6
  5939. POS('x','abc def ghi')      ->    0
  5940. POS(' ','abc def ghi')      ->    4
  5941. POS(' ','abc def ghi',5)    ->    8
  5942.  
  5943. =======================================================================================
  5944. 10.45  QUEUED
  5945.  
  5946.    >>──QUEUED()───────────────><
  5947.  
  5948. QUEUED returns the number of lines remaining in the currently active REXX data queue
  5949. at the time the function is invoked.
  5950.  
  5951. Here is an example:
  5952.  
  5953. QUEUED()    ->    5    /* Perhaps */
  5954.  
  5955. =======================================================================================
  5956. 10.46  RANDOM
  5957.  
  5958.    >>──RANDOM(─┬──────────────────────────┬─)────><
  5959.                ├─max──────────────────────┤
  5960.                ├─min,─┬─┬─────┬─┬───────┬─┘
  5961.                └─,────┘ └─max─┘ └─,seed─┘
  5962.  
  5963. RANDOM returns a quasi-random, nonnegative whole number in the range min to max
  5964. inclusive. If only one argument is specified, the range will be from 0 to that number.
  5965. Otherwise, the default values for min and max are 0 and 999, respectively. A specific
  5966. seed (which must be a whole number) for the random number can be specified as the
  5967. third argument if repeatable results are desired.
  5968.  
  5969. The magnitude of the range (that is, max minus min) must not exceed 100000.
  5970.  
  5971. Here are some examples:
  5972.  
  5973. RANDOM()          ->    305
  5974. RANDOM(5,8)       ->      7
  5975. RANDOM(,,1983)    ->    123  /* reproducible */
  5976. RANDOM(2)         ->      0
  5977.  
  5978. Notes:
  5979.  
  5980.  1. To obtain a predictable sequence of quasi-random numbers, use RANDOM a number
  5981.     of times, but specify a seed only the first time. For example, to simulate 40
  5982.     throws of a six-sided, unbiased die, use:
  5983.     sequence = RANDOM(1,6,12345)  /* any number would */
  5984.                                   /* do for a seed    */
  5985.     do 39
  5986.        sequence = sequence RANDOM(1,6)
  5987.        end
  5988.     say sequence
  5989.  
  5990.     The numbers are generated mathematically, using the initial seed, so that as far as
  5991.     possible they appear to be random. Running the program again will produce the
  5992.     same sequence; using a different initial seed almost certainly produces a different
  5993.     sequence.
  5994.  2. The random number generator is global for an entire program; the current seed is
  5995.     not saved across internal routine calls.
  5996.  3. The actual random number generator used may differ from implementation to
  5997.     implementation.
  5998.  
  5999. =======================================================================================
  6000. 10.47  REVERSE
  6001.  
  6002.    >>──REVERSE(string)────────────><
  6003.  
  6004. REVERSE returns string, swapped end for end.
  6005.  
  6006. Here are some examples:
  6007.  
  6008. REVERSE('ABc.')    ->    '.cBA'
  6009. REVERSE('XYZ ')    ->    ' ZYX'
  6010.  
  6011. =======================================================================================
  6012. 10.48  RIGHT
  6013.  
  6014.    >>──RIGHT(string,length──┬───────┬─)───────><
  6015.                             └─,pad──┘
  6016.  
  6017. RIGHT returns a string of length length containing the rightmost length characters of
  6018. string. The string returned is padded with pad characters (or truncated) on the left as
  6019. needed. The default pad character is a blank. length must be nonnegative.
  6020.  
  6021. Here are some examples:
  6022.  
  6023. RIGHT('abc  d',8)     ->    '  abc  d'
  6024. RIGHT('abc def',5)    ->    'c def'
  6025. RIGHT('12',5,'0')     ->    '00012'
  6026.  
  6027. =======================================================================================
  6028. 10.49  SETLOCAL
  6029.  
  6030.   >>──SETLOCAL()────────><
  6031.  
  6032. SETLOCAL saves the current working drive and directory, and the current values of the
  6033. OS/2 environment variables that are local to the current process.
  6034.  
  6035. For example, SETLOCAL can be used to save the current environment before changing
  6036. selected settings with the VALUE function. To restore the drive, directory, and
  6037. environment, use the ENDLOCAL function.
  6038.  
  6039. SETLOCAL returns a value of 1 if the initial drive, directory, and environment are
  6040. successfully saved, and a value of 0 if unsuccessful. If SETLOCAL is not followed by an
  6041. ENDLOCAL function in a procedure, then the initial environment saved by SETLOCAL will
  6042. be restored upon exiting the procedure. Here is an example:
  6043.  
  6044. /* current path is 'C:\PROJ\FILES' */
  6045. n = SETLOCAL()        /* saves all environment settings    */
  6046.  
  6047. /* Now use the VALUE function to change the PATH variable. */
  6048. p = VALUE('Path','C:\PROC\PROGRAMS'.'OS2ENVIRONMENT')
  6049.  
  6050. /* Programs in directory C:\PROC\PROGRAMS may now be run   */
  6051.  
  6052. n = ENDLOCAL()  /* restores initial environment (including */
  6053.                 /* the changed PATH variable, which is   */
  6054.                 /* once again 'C:\PROJ\FILES'              */
  6055.  
  6056. Note:    Unlike their counterparts in the OS/2 Batch language (the Setlocal and
  6057.           Endlocal statements), the REXX SETLOCAL and ENDLOCAL functions can be nested.
  6058.  
  6059. =======================================================================================
  6060. 10.50  SIGN
  6061.  
  6062.    >>──SIGN(number)───────────────><
  6063.  
  6064. SIGN returns a number that indicates the sign of number. number is first rounded
  6065. according to standard REXX rules, just as though the operation number+0 had been
  6066. carried out. If number is less than 0, then -1 is returned; if it is 0 then 0 is
  6067. returned; and if it is greater than 0, 1 is returned.
  6068.  
  6069. Here are some examples:
  6070.  
  6071. SIGN('12.3')       ->     1
  6072. SIGN(' -0.307')    ->    -1
  6073. SIGN(0.0)          ->     0
  6074.  
  6075. =======================================================================================
  6076. 10.51  SOURCELINE
  6077.  
  6078.    >>──SOURCELINE(─┬─────┬─)──────><
  6079.                    └──n──┘
  6080.  
  6081. SOURCELINE returns the line number of the final line in the source file if you omit n,
  6082. or returns the n th line in the source file if you specify n.
  6083.  
  6084. If specified, n must be a positive whole number, and must not exceed the number of the
  6085. final line in the source file.
  6086.  
  6087. Here are some examples:
  6088.  
  6089. SOURCELINE()    ->   10
  6090. SOURCELINE(1)   ->   '/* This is a 10-line program */'
  6091.  
  6092. =======================================================================================
  6093. 10.52  SPACE
  6094.  
  6095.    >>──SPACE(string─┬─────────────────────┬─)──────><
  6096.                     └─,──┬───┬─┬────────┬─┘
  6097.                          └─n─┘ └──,pad──┘
  6098.  
  6099. SPACE formats the blank-delimited words in string with n pad characters between each
  6100. word. The n must be nonnegative. If it is 0, all blanks are removed. Leading and
  6101. trailing blanks are always removed. The default for n is 1, and the default pad
  6102. character is a blank.
  6103.  
  6104. Here are some examples:
  6105.  
  6106. SPACE('abc  def  ')          ->    'abc def'
  6107. SPACE('  abc def',3)         ->    'abc   def'
  6108. SPACE('abc  def  ',1)        ->    'abc def'
  6109. SPACE('abc  def  ',0)        ->    'abcdef'
  6110. SPACE('abc  def  ',2,'+')    ->    'abc++def'
  6111.  
  6112. =======================================================================================
  6113. 10.53  STREAM
  6114.  
  6115.    >>───STREAM(name──┬──────────────────────────┬─)────><
  6116.                      └──,───┬───────────────────┤
  6117.                             ├─C,──streamcommand─┤
  6118.                             ├─D─────────────────┤
  6119.                             └─S─────────────────┘
  6120.  
  6121. STREAM returns a string describing the state of, or the result of an operation upon,
  6122. the character stream name. This function is used to request information on the state of
  6123. an input or output stream, or to carry out some specific operation on the stream.
  6124.  
  6125. The first argument, name, specifies the stream to be accessed. The second argument
  6126. can be one of the following strings (of which only the first letter is needed) which
  6127. describes the action to be carried out:
  6128.  
  6129. Command       an operation (specified by the streamcommand given as the third argument)
  6130.                to be applied to the selected input or output stream. The string that is
  6131.                returned depends on the command performed, and can be the null string.
  6132.  
  6133. Description   Also returns the current state of the specified stream. It is identical
  6134.                to the State operation, except that the returned string is followed by a
  6135.                colon and, if available, additional information about ERROR or NOTREADY
  6136.                states.
  6137.  
  6138. State         Returns a string that indicates the current state of the specified
  6139.                stream. This is the default operation.
  6140.  
  6141. When used with the State option, STREAM returns one of the following strings:
  6142.  
  6143. 'ERROR'              The stream has been subject to an erroneous operation (possibly
  6144.                       during input, output, or through the STREAM function. Additional
  6145.                       information about the error may be available by invoking the
  6146. STREAM
  6147.                       function with a request for the implementation-dependent
  6148.                        description.
  6149.  
  6150. 'NOTREADY'           The stream is known to be in a state such that normal input or
  6151.                       output operations attempted upon it would raise the NOTREADY
  6152.                       condition. For example, a simple input stream may have a defined
  6153.                       length; an attempt to read that stream (with the CHARIN or LINEIN
  6154.                       built-in functions, perhaps) beyond that limit may make the
  6155. stream
  6156.                       unavailable until the stream has been closed, for example, with
  6157.                       LINEIN(name), and then reopened.
  6158.  
  6159. 'READY'              The stream is known to be in a state such that normal input or
  6160.                       output operations can be attempted.  This is the usual state for
  6161.                       a stream, though it does not guarantee that any particular
  6162.                       operation will succeed.
  6163.  
  6164. 'UNKNOWN'            The state of the stream is unknown. In OS/2 implementations, this
  6165.                       generally means that the stream is closed (or has not yet been
  6166.                       opened). However, this response can be used in other environments
  6167.                       to indicate that the state of the stream cannot be determined.
  6168.  
  6169. Note:    The state (and operation) of an input or output stream is global to a REXX
  6170.          program, in that it is not saved and restored across function and subroutine
  6171.          calls (including those caused by a CALL ON condition trap).
  6172.  
  6173. Stream Commands
  6174.  
  6175. The following stream commands are used to:
  6176.  
  6177.   Open a stream for reading or writing
  6178.   Close a stream at the end of an operation
  6179.   Position the read or write position within a persistent stream (for example, a file)
  6180.   Get information about a stream (its existence, size, and last edit date).
  6181.  
  6182. The streamcommand argument must be used when you select the operation C
  6183. (command). The syntax is:
  6184.  
  6185.    >>──STREAM(name,'C',streamcommand)────>
  6186.  
  6187. In this form, the STREAM function itself returns a string corresponding to the given
  6188. streamcommand if the command is successful. If the command is unsuccessful,
  6189. STREAM returns an error message string in the same form as that supplied by the D
  6190. (Description) operation.
  6191.  
  6192. Command strings - The argument streamcommand can be any expression that REXX
  6193. evaluates as one of the following command strings:
  6194.  
  6195. 'OPEN'             Opens the named stream. The default for 'OPEN' is to open the stream
  6196.                     for both reading and writing data. To specify whether name is only
  6197. to
  6198.                     be read or only to be written to, add the word READ or WRITE to the
  6199.                     command string.
  6200.  
  6201.                     The STREAM function itself returns 'READY' if the named stream is
  6202.                     successfully opened or an appropriate error message if             
  6203.        unsuccessful.
  6204.  
  6205.                     Examples:
  6206.  
  6207.                     stream(strout,'c','open')
  6208.                     stream(strout,'c','open write')
  6209.                     stream(strinp,'c','open read')
  6210.  
  6211. 'CLOSE'            Closes the named stream. The STREAM function itself returns 'READY'
  6212.                     if the named stream is successfully closed or an appropriate error
  6213.                     message otherwise. If an attempt is made to close an unopened file,
  6214.                     then STREAM() returns a null string ("").
  6215.  
  6216.                     Example:
  6217.  
  6218.                     stream('STRM.TXT','c','close') 'SEEK' offset      Sets the read or write position a given number (offset) within a
  6219.                     persistent stream.
  6220.  
  6221.                     Note:    In OS/2, the read and write positions are the same. To use
  6222.                              this command, the named stream must first be opened (with
  6223.                              the 'OPEN' stream command, described previously).
  6224.  
  6225.                     The offset number can be preceded by one of the following
  6226. characters:
  6227.  
  6228.    =   Explicitly specifies the offset from the beginning of the stream.  This is the
  6229.         default if no prefix is supplied.
  6230.  
  6231.    <   Specifies offset from the end of the stream.
  6232.  
  6233.    +   Specifies offset forward from the current read or write position.
  6234.  
  6235.    -   Specifies offset backward from the current read or write position.
  6236.  
  6237.                     The STREAM function itself returns the new position in the stream
  6238. if
  6239.                     the read or write position is successfully located; an appropriate
  6240. error
  6241.                     message is displayed otherwise.
  6242.  
  6243.                     Examples:
  6244.  
  6245.                     stream(name,'c','seek =2')
  6246.                     stream(name,'c','seek +15')
  6247.                     stream(name,'c','seek -7')
  6248.                     fromend  = 125
  6249.                     stream(name,'c','seek <'fromend)
  6250.  
  6251. Used with these stream commands, the STREAM function returns specific information
  6252. about a stream
  6253.  
  6254. 'QUERY EXISTS'     Returns the full path specification of the named stream, if it
  6255.                     exists, and a null string otherwise.
  6256.  
  6257.                     stream('..\file.txt','c','query exists')
  6258.  
  6259. 'QUERY SIZE'       Returns the size in bytes of a persistent stream.
  6260.  
  6261.                     stream('..\file.txt','c','query size')
  6262.  
  6263. 'QUERY DATETIME' Returns the date and time stamps of a stream.
  6264.  
  6265.                     stream('..\file.txt','c','query datetime')
  6266.  
  6267. =======================================================================================
  6268. 10.54  STRIP
  6269.  
  6270.    >>──STRIP(string─┬─────────────────────────┬─)──────><
  6271.                     └─,──┬────────┬─┬───────┬─┘
  6272.                          └─option─┘ └─,char─┘
  6273.  
  6274. STRIP removes leading and trailing characters from string based on the option you
  6275. specify. Valid options (of which only the capitalized letter is significant, all others
  6276. are ignored) are:
  6277. Both           Removes both leading and trailing characters from string. This is the
  6278.                 default.
  6279.  
  6280. Leading        Removes leading characters from string.
  6281.  
  6282. Trailing       Removes trailing characters from string.
  6283.  
  6284. The third argument, char, specifies the character to remove; The default is a blank. 
  6285. If you specify char, it must be exactly one character long.
  6286.  
  6287. Here are some examples:
  6288.  
  6289. STRIP('  ab c  ')        ->    'ab c'
  6290. STRIP('  ab c  ','L')    ->    'ab c  '
  6291. STRIP('  ab c  ','t')    ->    '  ab c'
  6292. STRIP('12.7000',,0)      ->    '12.7'
  6293. STRIP('0012.700',,0)     ->    '12.7'
  6294.  
  6295. =======================================================================================
  6296. 10.55  SUBSTR
  6297.  
  6298.    >>──SUBSTR(string,n ─┬───────────────────────┬─)─────><
  6299.                         └─,─┬────────┬─┬──────┬─┘
  6300.                             └─length─┘ └─,pad─┘
  6301.  
  6302. SUBSTR returns the substring of string that begins at the nth character, and is of
  6303. length length and padded with pad if necessary. n must be a positive whole number.
  6304.  
  6305. If length is omitted, the rest of the string will be returned.  The default pad
  6306. character is a blank.
  6307.  
  6308. Here are some examples:
  6309.  
  6310. SUBSTR('abc',2)          ->    'bc'
  6311. SUBSTR('abc',2,4)        ->    'bc  '
  6312. SUBSTR('abc',2,6,'.')    ->    'bc....'
  6313.  
  6314. Note:    In some situations the positional (numeric) patterns of parsing templates are
  6315.          more convenient for selecting substrings, especially if more than one
  6316.          substring is to be extracted from a string.
  6317.  
  6318. =======================================================================================
  6319. 10.56  SUBWORD
  6320.  
  6321.    >>──SUBWORD(string,n ─┬──────────┬─)─────><
  6322.                          └─,length──┘
  6323.  
  6324. SUBWORD returns the substring of string that starts at the nth word, and is of length
  6325. length, blank-delimited words. n must be a positive whole number. If you omit length,
  6326. it defaults to the number of remaining words in string. The returned string never has
  6327. leading or trailing blanks, but includes all blanks between the selected words.
  6328.  
  6329. Here are some examples:
  6330.  
  6331. SUBWORD('Now is the  time',2,2)    ->    'is the'
  6332. SUBWORD('Now is the  time',3)      ->    'the  time'
  6333. SUBWORD('Now is the  time',5)      ->    ''
  6334.  
  6335. =======================================================================================
  6336. 10.57  SYMBOL
  6337.  
  6338.    >>──SYMBOL(name)───────────────><
  6339.  
  6340. SYMBOL returns the state of the symbol named by name. If name is not a valid REXX
  6341. symbol, BAD is returned. SYMBOL returns VAR if it is the name of a variable (that is, a
  6342. symbol that has been assigned a value). Otherwise, SYMBOL returns LIT, indicating that
  6343. it is either a constant symbol or a symbol that has not yet been assigned a value (that
  6344. is, a literal).
  6345.  
  6346. As with symbols in REXX expressions, lowercase characters in name are translated to
  6347. uppercase and substitution in a compound name occurs if possible.
  6348.  
  6349. Note:    You should specify name as a literal string (or derived from an expression) to
  6350.          prevent substitution before it is passed to the function.
  6351.  
  6352. Here are some examples:
  6353.  
  6354. /* following: Drop A.3;  J=3 */
  6355. SYMBOL('J')      ->   'VAR'
  6356. SYMBOL(J)        ->   'LIT' /* has tested "3"     */
  6357. SYMBOL('a.j')    ->   'LIT' /* has tested "A.3"   */
  6358. SYMBOL(2)        ->   'LIT' /* a constant symbol  */
  6359. SYMBOL('*')      ->   'BAD' /* not a valid symbol */
  6360.  
  6361. =======================================================================================
  6362. 10.58  TIME
  6363.  
  6364.    >>──TIME(─┬────────┬─)─────><
  6365.              └─option─┘
  6366.  
  6367. TIME returns the local time in the 24-hour clock format hh:mm:ss (hours, minutes, and
  6368. seconds) by default; for example:
  6369.  
  6370. 04:41:37
  6371.  
  6372. You can use the following options (for which only the capitalized letter is needed) to
  6373. obtain alternative formats, or to gain access to the elapsed-time clock:
  6374.  
  6375. Civil            Returns hh:mmxx, the time in Civil format, in which the hours may take
  6376.                   the values 1 through 12, and the minutes the values 00 through 59. 
  6377.                   The minutes are followed immediately by the letters "am" or "pm" to
  6378.                   distinguish times in the morning (midnight 12:00am through 11:59am)
  6379.                   from noon and afternoon (noon 12:00pm through 11:59pm).  The hour
  6380.                   will not have a leading zero.  The minute field shows the current
  6381.                   minute (rather than the nearest minute) for consistency with other
  6382.                   TIME results.
  6383.  
  6384. Elapsed          Returns sssssssss.uu0000, the number of seconds.hundredths since the
  6385.                   elapsed time clock was stared or reset (see below). The returned
  6386.                   number has no leading zeros, but always has four trailing zeros in
  6387.                   the decimal portion. It is not affected by the setting of NUMERIC
  6388.                   DIGITS.
  6389.  
  6390. Hours            Returns number of hours since midnight in the format hh (no leading
  6391.                   zeros).
  6392.  
  6393. Long             Returns time in the format hh:mm:ss.uu0000 (where uu is the fraction
  6394.                   of seconds in hundredths of a second). Minutes          Returns number of minutes since midnight in the format: mmmm (no
  6395.                   leading zeros).
  6396.  
  6397. Normal           Returns the time in the default format hh:mm:ss, as described above.
  6398.  
  6399. Reset            Returns sssssssss.uu0000, the number of seconds.hundredths since the
  6400.                   elapsed time clock was stared or reset (see below) and also resets
  6401.                   the elapsed-time clock to zero. The returned number has no leading
  6402.                   zeros, but always has four trailing zeros in the decimal portion.
  6403.  
  6404. Seconds          Returns number of seconds since midnight in the format sssss (no
  6405.                   leading zeros).
  6406.  
  6407. Here are some examples:
  6408.  
  6409. TIME('L')    ->   '16:54:22.120000'   /* Perhaps */
  6410. TIME()       ->   '16:54:22'
  6411. TIME('H')    ->   '16'
  6412. TIME('M')    ->   '1014'           /* 54 + 60*16 */
  6413. TIME('S')    ->   '60862'  /* 22 + 60*(54+60*16) */
  6414. TIME('N')    ->   '16:54:22'
  6415. TIME('C')    ->   '4:54pm'
  6416.  
  6417. The Elapsed-Time Clock
  6418.  
  6419. The elapsed-time clock may be used for measuring real time intervals. On the first call
  6420. to the elapsed-time clock, the clock is started, and both TIME('E') and TIME('R') will
  6421. return 0.
  6422.  
  6423. The clock is saved across internal routine calls, which is to say that an internal
  6424. routine inherits the time clock its caller started.  Any timing the caller is doing is
  6425. not affected even if an internal routine resets the clock.
  6426.  
  6427. Here is an example of the elapsed-time clock:
  6428.  
  6429. time('E')    ->    0          /* The first call */
  6430. /* pause of one second here */
  6431. time('E')    ->    1.020000   /* or thereabouts */
  6432. /* pause of one second here */
  6433. time('R')    ->    2.030000   /* or thereabouts */
  6434. /* pause of one second here */
  6435. time('R')    ->    1.050000   /* or thereabouts */
  6436.  
  6437. Note:    See the DATE function about consistency of times within a single expression.
  6438.          The elapsed-time clock is synchronized to the other calls to TIME and DATE,
  6439.          so multiple calls to the elapsed-time clock in a single expression always
  6440.          return the same result.  For the same reason, the interval between two normal
  6441.          TIME and DATE results may be calculated exactly using the elapsed-time clock.
  6442.  
  6443. Implementation maximum: If the number of seconds in the elapsed time exceed nine
  6444. digits (equivalent to over 31.6 years), an error will result.
  6445.  
  6446. =======================================================================================
  6447. 10.59  TRACE
  6448.  
  6449.    >>──TRACE(─┬────────┬─)─────><
  6450.               └─option─┘
  6451.  
  6452. TRACE returns trace actions currently in effect.
  6453.  
  6454. If option is supplied, it must be the valid prefix (?), one of the alphabetic character
  6455. options (that is, starting with A, C, E, F, I, L, N, O, or R) associated with the TRACE
  6456. instruction, or both. The function uses option to alter the effective trace action
  6457. (such as tracing labels). Unlike the TRACE instruction, the TRACE function alters the
  6458. trace action even if interactive debug is active.
  6459.  
  6460. Unlike the TRACE instruction, option cannot be a number.
  6461.  
  6462. Here are some examples:
  6463.  
  6464. TRACE()       ->   '?R' /* maybe */
  6465. TRACE('O')    ->   '?R' /* also sets tracing off    */
  6466. TRACE('?I')   ->   'O'  /* now in interactive debug */
  6467.  
  6468. =======================================================================================
  6469. 10.60  TRANSLATE
  6470.  
  6471.    >>──TRANSLATE(string ─┬──────────────────────────────────┬─)──><
  6472.                            └─,─┬────────┬─┬──────────────────┬┘
  6473.                                └─tableo─┘ └─,─┬──────┬─┬────┬┘
  6474.                                               └tablei┘ └,pad┘
  6475.  
  6476. TRANSLATE translates characters in string to other characters, or reorders characters
  6477. in a string. If neither translate table is given, string is simply translated to
  6478. uppercase (for example, a lowercase a-z to an uppercase A-Z). The output table is
  6479. tableo and the input translate table is tablei (the default is XRANGE('00'x,'FF'x)).
  6480. The output table defaults to the null string and is padded with pad or truncated as
  6481. necessary. The default pad is a blank. The tables can be of any length; the first
  6482. occurrence of a character in the input table is the one that is used if there are
  6483. duplicates.
  6484.  
  6485. Here are some examples:
  6486.  
  6487. TRANSLATE('abcdef')                        ->    'ABCDEF'
  6488. TRANSLATE('abbc','&','b')                  ->    'a&&c'
  6489. TRANSLATE('abcdef','12','ec')              ->    'ab2d1f'
  6490. TRANSLATE('abcdef','12','abcd','.')        ->    '12..ef'
  6491. TRANSLATE('4123','abcd','1234')            ->    'dabc'
  6492.  
  6493. Note:    The last example shows how to use the TRANSLATE function to reorder the
  6494.          characters in a string.  In the example, the last character of any
  6495.          four-character string specified as the second argument would be moved to the
  6496.          beginning of the string.
  6497.  
  6498. =======================================================================================
  6499. 10.61  TRUNC
  6500.  
  6501.    >>───TRUNC(number ─┬─────┬─)──────><
  6502.                       └─,n──┘
  6503.  
  6504. TRUNC returns the integer part of number, and n decimal places. The default n is zero,
  6505. and it returns an integer with no decimal point. If you specify n, it must be a
  6506. nonnegative whole number. The number is first rounded according to standard REXX rules,
  6507. just as though the operation number+0 had been carried out. The number is then
  6508. truncated to n decimal places (or trailing zeros are added if needed to make up the
  6509. specified length). The result is never in exponential form.
  6510.  
  6511. Here are some examples:
  6512.  
  6513. TRUNC(12.3)           ->    12
  6514. TRUNC(127.09782,3)    ->    127.097
  6515. TRUNC(127.1,3)        ->    127.100
  6516. TRUNC(127,2)          ->    127.00
  6517.  
  6518. Note:    The number is rounded according to the current setting of NUMERIC DIGITS if
  6519.          necessary before being processed by the function.
  6520.  
  6521. =======================================================================================
  6522. 10.62  VALUE
  6523.  
  6524.    >>─VALUE(name───┬────────────────────────────────┬───)───><
  6525.                    └─,──┬───────────┬─┬───────────┬─┘
  6526.                         └─newvalue──┘ └─,selector─┘
  6527.  
  6528. VALUE returns the value of the symbol named by name, and optionally assigns it a new
  6529. value. By default, VALUE refers to the current REXX-variables environment, but other,
  6530. external collections of variables may be selected. If you use the function to refer to
  6531. REXX variables, then name must be a valid REXX symbol. (You can confirm this by
  6532. using the SYMBOL function.) Lowercase characters in name are translated to uppercase.
  6533. If name is a compound symbol, then REXX substitutes symbol values to produce the
  6534. derived name of the symbol.
  6535.  
  6536. If you specify newvalue, then the named variable is assigned this new value. This does
  6537. not affect the result returned; that is, the function returns the value of name as it
  6538. was before the new assignment.
  6539.  
  6540. Here are some examples:
  6541.  
  6542.      /* After: Drop A3; A33=7; K=3; fred='K'; list.5='Hi' */
  6543.      VALUE('a'k)     ->  'A3'
  6544.      VALUE('a'k||k)  ->  '7'
  6545.      VALUE('fred')   ->  'K'  /* looks up FRED   */
  6546.      VALUE(fred)     ->  '3'  /* looks up K      */
  6547.      VALUE(fred,5)   ->  '3'  /* and sets K=5    */
  6548.      VALUE(fred)     ->  '5'
  6549.      VALUE('LIST.'k) ->  'Hi' /* looks up LIST.5 */
  6550.  
  6551. To use VALUE to manipulate OS/2 environment variables, selector must be the string
  6552. 'OS2ENVIRONMENT' or an expression so evaluated. In this case, the variable name
  6553. need not be a valid REXX symbol. When VALUE is used to set or change the value of
  6554. an environment variable, the new value is retained after the REXX procedure ends.
  6555.  
  6556. Here are some examples:
  6557.  
  6558. /* Given that an external variable FRED has a value of 4      */
  6559. share = 'OS2ENVIRONMENT'
  6560. say VALUE('fred',7,share)      /* says '4' and assigns        */
  6561.                                /* FRED a new value of 7       */
  6562.  
  6563. say VALUE('fred',,share)       /* says '7'                    */
  6564.  
  6565. /* After this procedure ends, FRED again has a value of 4     */
  6566.  
  6567. /* Accessing and changing OS/2 environment entries            */
  6568. env = 'OS2ENVIRONMENT'
  6569. new = 'C:\LIST\PROD;'
  6570. say value('prompt',,env)   /* says '$i[p]' (perhaps)          */
  6571. say value('path',new,env)  /* says 'C:\EDIT\DOCS;' (perhaps)  */
  6572.                            /* and sets PATH = 'C:LIST\PROD'   */
  6573.  
  6574. say value('path',,env)     /* says 'C:LIST\PROD'              */
  6575.  
  6576. /* When this procedure ends, PATH = 'C:\LIST\PROD'           */
  6577.  
  6578. Notes:
  6579.  
  6580.  1. If the VALUE function refers to an uninitialized REXX variable, then the default
  6581.      value of the variable is always returned; the NOVALUE condition is not raised.
  6582.      NOVALUE is never raised by a reference to an external collection of variables.
  6583.  
  6584.  2. The VALUE function is used when a variable contains the name of another variable,
  6585.     or when a name is constructed dynamically. If the name is specified as a single
  6586.     literal string, the symbol is a constant and so the whole function call can usually
  6587.     be replaced directly by the string between the quotation marks.  (For example,
  6588.     fred=VALUE('k'); is identical to the assignment fred=k;,unless the NOVALUE
  6589.     condition is being trapped.
  6590.  
  6591.  3. To effect temporary changes to environment variables, use the SETLOCAL and
  6592.     ENDLOCAL functions.
  6593.  
  6594. =======================================================================================
  6595. 10.63  VERIFY
  6596.  
  6597.    >>──VERIFY(string,reference─┬──────────────────────────┬─)────><
  6598.                                └─,─┬─────────┬─┬────────┬─┘
  6599.                                    └─option──┘ └─,start─┘
  6600.  
  6601. VERIFY returns a number indicating whether string is composed only of characters from
  6602. reference. VERIFY returns the position of the first character in string that is not
  6603. also in reference.  If all the characters were found in reference, 0 is returned.
  6604.  
  6605. The third argument, option, can be any expression that results in a string starting
  6606. with N or M that represents either Nomatch (the default) or Match.. Only the first
  6607. character of option is significant and it can be in uppercase or lowercase, as usual.
  6608. If Nomatch is specified, the position of the first character in string that is not also
  6609. in reference is returned. 0 is returned if all characters in string were found in
  6610. reference. If Match is specified, the position of the first character in string that is
  6611. in reference is returned, or 0 is returned if none of the characters were found.
  6612.  
  6613. The default for start is 1, thus, the search starts at the first character of string.
  6614. You can override this by specifying a different start point, which must be a positive
  6615. whole number.
  6616.  
  6617. VERIFY always returns 0 if string is null or if start is greater than LENGTH(string).
  6618. If reference is null, VERIFY returns 0 if you specify Match; otherwise, 1 is returned.
  6619.  
  6620. Here are some examples:
  6621.  
  6622. VERIFY('123','1234567890')             ->    0
  6623. VERIFY('1Z3','1234567890')             ->    2
  6624. VERIFY('AB4T','1234567890')            ->    1
  6625. VERIFY('AB4T','1234567890','M')        ->    3
  6626. VERIFY('AB4T','1234567890','N')        ->    1
  6627. VERIFY('1P3Q4','1234567890',,3)        ->    4
  6628. VERIFY('AB3CD5','1234567890','M',4)    ->    6
  6629.  
  6630. =======================================================================================
  6631. 10.64  WORD
  6632.  
  6633.    >>───WORD(string,n)────────><
  6634.  
  6635. WORD returns the n th blank-delimited word in string. n must be a positive whole
  6636. number. If there are fewer than n words in string, the null string is returned. This
  6637. function is equivalent to SUBWORD(string,n,1).
  6638.  
  6639. Here are some examples:
  6640.  
  6641. WORD('Now is the time',3)    ->    'the'
  6642. WORD('Now is the time',5)    ->    ''
  6643.  
  6644. =======================================================================================
  6645. 10.65  WORDINDEX
  6646.  
  6647.    >>───WORDINDEX(string,n)────────><
  6648.  
  6649. WORDINDEX returns the position of the first character in the n th blank-delimited word
  6650. in string. n must be a positive whole number. If there are fewer than n words in the
  6651. string, 0 is returned.
  6652.  
  6653. Here are some examples:
  6654.  
  6655. WORDINDEX('Now is the time',3)    ->    8
  6656. WORDINDEX('Now is the time',6)    ->    0
  6657.  
  6658. =======================================================================================
  6659. 10.66  WORDLENGTH
  6660.  
  6661.    >>───WORDLENGTH(string,n)────────><
  6662.  
  6663. WORDLENGTH returns the length of the n th blank-delimited word in string. n must be a
  6664. positive whole number. If there are fewer than n words in the string, 0 is returned.
  6665.  
  6666. Here are some examples:
  6667.  
  6668. WORDLENGTH('Now is the time',2)       ->    2
  6669. WORDLENGTH('Now comes the time',2)    ->    5
  6670. WORDLENGTH('Now is the time',6)       ->    0
  6671.  
  6672. =======================================================================================
  6673. 10.67  WORDPOS
  6674.  
  6675.    >>───WORDPOS(phrase,string──┬─────────┬──)───────><
  6676.                                └─,start──┘
  6677.  
  6678. WORDPOS searches string for the first occurrence of the sequence of blank-delimited
  6679. words phrase, and returns the word number of the first word of phrase in string. Multiple blanks between words in either phrase or string are treated as a single blank
  6680. for the comparison, but otherwise the words must match exactly.
  6681.  
  6682. By default, the search starts at the first word in string. You can override this by
  6683. specifying start (which must be positive), the word at which to start the search.
  6684.  
  6685. Here are some examples:
  6686.  
  6687. WORDPOS('the','now is the time')              ->  3
  6688. WORDPOS('The','now is the time')              ->  0
  6689. WORDPOS('is the','now is the time')           ->  2
  6690. WORDPOS('is   the','now is the time')         ->  2
  6691. WORDPOS('is   time ','now is   the time')     ->  0
  6692. WORDPOS('be','To be or not to be')            ->  2
  6693. WORDPOS('be','To be or not to be',3)          ->  6
  6694.  
  6695. =======================================================================================
  6696. 10.68  WORDS
  6697.  
  6698.    >>───WORDS(string)────────><
  6699.  
  6700. WORDS returns the number of blank-delimited words in string.
  6701.  
  6702. Here are some examples:
  6703.  
  6704. WORDS('Now is the time')    ->    4
  6705. WORDS(' ')                  ->    0
  6706. @
  6707. @@@@@@@@@@@@@@@@@@@
  6708. 10.69  XRANGE
  6709.  
  6710.    >>───XRANGE(─┬───────┬──┬───────┬─)───────><
  6711.                 └─start─┘  └─,end──┘
  6712.  
  6713. XRANGE returns a string of all one-byte codes between and including the values start
  6714. and end. The default value for start is '00'x, and the default value for end is 'FF'x.
  6715. If start is greater than end, the values wrap from 'FF'x to '00'x. If specified, start
  6716. and end must be single characters.
  6717.  
  6718. Here are some examples:
  6719.  
  6720. XRANGE('a','f')      ->   'abcdef'
  6721. XRANGE('03'x,'07'x)  ->   '0304050607'x
  6722. XRANGE(,'04'x)       ->   '0001020304'x
  6723. XRANGE('i','j')      ->   '898A8B8C8D8E8F9091'x  /* EBCDIC */
  6724. XRANGE('FE'x,'02'x)  ->   'FEFF000102'x
  6725. XRANGE('i','j')      ->   'ij'                   /* ASCII  */
  6726.  
  6727. =======================================================================================
  6728. 10.70  X2B (Hexadecimal to Binary)
  6729.  
  6730.    >>───X2B(hexstring)──────────><
  6731.  
  6732. X2B converts hexstring (a string of hexadecimal characters) to an equivalent string of
  6733. binary digits. hexstring can be of any length; each hexidecimal character is converted
  6734. to a string of four binary digits. The returned string has a length that is a multiple
  6735. of four, and does not include any blanks.
  6736.  
  6737. Blanks can optionally be added (at byte boundaries only, not leading or trailing) to
  6738. aid readability; they are ignored. If hexstring is null, X2B returns 0.
  6739.  
  6740. Here are some examples:
  6741.  
  6742. X2B('C3')        ==  '11000011'
  6743. X2B('7')         ==  '0111'
  6744. X2B('1 C1')      ==  '000111000001'
  6745.  
  6746. You can combine X2B( ) may be combined with the functions D2X( ) and C2X( ) to
  6747. convert decimal numbers or character strings into binary form.
  6748.  
  6749. Here are some examples:
  6750.  
  6751. X2B(C2X('C3'x))  ==  '11000011'
  6752. X2B(D2X('129'))  ==  '10000001'
  6753. X2B(D2X('12'))   ==  '1100'
  6754.  
  6755. =======================================================================================
  6756. 10.71  X2C (Hexadecimal to Character)
  6757.  
  6758.    >>───X2C(hexstring)─────────><
  6759.  
  6760. X2C converts hexstring (a string of hexadecimal characters) to character.
  6761.  
  6762. hexstring can be of any length. You can optionally add blanks to hexstring (at byte
  6763. boundaries only, not leading or trailing positions) to aid readability; they are
  6764. ignored.
  6765.  
  6766. If necessary, hexstring is padded with a leading 0 to make an even number of
  6767. hexadecimal digits.
  6768.  
  6769. Here are some examples:
  6770.  
  6771. X2C('4865 6c6c 6f') ->  'Hello'     /*  ASCII   */
  6772. X2C('3732 73')      ->  '72s'       /*  ASCII   */
  6773. X2C('F')          ->    '0F'x
  6774.  
  6775. =======================================================================================
  6776. 10.72  X2D (Hexadecimal to Decimal)
  6777.  
  6778.    >>───X2D(hexstring ─┬─────┬─)──────><
  6779.                        └─,n──┘
  6780.  
  6781. X2D converts hexstring (a string of hexadecimal characters) to decimal. If the result
  6782. cannot be expressed as a whole number, an error results. That is, the result must have
  6783. no more digits than the current setting of NUMERIC DIGITS.
  6784.  
  6785. You can optionally add blanks to hexstring (at byte boundaries only, not leading or
  6786. trailing positions) to aid readability; they are ignored.
  6787.  
  6788. If hexstring is null, X2D returns 0.
  6789.  
  6790. If n is not specified, hexstring is processed as an unsigned binary number.
  6791.  
  6792. Here are some examples:
  6793.  
  6794. X2D('0E')        ->    14
  6795. X2D('81')        ->    129
  6796. X2D('F81')       ->    3969
  6797. X2D('FF81')      ->    65409 X2D('c6 f0'X)    ->    240
  6798.  
  6799. If n is specified, the given sequence of hexadecimal digits is padded on the left with
  6800. zeros (note, not sign-extended), or truncated on the left to n characters. The
  6801. resulting string of n hexadecimal digits is taken to be a signed binary number-positive
  6802. if the leftmost bit is OFF, and negative, in two's complement notation, if the leftmost
  6803. bit is ON. If n is 0, X2D returns 0.
  6804.  
  6805. Here are some examples:
  6806.  
  6807. X2D('81',2)      ->    -127
  6808. X2D('81',4)      ->    129
  6809. X2D('F081',4)    ->    -3967
  6810. X2D('F081',3)    ->    129
  6811. X2D('F081',2)    ->    -127
  6812. X2D('F081',1)    ->    1
  6813. X2D('0031',0)    ->    0
  6814.  
  6815. =======================================================================================
  6816. SECTION 11      Queue Interface
  6817.  
  6818. REXX provides queuing services entirely separate from the OS/2 interprocess
  6819. communications queues. The queues discussed here are solely for the use of REXX
  6820. programs.
  6821.  
  6822. REXX queues are manipulated within a program by these instructions:
  6823.  
  6824. PUSH       Stacks a string on top of the queue (LIFO).
  6825.  
  6826. QUEUE      Adds a string to the tail of the queue (FIFO).
  6827.  
  6828. PULL       Reads a string from the head of the queue. If the queue is empty, input is
  6829.             taken from the console (STDIN:).
  6830.  
  6831. To get the number of items remaining in the queue, use the function QUEUED.
  6832.  
  6833. Access to Queues
  6834.  
  6835. There are two kinds of queues in REXX. Both kinds are accessed and processed by
  6836. name.
  6837.  
  6838. Session Queues - One session queue is automatically provided for each OS/2 session
  6839. in operation. Its name is always SESSION, and it is created by REXX the first time
  6840. information is put on the queue by a program or procedure. All processes (programs and
  6841. procedures) in a session can access the session queue. However, a given process can
  6842. only access the session queue defined for its session, and the session queue is not
  6843. unique to any single process in the session.
  6844.  
  6845. Private Queues - Private queues are created (and deleted) by your program. You can
  6846. name the queue yourself or leave the naming to REXX. In order for your program to use
  6847. any queue, it must know the name of the queue.
  6848.  
  6849.  
  6850. =======================================================================================
  6851. 11.1   RXQUEUE Function
  6852.  
  6853. Use the RxQueue function in a REXX program to create and delete queues and to set
  6854. and query their names. The first parameter determines the function, the entire function
  6855. name must be specified but the case of the function parameter is ignored.
  6856.  
  6857. Syntax:
  6858.  
  6859.    >>──RXQUEUE(─┬──"Create"──┬─────────────┬─┬─)─────><
  6860.                 │            └─,queuename ─┘ │
  6861.                 ├───"Delete"── queuename ────┤
  6862.                 ├───"Get"───── newqueuename ─┤
  6863.                 └───"Set"───── newqueuename ─┘
  6864.  
  6865. Parameters:
  6866.  
  6867. Create           Creates a queue with the name, queuename (if specified); if no name is
  6868.                   specified, then REXX will provide a name. Returns the name of the
  6869.                   queue in either case.
  6870.  
  6871. Delete           Deletes the named queue; returns 0 if successful, a nonzero number if
  6872.                   an error occurs; the possible return values are:
  6873.  
  6874.    0          Queue has been deleted.
  6875.  
  6876.    5          Not a valid queue name.
  6877.  
  6878.    9          Queue named does not exist.
  6879.  
  6880.    10         Queue is busy; wait is active.
  6881.  
  6882.    12         A memory failure has occurred.
  6883.  
  6884.    1000       Initialization error; check file OS/2.INI
  6885.  
  6886. Get              Returns the name of the queue currently in use.
  6887.  
  6888. Set              Sets the name of the current queue to newqueuename and returns the
  6889.                   previous name of the queue.
  6890.  
  6891. Example: Sample Queue in a REXX Procedure
  6892.  
  6893. /*                                                                */
  6894. /*        push/pull WITHOUT multiprogramming support         */
  6895. /*                                                                */
  6896. push date() time()          /* push date and time            */
  6897. do 1000                     /* lets pass some time           */
  6898.   nop                       /* doing nothing                 */
  6899. end                         /* end of loop                   */
  6900. pull a b .                  /* pull them                     */
  6901. say 'Pushed at ' a b ', Pulled at ' date()
  6902. time() /* say now and then */
  6903.  
  6904. /*                                                                    */
  6905. /*              push/pull WITH multiprogramming support               */
  6906. /*            (no error recovery, or unsupported env tests            */
  6907. /*                                                                    */
  6908. newq = RXQUEUE('Create')    /* create a unique queue           */
  6909. oq = RXQUEUE('Set',newq)    /* establish new queue             */
  6910. push date() time()          /* push date and time              */
  6911. do 1000                     /* lets spend some time            */
  6912.   nop                       /* doing nothing                   */
  6913. end                         /* end of loop                     */
  6914. pull a b .                  /* get pushed info                 */
  6915. say 'Pushed at ' a b ', Pulled at ' date() time() /* tell user     */
  6916. call RXQUEUE 'Delete',newq         /* destroy unique queue created  */
  6917. call RXQUEUE 'Set',oq         /* reset to default queue (not required)*/
  6918.  
  6919. Special Considerations
  6920.  
  6921.  1. External programs that must communicate with a REXX procedure by means of
  6922.     defined data queues can use the default queue or the session queue, or they can
  6923.     receive the data queue name by some interprocess communication technique. This
  6924.     could include parameter passing, placement on a prearranged logical queue, or use
  6925.     of normal OS/2 Inter-Process Communication mechanisms (for example, pipes,
  6926.     shared memory or IPC queues).
  6927.  
  6928.  2. Named queues are available across the entire system; therefore, the names of
  6929.     queues must be unique within the system.  If a queue named os2que exists and this
  6930.     function is issued:     newqueue = RXQUEUE('Create', 'os2que')
  6931.  
  6932.     a new queue is created and the name is chosen by REXX.  This new name is
  6933.     returned by the function.
  6934.  
  6935.  3. Any external program started inherits as its default queue the queue in use by the
  6936.     parent process.
  6937.  
  6938. Detached Processes
  6939.  
  6940.  1. Detached processes will access a detached session queue that is unique for each
  6941.     detached process. Note, however, that this detached session queue is not the same
  6942.     as the session queue of the starting session.
  6943.  
  6944.  2. REXX programs that are to be run as detached processes cannot perform any SAY
  6945.     instructions or any PULL or PARSE PULL instructions that involve terminal I/O.
  6946.     However, PULL and PARSE PULL instructions that act on a queue are permitted in
  6947.     detached processes.
  6948.  
  6949. Multi-Programming Considerations
  6950.  
  6951. This data queue mechanism differs from OS/2 standard API queueing in the following
  6952. ways:
  6953.  
  6954.  1. The queue is NOT owned by a specific process, and as such any process is entitled
  6955.     to modify the queue at any time.  The operations that effect the queue are atomic,
  6956.     in that the resource will be serialized by the subsystem such that no data
  6957.     integrity problems can be encountered.
  6958.  
  6959.     However, synchronization of requests such that two processes, accessing the same
  6960.     queue, get the data in the order it was placed on the queue is a user
  6961.     responsibility and will not be provided by the subsystem support code. This
  6962.     selector is owned by the calling application code and must be freed by the caller  
  6963.     using DosFreeSeg.
  6964.  
  6965.  2. A regular OS/2 IPC queue is owned (created) by a specific process. When that
  6966.     process terminates, the queue is destroyed. Conversely, the queues created by the
  6967.     RxQueue('Create', queuename) call will exist until EXPLICITLY deleted. Termination
  6968.     of a program or procedure that created a private queue does not force the deletion
  6969.     of the private queue. Any data on the queue when the process creating it terminates
  6970.     will remain on the queue until either the queue is deleted (by way of the REXX
  6971.     function call RxQueue('Create', queuename) or until the data is read.
  6972.  
  6973. Data queues must be explicitly deleted by some procedure or program (not necessarily
  6974. the creator). Deletion of a queue with remaining items, destroys those items. If a
  6975. queue is not deleted, it will be lost and cannot be recovered accept by randomly
  6976. attempting to access each queue in the defined series.
  6977.