home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / bt_98162.zip / BINTOOL.INF (.txt) < prev    next >
OS/2 Help File  |  1998-06-11  |  38KB  |  1,237 lines

  1.  
  2. ΓòÉΓòÉΓòÉ 1. Introduction ΓòÉΓòÉΓòÉ
  3.  
  4. Introduction 
  5.  
  6. This is binary editor (or file creator) which takes all commands via a text 
  7. file or command line. 
  8.  
  9. It can verify the contents of files before a patch is applied. The following is 
  10. an example of how a file can be created: 
  11.  
  12.    OPENNEW  L4029.PIC
  13.    WRITE   '1B'x || '[K' || '0B00 FF31 02 A0 04 00 00 0000 90'x
  14.    CLOSE
  15.  
  16. This program does not have commands such as #define & #include as its expected 
  17. that you'd add a PPWIZARD preprocessor step if you wanted the much more power 
  18. capabilities (macros with parameters, conditional inclusion etc). 
  19.  
  20. Please see my web page "http://www.ozemail.com.au/~dbareis". for the latest 
  21. copy of BINTOOL or PPWIZARD, or contact me (Dennis Bareis) via email 
  22. (db0@anz.com).  I'm open to any reasonable suggestions. 
  23.  
  24. Please have a look at the proposed changes section and after using this program 
  25. for a while tell me what you think. 
  26.  
  27. Note that I would have loved to have written this in Java, however as a 
  28. compiled language it does not have an "interpret" instruction. Apparently 
  29. something is being added to version 1.2 which might allow something similar, 
  30. I'll have a look then.  The "interpret" instruction is important as it allows 
  31. the preprocessor to be extended as well as doing a lot of work I'd otherwise 
  32. need to do myself (and I wouldn't do it as well).  I will not be rewriting the 
  33. preprocessor in Java (as it wouldn't be compatible with the rexx version), but 
  34. with any luck I'd be able to write any similar future stuff in Java.... 
  35.  
  36.  
  37. ΓòÉΓòÉΓòÉ 1.1. Proposed Changes ΓòÉΓòÉΓòÉ
  38.  
  39. If I've got the time I like to think about the best way of implementing 
  40. something (as well as questioning whether or not it should be).  If I have a 
  41. requirement I like to implement as generic a solution as possible.  This is my 
  42. "longer" term think about it list.. 
  43.  
  44. Come on, surely someone out there wishes this had an "xyz" feature or something 
  45. worked better?  I've only had one single comment about its functioning and this 
  46. prompted me to make a change, since there have been so many downloads of this 
  47. tool its either crap or perfect... I don't think its crap, but then again I 
  48. doubt its perfect either, so comments please!  Tell me what you think even if 
  49. option is already listed as without feedback on whats important I could reasign 
  50. priorities or delete an item altogether. 
  51.  
  52. Proposed Changes - Rough Priority 
  53.  
  54.        1. Command line parameters (such as /DEBUG, and /PARM). 
  55.  
  56.        2. Better output from script, get rid of commands, show again if in 
  57.           debug mode (plus normal interactive stuff) + maybe more. 
  58.  
  59.        3. DELETE command.  Deletes specified number of bytes (shrinks file). 
  60.  
  61.        4. COPY  command.  Copies  specified number of bytes to specified file. 
  62.           A CUT becomes a COPY then DELETE. 
  63.  
  64.        5. INSERT command.  Insert contents of file.  Also Insert specified 
  65.           bytes. 
  66.  
  67.        6. BOOKMARK locations.  Then "MoveTo Fred" etc. 
  68.  
  69.  
  70. ΓòÉΓòÉΓòÉ 1.2. Change History ΓòÉΓòÉΓòÉ
  71.  
  72. Change History 
  73.  
  74.        1. Version 98.??? 
  75.  
  76.              
  77.  
  78.  
  79. ΓòÉΓòÉΓòÉ 1.3. Bugs ΓòÉΓòÉΓòÉ
  80.  
  81. Currently Known Bugs 
  82.  
  83.  Reporting Bugs or Suggestions 
  84.  
  85.  If reporting bugs please supply: 
  86.  
  87.        1. All files involved (input, output and any Batch files used to run the 
  88.           preprocessor).  You have hopefully trimmed out everything which is 
  89.           not required to reproduce the problem. 
  90.  
  91.        2. A detailed description of the problem. 
  92.  
  93.  The easier you make it for me the faster I will be able to come up with a fix 
  94.  or tell you what your doing wrong etc. 
  95.  
  96.  
  97. ΓòÉΓòÉΓòÉ 2. BINTOOL.CMD Command Line ΓòÉΓòÉΓòÉ
  98.  
  99. BINTOOL.CMD Command Line 
  100.  
  101.         BINTOOL[.CMD]  [whitespace]?[whitespace]         OR
  102.         BINTOOL[.CMD]  [whitespace]ScriptFile[whitespace]
  103.  
  104. This program has two main modes "INTERACTIVE" mode where the user enters all 
  105. information from a command prompt and file driven.  If "?" is specified 
  106. interactive mode is used otherwise you supply the name of the file which 
  107. contains the commands to be executed. 
  108.  
  109. In both modes blank lines and ones that begin with ";" are ignored.  If a line 
  110. contains ";;" then the last occurrance within a line and anything following is 
  111. removed (inline comment). 
  112.  
  113. Script Mode 
  114.  
  115. If a command or verification fails the script terminates. 
  116.  
  117. Interactive Mode 
  118.  
  119. If a command or verification fails an error is displayed but the program does 
  120. not terminate. 
  121.  
  122. The command prompt maintains a history of previous commands and all usual keys 
  123. work including "<F1>" or selective recall. 
  124.  
  125. In interactive mode the "RECORD" command can be used to record all the commands 
  126. typed so you can later on rerun what you have recorded to repeat if required. 
  127.  
  128. RETURN CODES 
  129.  
  130.          A return code of 0 indicates success. 
  131.  
  132.          Any other value indicates an error occurred. 
  133.  
  134.  
  135. ΓòÉΓòÉΓòÉ 2.1. /Color ΓòÉΓòÉΓòÉ
  136.  
  137. Switch /Color[:YesOrNo] 
  138.  
  139. This is a BINTOOL.CMD command line switch.  You can set up your own default 
  140. switches in the "BINTOOL_OPTIONS" environment variable. You can determine if 
  141. colors are used in displayed output.  Useful if redirecting output to log files 
  142. (or you just hate colors!). 
  143.  
  144. If the "YesOrNo" is not specified then it defaults to "Y", otherwise one of the 
  145. following values is expected: 
  146.  
  147.          Y 
  148.          N 
  149.          YES 
  150.          NO 
  151.  
  152.  For colors to work the session must support ANSI color strings. OS/2 does this 
  153.  by default.  NT does not seem to. 
  154.  
  155.  
  156. ΓòÉΓòÉΓòÉ 2.2. /Debug ΓòÉΓòÉΓòÉ
  157.  
  158. Switch /Debug 
  159.  
  160. This is a BINTOOL.CMD command line switch.  You can set up your own default 
  161. switches in the "BINTOOL_OPTIONS" environment variable. This option can be 
  162. useful in determining what is going wrong when you don't get the output you 
  163. expected. 
  164.  
  165.  
  166. ΓòÉΓòÉΓòÉ 3. Commands ΓòÉΓòÉΓòÉ
  167.  
  168. Commands 
  169.  
  170. The following commands are available to you when you use the BINTOOL.CMD: 
  171.  
  172.          CLOSE 
  173.          DECIMAL 
  174.          DUMP 
  175.          DUMPCHAR 
  176.          EXIT 
  177.          GOTO 
  178.          FIND 
  179.          FINDCS 
  180.          HEXADECIMAL 
  181.          LOCATE[!] 
  182.          MOVETO 
  183.          ONERROR 
  184.          OPEN 
  185.          OPENNEW 
  186.          OPENREAD 
  187.          QUIT 
  188.          REBUILD 
  189.          RECORD 
  190.          REXX 
  191.          SYSTEM 
  192.          VERIFY 
  193.          VERIFYFILE 
  194.          WRITE 
  195.          ? 
  196.  
  197.  Note that a lot of the commands are demonstrated further in the example 
  198.  scripts that are included in this manual.  Also note that for anything but 
  199.  trivial scripts its worth the effort to include a "PPWIZARD" step in a batch 
  200.  file rather than using BINTOOL directly.  This would allow you to use more 
  201.  powerful commands such as #define, #evaluate, #include, #if and more. 
  202.  
  203.  
  204. ΓòÉΓòÉΓòÉ 3.1. CLOSE ΓòÉΓòÉΓòÉ
  205.  
  206. CLOSE 
  207.  
  208. This will close the currently open file.  It does not take parameters. 
  209.  
  210.  
  211. ΓòÉΓòÉΓòÉ 3.2. DECIMAL ΓòÉΓòÉΓòÉ
  212.  
  213. DECIMAL 
  214.  
  215. If you do not specifically indicate that a number is in either hex or decimal 
  216. then by default the number is assumed to be hexadecimal. To indicate a number 
  217. is in base 10 preceed the number with '$', for hexadecimal use 'x'. 
  218.  
  219. This commands purpose is to change the default to decimal.  To restore it use 
  220. the "HEXADECIMAL" command. 
  221.  
  222.  
  223. ΓòÉΓòÉΓòÉ 3.3. DUMP ΓòÉΓòÉΓòÉ
  224.  
  225. DUMP 
  226.  
  227. This command will dump all or part of the current file in both hex and 
  228. character modes.  The default character set used is ASCII with dots used for 
  229. unusual characters, if this is unsuitable you could create your own character 
  230. tables and load them with the "DUMPCHAR" command. 
  231.  
  232. A second dump command immediately following a previous one will always continue 
  233. from where the previous one left off.  Commands which affect the current 
  234. position (such as WRITE) will reset the position from which following dumps 
  235. take place. 
  236.  
  237. A dump command does not move the read/write position. 
  238.  
  239. Syntax 
  240.  
  241.    [whitespace]DUMP [whitespace][NumBytesToDump][whitespace]
  242.  
  243. The "NumBytesToDump" specifies the number of bytes to dump.  If not specified a 
  244. default is used. 
  245.  
  246. EXAMPLE OF DUMP OUTPUT 
  247.  
  248.    40: 0E1F BA0E 00B4 09CD 21B8 014C CD21 5468   | ........!..L.!Th |
  249.    50: 6973 2070 726F 6772 616D 2063 616E 6E6F   | is program canno |
  250.    60: 7420 6265 2072 756E 2069 6E20 6120 444F   | t be run in a DO |
  251.    70: 5320 7365 7373 696F 6E2E 0D0D 0A24 0000   | S session....$.. |
  252.  
  253.  
  254. ΓòÉΓòÉΓòÉ 3.4. DUMPCHAR ΓòÉΓòÉΓòÉ
  255.  
  256. DUMPCHAR 
  257.  
  258. This command allows you to redefine the character set used in the character 
  259. portion of a dump.  This could be as simple as changing the ASCII character set 
  260. so that blanks are used instead of dot for unusual chacters.  See EBCDIC.BIN 
  261. for an example for how to create a new character set. 
  262.  
  263. Syntax 
  264.  
  265.    [whitespace]DUMPCHAR [whitespace][["]CharacterSetFile["]][whitespace]
  266.  
  267. The "CharacterSetFile" specifies the name of the file to be loaded.  If not 
  268. specified then the character set is restored to the default. 
  269.  
  270. FORMAT OF FILE 
  271.  
  272. The following describes the contents of the file (all bytes in ASCII): 
  273.  
  274.        1. It must begin with the string "DUMPCHAR". 
  275.  
  276.        2. The character "|". 
  277.  
  278.        3. A description of the file, displayed when loaded. 
  279.  
  280.        4. The character "|". 
  281.  
  282.        5. There must be exactly 256 characters which are mapped to the hex 
  283.           value. 
  284.  
  285.  
  286. ΓòÉΓòÉΓòÉ 3.5. EXIT ΓòÉΓòÉΓòÉ
  287.  
  288. EXIT 
  289.  
  290. In interactive mode this will exit the program.  Opened files will be closed. 
  291.  
  292.  
  293. ΓòÉΓòÉΓòÉ 3.6. FIND ΓòÉΓòÉΓòÉ
  294.  
  295. FIND 
  296.  
  297. This command will FIND a number of bytes in the file from the current location 
  298. onwards.  If we don't find the string then the current file position is 
  299. restored. 
  300.  
  301. This command is used to perform a case insensitive search.  If you require a 
  302. case sensitive search you should use "FINDCS" instead.  Note for performance a 
  303. case sensitive search will be performed anyway if your search string does not 
  304. contain any letters. 
  305.  
  306. Syntax 
  307.  
  308.    [whitespace]FIND [whitespace]RexStringExpression[whitespace]
  309.  
  310. The "RexStringExpression" is a rexx expression which will be executed.  The 
  311. result should be a string which is to be verified. 
  312.  
  313. EXAMPLES 
  314.  
  315.    FIND    '0000'x || copies('*', 8) || '0B00'x   ;;Look for these 12 bytes
  316.    WRITE   'FFFF'x                                ;;Patch the first 2 bytes
  317.  
  318.  
  319. ΓòÉΓòÉΓòÉ 3.7. FINDCS ΓòÉΓòÉΓòÉ
  320.  
  321. FINDCS 
  322.  
  323. This command is the same as the "FIND" command except that a case sensitive 
  324. search is performed. 
  325.  
  326.  
  327. ΓòÉΓòÉΓòÉ 3.8. GOTO ΓòÉΓòÉΓòÉ
  328.  
  329. GOTO 
  330.  
  331. This command will transfer control to the line with the label specified. 
  332.  
  333. Syntax 
  334.  
  335.    [whitespace]GOTO [whitespace]Label[whitespace]
  336.  
  337. The "Label" is the name of a label that should be defined somewhere in the 
  338. source script (either before or after the current location). 
  339.  
  340. EXAMPLES 
  341.  
  342.    ;--- Transfer control to the "END" label ---
  343.    GOTO    END
  344.    ...
  345.    ...
  346.  
  347.    ;--- Define the "END" label ----------------
  348.    :End
  349.  
  350.  
  351. ΓòÉΓòÉΓòÉ 3.9. HEXADECIMAL ΓòÉΓòÉΓòÉ
  352.  
  353. HEXADECIMAL 
  354.  
  355. If you do not specifically indicate that a number is in either hex or decimal 
  356. then by default the number is assumed to be hexadecimal. To indicate a number 
  357. is in base 10 preceed the number with '$', for hexadecimal use 'x'. 
  358.  
  359. This commands purpose is to change the back to hexadecimal in situations where 
  360. you have probably changed the default number base. For example you could have 
  361. previously used the "DECIMAL" command to make base 10 the default number base. 
  362.  
  363.  
  364. ΓòÉΓòÉΓòÉ 3.10. LOCATE[!] ΓòÉΓòÉΓòÉ
  365.  
  366. LOCATE[!] 
  367.  
  368. These commands will find the first character that is in or not in a list of 
  369. characters you supply.  You could use this to verify that a file contains no 
  370. null bytes ('00x') etc. 
  371.  
  372. Syntax 
  373.  
  374.    [whitespace]LOCATE[!] [whitespace]RexStringExpression[whitespace]
  375.  
  376. If the command used is "LOCATE" then the search will be for the first character 
  377. that is also in the list you supply. If LOCATE! is used then it will try to 
  378. find a character that is not in the list. 
  379.  
  380. The "RexStringExpression" is a rexx expression which will be executed.  The 
  381. result is a sequence of characters. 
  382.  
  383. EXAMPLES 
  384.  
  385. See if there are any null bytes in the file: 
  386.  
  387.    LOCATE  '00'x
  388.  
  389. Find the first non numeric byte: 
  390.  
  391.    LOCATE!  xrange('0', '9')
  392.  
  393.  
  394. ΓòÉΓòÉΓòÉ 3.11. MOVETO ΓòÉΓòÉΓòÉ
  395.  
  396. MOVETO 
  397.  
  398. This command is used to move the current read, write or dump location to a new 
  399. position within the file. 
  400.  
  401. Note that all seeks will fail unless the file contains at least one byte (rexx 
  402. feature).  If you try to move outside of the valid range the command will fail. 
  403.  
  404. Syntax 
  405.  
  406.    [whitespace]MOVETO [whitespace]START|END[whitespace]    OR
  407.    [whitespace]MOVETO [whitespace]+|-  Offset[whitespace]  OR
  408.    [whitespace]MOVETO [whitespace]Offset[whitespace]
  409.  
  410. The "Offset" parameter is a decimal or hex value which specifies how much to 
  411. move or where to move to. to be opened. 
  412.  
  413. EXAMPLES 
  414.  
  415.    MoveTo  Start
  416.    MoveTo  End
  417.    MOVETO  + x1                            ;;Move forwards  1 byte  (number supplied as hex)
  418.    MOVETO  - $2                            ;;Move backwards 2 bytes (number supplied as decimal)
  419.    HEXADECIMAL                             ;;Ensure default is hex
  420.    MoveTo  B                               ;;Move to offset B hex (0 = 1st byte)
  421.  
  422.  
  423. ΓòÉΓòÉΓòÉ 3.12. ONERROR ΓòÉΓòÉΓòÉ
  424.  
  425. ONERROR 
  426.  
  427. This command can be used to specify a label where processing will be 
  428. transferred if the next command fails. 
  429.  
  430. Syntax 
  431.  
  432.    [whitespace]ONERROR [whitespace]Label[whitespace]
  433.  
  434. The "Label" is the name of a label that should be defined somewhere in the 
  435. source script (either before or after the current location). 
  436.  
  437. EXAMPLES 
  438.  
  439.    ;--- Patch all Nulls -------------------------
  440.    rexx   NullCounter = 0
  441.    :PatchLoop
  442.        ;--- Look for null bytes -----------------
  443.        OnError NoMoreNulls
  444.        FIND  "00"x
  445.  
  446.        ;--- Overwrite null byte -----------------
  447.        WRITE 'FF';
  448.        rexx   NullCounter = NullCounter + 1
  449.    goto PatchLoop
  450.    :NoMoreNulls
  451.    rexx   say AddCommasToDecimalNumber(NullCounter) || ' null byte(s) converted.'
  452.  
  453.  
  454. ΓòÉΓòÉΓòÉ 3.13. OPEN ΓòÉΓòÉΓòÉ
  455.  
  456. OPEN 
  457.  
  458. This command is used to open a file for read and write.  If you wish to start 
  459. with a clean file then use "OPENNEW" instead.  If you don't intend to update 
  460. the file then you should use "OPENREAD". 
  461.  
  462. Syntax 
  463.  
  464.    [whitespace]OPEN [whitespace]["]FileName["][whitespace]
  465.  
  466. The "FileName" parameter is the name of the file to be opened. 
  467.  
  468. EXAMPLES 
  469.  
  470.    OPEN  "MEMORY.BIN"
  471.    DUMP
  472.    CLOSE
  473.  
  474.  
  475. ΓòÉΓòÉΓòÉ 3.14. OPENNEW ΓòÉΓòÉΓòÉ
  476.  
  477. OPENNEW 
  478.  
  479. This command is the same as "OPEN" except that any existing file is first 
  480. deleted so that you are starting with a "clean" file. 
  481.  
  482.  
  483. ΓòÉΓòÉΓòÉ 3.15. OPENREAD ΓòÉΓòÉΓòÉ
  484.  
  485. OPENREAD 
  486.  
  487. This command is the same as "OPEN" except that the file must exists and is 
  488. opened for read only.  You will not be able to perform any commands that modify 
  489. the file (such as "WRITE"). 
  490.  
  491.  
  492. ΓòÉΓòÉΓòÉ 3.16. QUIT ΓòÉΓòÉΓòÉ
  493.  
  494. QUIT 
  495.  
  496. An alias for "EXIT". 
  497.  
  498.  
  499. ΓòÉΓòÉΓòÉ 3.17. REBUILD ΓòÉΓòÉΓòÉ
  500.  
  501. REBUILD 
  502.  
  503. This command allows you to open any binary file and create a script which could 
  504. be used to recreate it from scratch. 
  505.  
  506. One possible use of this command is to binary edit the file with a text editor. 
  507. Might be slower but its certainly easier.  Once in text form you can use 
  508. commands such as PVCS to track source changes. Difference programs can also be 
  509. used. 
  510.  
  511. As the command only rebuilds the file from the current location onwards to 
  512. capture the whole file ensure that you are at the start of the file (Use 
  513. "MOVETO" if required). 
  514.  
  515. Syntax 
  516.  
  517.    [whitespace]REBUILD [whitespace]["]NewScriptFile["][whitespace]
  518.  
  519. The "NewScriptFile" parameter if supplied is the name of a file to which 
  520. information is to be written. 
  521.  
  522. EXAMPLES 
  523.  
  524.    OPENREAD "XCOPY.EXE"
  525.    REBUILD  "XCOPY.BIN"
  526.    CLOSE
  527.  
  528.  
  529. ΓòÉΓòÉΓòÉ 3.18. RECORD ΓòÉΓòÉΓòÉ
  530.  
  531. RECORD 
  532.  
  533. This command can only be used in interactive mode and is used to record the 
  534. commands you enter, on the theory that you will want to use these later to 
  535. polish up an automated script. 
  536.  
  537. It allows you to experiment to produce the correct result, then with minor 
  538. editing of the produced file (to remove your mistakes) you have a script which 
  539. is very likely to work. 
  540.  
  541. Syntax 
  542.  
  543.    [whitespace]RECORD [whitespace][["]RecordFileName["]][whitespace]
  544.  
  545. The "RecordFileName" parameter if supplied is the name of a file to which 
  546. information is to be written.  If no filename is supplied then recording is 
  547. turned off. 
  548.  
  549. EXAMPLES 
  550.  
  551.    RECORD  "MEMORY.BIN"
  552.    RECORD
  553.  
  554.  
  555. ΓòÉΓòÉΓòÉ 3.19. REXX ΓòÉΓòÉΓòÉ
  556.  
  557. REXX 
  558.  
  559. This command will let you execute any rexx statement.  This is a specialised 
  560. command which you may never have need for. 
  561.  
  562. Syntax 
  563.  
  564.    [whitespace]REXX [whitespace]RexxCommand[whitespace]
  565.  
  566. The "RexxCommand" parameter is any valid rexx command (or commands).  Any 
  567. variables you set will remain until the end of the program or modified. 
  568.  
  569. EXAMPLES 
  570.  
  571.    ;--- Calculator ----------------------------------------------------------------
  572.    rexx   say 40 * 3 + 11
  573.  
  574.    ;--- Output a status message ---------------------------------------------------
  575.    REXX   say 'About to patch the file'
  576.  
  577.    ;--- Perform a simple validation that the "PATH" environment variable exists ---
  578.    rexx   if GetEnv("PATH") = '' then do; call CommandFailure '"PATH" Envvar missing!'; end
  579.  
  580.    ;--- Make sure exactly 256 bytes are written to the file -----------------------
  581.    rexx   StartTable = CurrentOffset();
  582.    WRITE   copies('.', 256);
  583.    rexx   NumberOfBytes = CurrentOffset() - StartTable;
  584.    rexx   if NumberOfBytes <> 256 then do; call CommandFailure 'Wrote ' || NumberOfBytes || ' bytes, expected exactly 256!'; end
  585.  
  586.  
  587. ΓòÉΓòÉΓòÉ 3.20. SYSTEM ΓòÉΓòÉΓòÉ
  588.  
  589. SYSTEM 
  590.  
  591. This command allows you to execute system commands.  The system command does 
  592. not fail if a non-zero return code is returned by the command processor however 
  593. the rexx variable "SystemRc" is set and can be verified with the "REXX" command 
  594. if required. 
  595.  
  596. Syntax 
  597.  
  598.    [whitespace]REXX [whitespace][SystemCommand][whitespace]
  599.  
  600. The "SystemCommand" parameter (if supplied) is anything you could type from an 
  601. operating system command prompt.  If not supplied a command prompt is started 
  602. (use "EXIT" to leave this command prompt). 
  603.  
  604. EXAMPLES 
  605.  
  606.    SYSTEM
  607.    SYSTEM  dir *.exe
  608.  
  609.  
  610. ΓòÉΓòÉΓòÉ 3.21. VERIFY ΓòÉΓòÉΓòÉ
  611.  
  612. VERIFY 
  613.  
  614. This command will VERIFY a number of bytes in the file at the current position. 
  615. The current position is not modified so a subsequent WRITE will overwrite the 
  616. verified bytes. 
  617.  
  618. You may wish a more global file level check, if so have a look at the 
  619. "VERIFYFILE" command. 
  620.  
  621. Syntax 
  622.  
  623.    [whitespace]VERIFY [whitespace]RexStringExpression[whitespace]
  624.  
  625. The "RexStringExpression" is a rexx expression which will be executed.  The 
  626. result should be a string which is to be verified. 
  627.  
  628. EXAMPLES 
  629.  
  630.    MOVETO + x1                            ;;Move forwards 1 decimal
  631.    VERIFY '[K' || '0B00'x                 ;;Verify 4 of the bytes
  632.    WRITE  '0000 0000'x                    ;;Overwrite the 4 verified bytes
  633.  
  634.  
  635. ΓòÉΓòÉΓòÉ 3.22. VERIFYFILE ΓòÉΓòÉΓòÉ
  636.  
  637. VERIFYFILE 
  638.  
  639. This command will verify a files: 
  640.  
  641.        1. Existance 
  642.        2. Length 
  643.        3. CRC32 
  644.  
  645.  If you can't verify the files contents at this level the "VERIFY" command may 
  646.  be more suitable for your needs. 
  647.  
  648.  Syntax 
  649.  
  650.      [whitespace]VERIFYFILE [whitespace]"FileName" [whitespace][FileLength [whitespace][FileCrc32]][whitespace]
  651.  
  652.  The "FileName" parameter specifies the name of a file.  Its expected to exist. 
  653.  This is the only required parameter. 
  654.  
  655.  The "FileLength" parameter specifies the length of the file.  As well as 
  656.  existing it is expected to have this file size.  The length is supplied in 
  657.  decimal. 
  658.  
  659.  The "FileCrc32" parameter specifies the CRC32 of the file.  As well as 
  660.  existing and having the correct length it is expected to have the correct CRC. 
  661.  A CRC is unlikely to be the same if a files contents are not as expected.  The 
  662.  CRC used by this program is the same as that used by PKZIP.  Note that the CRC 
  663.  routine is written in pure rexx and is not that fast so you may not wish to 
  664.  check the CRC or a really large file. The CRC is supplied in exactly 8 
  665.  hexadecimal characters. 
  666.  
  667.  EXAMPLES 
  668.  
  669.  The following demonstrates the 3 different file level verifications that can 
  670.  be performed: 
  671.  
  672.      VerifyFile "L4029.PIC"                 ;;Ensure File exists
  673.      VerifyFile "L4029.PIC" 15              ;;Ensure File exists + correct length (15 decimal)
  674.      VerifyFile "L4029.PIC" 15  B8BD46E4    ;;Ensure File exists + correct length (15 decimal) + CRC32 is correct
  675.  
  676.  
  677. ΓòÉΓòÉΓòÉ 3.23. WRITE ΓòÉΓòÉΓòÉ
  678.  
  679. WRITE 
  680.  
  681. This command will WRITE a number of bytes to the output file to the current 
  682. location.  A subsequent write's characters will be written immediately after 
  683. the previous ones. 
  684.  
  685. Syntax 
  686.  
  687.    [whitespace]WRITE [whitespace]RexStringExpression[whitespace]
  688.  
  689. The "RexStringExpression" is a rexx expression which will be executed.  The 
  690. result should be a string which is to be written to the file. 
  691.  
  692. EXAMPLES 
  693.  
  694.    WRITE  '1B'x || '[K' || '0B00 FF31 02 A0 04 00 00 0000 90'x
  695.    WRITE  copies('*', 10)
  696.    WRITE  '0D0A'x                         ;;Output CR + LF
  697.    WRITE  binary('0100 0001');            ;;Ascii 'A'
  698.  
  699.  
  700. ΓòÉΓòÉΓòÉ 3.24. ? ΓòÉΓòÉΓòÉ
  701.  
  702.  
  703. This command will display the online manual. 
  704.  
  705. Syntax 
  706.  
  707.    [whitespace]? [whitespace][HelpOnWhat][whitespace]
  708.  
  709. The "HelpOnWhat" parameter is optional.  If not specified then the maunal is 
  710. opened at the table of contents, otherwise the manual will be opened at the 
  711. first heading that matches what you typed. 
  712.  
  713. EXAMPLES 
  714.  
  715.    ?
  716.    ?  dump
  717.    ?  write
  718.  
  719.  
  720. ΓòÉΓòÉΓòÉ 4. Procedures ΓòÉΓòÉΓòÉ
  721.  
  722. Procedures 
  723.  
  724. The following Procedures are available to you whenever you execute a rexx 
  725. expression (for example in REXX & WRITE commands).: 
  726.  
  727.          AddCommasToDecimalNumber 
  728.          Binary 
  729.          B2C 
  730.          CommandFailure 
  731.          CurrentOffset 
  732.          EOL 
  733.          GetEnv 
  734.          GotoLabel 
  735.          ReplaceString 
  736.  
  737.  
  738. ΓòÉΓòÉΓòÉ 4.1. AddCommasToDecimalNumber() ΓòÉΓòÉΓòÉ
  739.  
  740. AddCommasToDecimalNumber() 
  741.  
  742. This function takes a single parameter (a decimal integer) and returns the 
  743. number with commas as required. 
  744.  
  745.  
  746. ΓòÉΓòÉΓòÉ 4.2. Binary() ΓòÉΓòÉΓòÉ
  747.  
  748. Binary() 
  749.  
  750. This routine takes a single parameter (a binary string) and returns a string of 
  751. characters that represent the passed string.  Note that "B2C()" is an alias for 
  752. this command. 
  753.  
  754. Sometimes a value is more meaningful in binary.  If using a PPWIZARD front end 
  755. it would also provide the option of programatically building different bit 
  756. strings based on conditions. 
  757.  
  758. EXAMPLES 
  759.  
  760.    WRITE  binary('0100 0001')              ;;Ascii 'A'
  761.    WRITE  binary('0100 0010   0100 0011')  ;;Ascii 'BC'
  762.    WRITE  binary('01000100 01000101')      ;;Ascii 'DE'
  763.    WRITE  binary('0000 0000')              ;;x00
  764.  
  765.  
  766. ΓòÉΓòÉΓòÉ 4.3. CommandFailure() ΓòÉΓòÉΓòÉ
  767.  
  768. CommandFailure() 
  769.  
  770. This routine requires a single parameter (a string to display). The error 
  771. message will be displayed and then clean up processing will take place and the 
  772. program exited with a non-zero return code. 
  773.  
  774. Its major use if in validations such as that shown in the example below. 
  775.  
  776. Do not call exit() directly. 
  777.  
  778. EXAMPLES 
  779.  
  780. ;--- Perform a simple validation that the "PATH" environment variable exists -
  781. rexx  if GetEnv("PATH") = '' then do; call CommandFailure '"PATH" Envvar missing!'; end
  782.  
  783.  
  784. ΓòÉΓòÉΓòÉ 4.4. CurrentOffset() ΓòÉΓòÉΓòÉ
  785.  
  786. CurrentOffset() 
  787.  
  788. This routine takes no parameters and returns the current offset in the file 
  789. ('!' is returned on error).  You must of course only try calling this routine 
  790. when a file is open! 
  791.  
  792. EXAMPLES 
  793.  
  794.    ;--- Make sure exactly 256 bytes are written to the file -----------------------
  795.    rexx   StartTable = CurrentOffset();
  796.    WRITE   copies('.', 256);
  797.    rexx   NumberOfBytes = CurrentOffset() - StartTable;
  798.    rexx   if NumberOfBytes <> 256 then do; call CommandFailure 'Wrote ' || NumberOfBytes || ' bytes, expected exactly 256!'; end
  799.  
  800.  
  801. ΓòÉΓòÉΓòÉ 4.5. EOL() ΓòÉΓòÉΓòÉ
  802.  
  803. EOL() 
  804.  
  805. This routine takes no parameters and returns the character or characters 
  806. required to terminate a text line.  On PC systems it would return a Carriage 
  807. Return followed by a Line Feed.  On Unix systems only a Line Feed would be 
  808. returned. 
  809.  
  810. This routine should be called rather than hardcoding the CR + LF etc to make 
  811. your script platform independant. 
  812.  
  813. EXAMPLES 
  814.  
  815.    WRITE  '0D0A'x                         ;;Output CR + LF (Hardcoded - not recommended)
  816.    WRITE  EOL()                           ;;Same as '0D0A'x on PC systems
  817.  
  818.  
  819. ΓòÉΓòÉΓòÉ 4.6. GetEnv() ΓòÉΓòÉΓòÉ
  820.  
  821. GetEnv() 
  822.  
  823. This routine takes a single parameter (the name of an environment variable) and 
  824. returns its contents. 
  825.  
  826. EXAMPLES 
  827.  
  828.    ;--- Make sure "PATH" exists -------------------------------------
  829.    rexx  if GetEnv("PATH") = '' then do; call CommandFailure '"PATH" Envvar missing!'; end
  830.  
  831.    ;--- Write the contents of the "path" to the file ----------------
  832.    WRITE  GetEnv("PATH");
  833.  
  834.  
  835. ΓòÉΓòÉΓòÉ 4.7. GotoLabel() ΓòÉΓòÉΓòÉ
  836.  
  837. GotoLabel() 
  838.  
  839. This routine takes a single parameter (the name of a label).  The next command 
  840. to be executed will be from the line following the label in the script file. 
  841.  
  842. The command would be useful in "REXX" commands to make inteligent decisions. 
  843.  
  844.  
  845. ΓòÉΓòÉΓòÉ 4.8. ReplaceString() ΓòÉΓòÉΓòÉ
  846.  
  847. ReplaceString() 
  848.  
  849. This function will convert all occurances of a substring as you specify. 
  850.  
  851. The function takes 4 parameters although only the first 3 are required, the 
  852. parameters are: 
  853.  
  854.        1. The string which is to be translated. 
  855.  
  856.        2. The FROM string. 
  857.  
  858.        3. The TO string. 
  859.  
  860.        4. An optional parameter which is the name of a variable that should be 
  861.           updated with the number of replacements that occurred.  You should 
  862.           preset this variable to 0 if required. 
  863.  
  864.  
  865. ΓòÉΓòÉΓòÉ 5. Example Scripts ΓòÉΓòÉΓòÉ
  866.  
  867. Example Scripts 
  868.  
  869.          EBCDIC.BIN 
  870.          EXAMPLE.BIN 
  871.          PATCHALL.BIN 
  872.          PPWIZARD.BIN 
  873.  
  874.  
  875. ΓòÉΓòÉΓòÉ 5.1. EBCDIC.BIN ΓòÉΓòÉΓòÉ
  876.  
  877. EBCDIC.BIN 
  878.  
  879. This script creates "EBCDIC.TBL" which can then be loaded via a "DUMPCHAR" 
  880. command so that subsequent "DUMP" commands display the characters in EBCDIC. 
  881.  
  882. ;----------------------------------------------------------------------------
  883. ;------------------------------[ EBCDIC.BIN ]--------------------------------
  884. ;----------------------------------------------------------------------------
  885. ;
  886. ; Used to create "EBCDIC.TBL" which can then be loaded via the "DUMPCHAR"
  887. ; command to control the characters displayed by the "DUMP" command.
  888. ;
  889. ;----------------------------------------------------------------------------
  890.  
  891.  
  892. ;*** $Header:   E:/DB/PVCS.IT/OS2/BINTOOL/EBCDIC.BIV   1.2   11 Jun 1998 18:48:10   Dennis_Bareis  $
  893.  
  894.  
  895. ;--- Open a NEW file --------------------------------------------------------
  896. OpenNew  "EBCDIC.TBL"
  897.  
  898. ;--- Output header ----------------------------------------------------------
  899. write    'DUMPCHAR'
  900. write    '|'
  901. write    'To EBCDIC'
  902. write    '|'
  903.  
  904. ;--- Remember Current Offset ------------------------------------------------
  905. rexx   StartTable = CurrentOffset();
  906.  
  907. ;--- Output 256 char translation set ----------------------------------------
  908. WRITE   '................................'
  909. WRITE   '................................'
  910. WRITE   ' '
  911. WRITE   '...........'
  912. WRITE   '<(+.&'
  913. WRITE   '.........'
  914. WRITE   '!$*);.-/'
  915. WRITE   '........'
  916. WRITE   '|,%_>?'
  917. WRITE   '..........'
  918. WRITE   ":#@'"
  919. WRITE   '="'
  920. WRITE   '.'
  921. WRITE   'abcdefghi'
  922. WRITE   '.{..+..'
  923. WRITE   'jklmnopqr'
  924. WRITE   '.}.....~'
  925. WRITE   'stuvwxyz'
  926. WRITE   '...'
  927. WRITE   '['
  928. WRITE   '...............'
  929. WRITE   ']'
  930. WRITE   '...'
  931. WRITE   'ABCDEFGHI'
  932. WRITE   '.......'
  933. WRITE   'JKLMNOPQR'
  934. WRITE   '......\.'
  935. WRITE   'STUVWXYZ'
  936. WRITE   '......'
  937. WRITE   '0123456789'
  938. WRITE   '......'
  939.  
  940. ;--- Verify that exactly 256 bytes were written -----------------------------
  941. rexx   NumberOfBytes = CurrentOffset() - StartTable;
  942. rexx   if NumberOfBytes <> 256 then do; call CommandFailure 'EBCDIC character table has ' || NumberOfBytes || ' bytes, expected exactly 256!'; end
  943.  
  944. ;--- Close the file ---------------------------------------------------------
  945. close
  946.  
  947.  
  948. ΓòÉΓòÉΓòÉ 5.2. EXAMPLE.BIN ΓòÉΓòÉΓòÉ
  949.  
  950. EXAMPLE.BIN 
  951.  
  952. This is a simple example with no real purpose. 
  953.  
  954. ;----------------------------------------------------------------------------
  955. ;------------------------------[ EXAMPLE.BIN ]-------------------------------
  956. ;----------------------------------------------------------------------------
  957. ;
  958. ;  This is an example file which shows most of the commands available.
  959. ;  It is not a realistic example but it does function.
  960. ;
  961. ;  Also have a look at my PPWIZARD tool.  If this was run as a step prior
  962. ;  to this one then you could have much more powerful commands such as
  963. ;  #if, #evaluate, #define.  You could define macros with parameters and
  964. ;  conditional inclusion.  These features were left out of this tool on the
  965. ;  assumption that you'd use PPWIZARD. In a line below the contents of the
  966. ;  "PATH" evironment variable is written, no validation of its existance
  967. ;  is or can be performed without using PPWIZARD.
  968. ;
  969. ;
  970. ;  This tool:
  971. ;
  972. ;         (a) Easily verify file contents then perform patches.
  973. ;         (b) Run difference & source management programs over the source.
  974. ;         (c) Comment changes.
  975. ;         (d) Allows you to binary edit files with a text editor!
  976. ;
  977. ;
  978. ;  To Execute this file:
  979. ;
  980. ;         BINTOOL.CMD EXAMPLE.BIN
  981. ;
  982. ;
  983. ;  To try command interactively (Type "QUIT" to exit):
  984. ;
  985. ;         BINTOOL.CMD ?
  986. ;
  987. ;----------------------------------------------------------------------------
  988.  
  989. ;*** $Header:   E:/DB/PVCS.IT/OS2/BINTOOL/EXAMPLE.BIV   1.8   11 Jun 1998 18:48:10   Dennis_Bareis  $
  990.  
  991.  
  992. ;--- Open a NEW file --------------------------------------------------------
  993. OPENNEW  L4029.PIC
  994.  
  995. ;--- Write out the Lexmark 4029 Initialization Codes ------------------------
  996. WRITE   '1B'x || '[K' || '0B00 FF31 02 A0 04 00 00 0000 90'x
  997.  
  998. ;--- Close the file ---------------------------------------------------------
  999. CLOSE
  1000.  
  1001.  
  1002. ;--- Open a binary file -----------------------------------------------------
  1003. OPENREAD  'L4029.PIC'
  1004.  
  1005. ;--- DUMP "BINTOOL" Commands required to rebuild this file ------------------
  1006. REBUILD   L4029.TXT
  1007.  
  1008. ;--- Close the file ---------------------------------------------------------
  1009. CLOSE
  1010.  
  1011.  
  1012. ;--- Perform some "FILE LEVEL" verifications before patching ----------------
  1013. VerifyFile "L4029.PIC"                 ;;Ensure File exists
  1014. VerifyFile "L4029.PIC" 15              ;;Ensure File exists + correct length (15 decimal)
  1015. VerifyFile "L4029.PIC" 15  B8BD46E4    ;;Ensure File exists + correct length (15 decimal) + CRC32 is correct
  1016.  
  1017.  
  1018. ;--- Perform a simple validation that the "PATH" environment variable exists -
  1019. rexx  if GetEnv("PATH") = '' then do; call CommandFailure 'ERROR: "PATH" Envvar missing!'; end
  1020.  
  1021. ;--- Open  file (don't delete it!) ------------------------------------------
  1022. OPEN  "L4029.PIC"
  1023.  
  1024. ;--- Move around a bit ------------------------------------------------------
  1025. ;DUMPCHAR EBCDIC                       ;;Dump character information in EBCDIC (used EBCDIC.TBL)
  1026. DUMP                                   ;;Dump first part of file
  1027. MOVETO START
  1028. MOVETO + x1                            ;;Move forwards 1 decimal
  1029. VERIFY '[K' || '0B00'x                 ;;Verify 4 of the bytes
  1030. MOVETO + xA                            ;;Move backwards 1 decimal
  1031. MOVETO - $2                            ;;Move backwards 2 decimal
  1032. MOVETO + 5                             ;;Move forwards 5 HEX
  1033. DECIMAL                                ;;Default now decimal
  1034. MOVETO - 1
  1035. MOVETO - $1
  1036. HEXADECIMAL                            ;;Default now hex (again)
  1037. MoveTo B                               ;;Move to offset B hex (0 = 1st byte)
  1038. MOVETO END
  1039.  
  1040.  
  1041. ;--- Jump forwards a bit (small!) -------------------------------------------
  1042. goto NextLine
  1043. :NextLine
  1044.  
  1045. ;--- Write some stuff to end ------------------------------------------------
  1046. WRITE  '0D0A'x                         ;;Output CR + LF
  1047. WRITE  copies('~', 70)
  1048. WRITE  EOL()                           ;;Same as '0D0A'x on PC systems
  1049. WRITE  GetEnv("PATH");
  1050. WRITE  EOL()
  1051. WRITE  binary('0100 0001')              ;;Ascii 'A'
  1052. WRITE  binary('0100 0010   0100 0011')  ;;Ascii 'BC'
  1053. WRITE  binary('01000100 01000101')      ;;Ascii 'DE'
  1054.  
  1055. ;--- Write the current offset to the file -----------------------------------
  1056. write  CurrentOffset();
  1057.  
  1058. ;--- Close the file ---------------------------------------------------------
  1059. CLOSE
  1060.  
  1061.  
  1062. ;--- Handy Commands in INTERACTIVE Command ----------------------------------
  1063. ;QUIT                                  ;;Exit Interactive mode
  1064. ;SYSTEM dir                            ;;Run the DIR command
  1065. ;SYSTEM                                ;;Go to OS/2 command prompt
  1066. ;RECORD  "1.LOG"                       ;;Remember commands and logs some results as comments
  1067. ;RECORD                                ;;Turn off recording.
  1068.  
  1069.  
  1070. ΓòÉΓòÉΓòÉ 5.3. PATCHALL.BIN ΓòÉΓòÉΓòÉ
  1071.  
  1072. PATCHALL.BIN 
  1073.  
  1074. ;----------------------------------------------------------------------------
  1075. ;------------------------------[ EBCDIC.BIN ]--------------------------------
  1076. ;----------------------------------------------------------------------------
  1077. ;
  1078. ; Simplistic example where everythings hardcoded.  Main things demonstrated
  1079. ; are labels, the GOTO command and ONERROR command.
  1080. ;
  1081. ; Note that the only command handled by an error handler is the
  1082. ; FIND command.  If any other command (such as the WRITE command) fails the
  1083. ; program will fatally terminate.  If this was not desired an
  1084. ; ONERROR command would need to be placed at each line which might fail.
  1085. ;
  1086. ;----------------------------------------------------------------------------
  1087.  
  1088. ;*** $Header:   E:/DB/PVCS.IT/OS2/BINTOOL/PATCHALL.BIV   1.0   11 Jun 1998 18:48:10   Dennis_Bareis  $
  1089.  
  1090.  
  1091.  
  1092. ;--- Open the file to be patched --------------------------------------------
  1093. OPEN  "AFTER.EXE"
  1094.  
  1095. ;--- Patch all Nulls --------------------------------------------------------
  1096. rexx   NullCounter = 0
  1097. :PatchLoop
  1098.  
  1099.    ;--- Look for null bytes -------------------------------------------------
  1100.    OnError  NoMoreNulls
  1101.    FINDCS   "00"x
  1102.  
  1103.    ;--- Replace Null byte with "FF" hex -------------------------------------
  1104.    WRITE    'FF';
  1105.    rexx     NullCounter = NullCounter + 1
  1106. goto PatchLoop
  1107. :NoMoreNulls
  1108. rexx   say AddCommasToDecimalNumber(NullCounter) || ' null byte(s) converted.'
  1109.  
  1110. ;--- Close the file ---------------------------------------------------------
  1111. close
  1112.  
  1113.  
  1114. ΓòÉΓòÉΓòÉ 5.4. PPWIZARD.BIN ΓòÉΓòÉΓòÉ
  1115.  
  1116. PBINTOOL.CMD 
  1117.  
  1118. This batch file could be used to process "PPWIZARD.BIN": 
  1119.  
  1120. /**********************************/
  1121. /* BINTOOL.CMD with PPWIZARD STEP */
  1122. /**********************************/
  1123.  
  1124. /*--- Initialization --------------------------------------------------------*/
  1125. address cmd '@echo off'
  1126. DebugSwitches = '';
  1127. /*DebugSwitches = '/debug';*/
  1128.  
  1129. /*--- Check thate the user supplied a filename and that it exists -----------*/
  1130. UsersScriptFile = strip(arg(1));
  1131. if UsersScriptFile = '' then
  1132.    Abort("You did not supply the name of a script file!");
  1133. if stream(UsersScriptFile, 'c', 'query exists') = '' then
  1134.    Abort('The file "' || UsersScriptFile || '" does not exist!');
  1135.  
  1136. /*--- Get name of temp file (not best way but portable) ---------------------*/
  1137. TmpFile = GetEnv("TMP") || '\PBT' || right(time('S'), 5, '0') || ".TMP";
  1138.  
  1139. /*--- Run the PPWIZARD step -------------------------------------------------*/
  1140. address cmd 'cmd.exe /c PPWIZARD.CMD ' || UsersScriptFile || ' /crlf /output:' || TmpFile || ' ' || DebugSwitches;
  1141. if Rc <> 0 then
  1142.    Abort("PPWIZARD step failed (Rc = " || Rc || ')');
  1143.  
  1144. /*--- Run the BINTOOL step --------------------------------------------------*/
  1145. address cmd 'cmd.exe /c BINTOOL.CMD ' || TmpFile;
  1146. if Rc <> 0 then
  1147.    Abort("BINTOOL step failed (Rc = " || Rc || ')');
  1148.  
  1149. /*--- Command worked so delete the temporary file ---------------------------*/
  1150. address cmd 'del ' || TmpFile || ' >nul 2>&1';
  1151.  
  1152. /*--- Thats all Folks -------------------------------------------------------*/
  1153. exit(0);
  1154.  
  1155.  
  1156. /*===========================================================================*/
  1157. Abort:
  1158. /*===========================================================================*/
  1159.    CallersLine = SIGL;
  1160.    say arg(1) || '';
  1161.    exit(CallersLine);
  1162.  
  1163.  
  1164. /*===========================================================================*/
  1165. GetEnv:
  1166. /*                                                                           */
  1167. /* arg(1) : Name of environment variable.                                    */
  1168. /*===========================================================================*/
  1169.    return( value(arg(1),,'OS2ENVIRONMENT') );
  1170.  
  1171. PPWIZARD.BIN 
  1172.  
  1173. ;----------------------------------------------------------------------------
  1174. ;------------------------------[ PPWIZARD.BIN ]------------------------------
  1175. ;----------------------------------------------------------------------------
  1176. ;
  1177. ; Simplistic example of using PPWIZARD.
  1178. ;
  1179. ; Note that it would be smarter to validate both addresses first and then
  1180. ; write the new value.  As it currently stands this example could fail
  1181. ; at the second validation after we've already patched the file.
  1182. ;
  1183. ; It would be smarter yet to be woring on a copy and only update the original
  1184. ; as the last step (maybe using "SYSTEM copy ......").
  1185. ;
  1186. ;----------------------------------------------------------------------------
  1187.  
  1188.  
  1189. ;*** $Header:   E:/DB/PVCS.IT/OS2/BINTOOL/PPWIZARD.BIV   1.0   11 Jun 1998 18:48:12   Dennis_Bareis  $
  1190.  
  1191. ;--- Set up some constants --------------------------------------------------
  1192. #define  FileToPatch       "XYZ.CMD"
  1193. #define  ExpectToFind      "97.123"
  1194. #define  FirstPosn         x1001
  1195. #define  SecondPosn        x3415
  1196.  
  1197. ;--- Create YY.DDD Version # (example "98.107") -----------------------------
  1198. #evaluate YYDDD    ~substr(date('Sorted'),3,2) || '.' || right(date('Days'), 3, '0')~
  1199.  
  1200.  
  1201.  
  1202. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1203. ;;;;;;;;;;;;;;;;;;;;;;;;;[ One Way ];;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1204. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1205.  
  1206.  
  1207.  
  1208. ;--- Open the file and update the version numbers ---------------------------
  1209. Open   <$FileToPatch>
  1210. MoveTo <$FirstPosn>
  1211. verify <$ExpectToFind>
  1212. write  <$YYDDD>
  1213. MoveTo <$SecondPosn>
  1214. verify <$ExpectToFind>
  1215. write  <$YYDDD>
  1216. close
  1217.  
  1218.  
  1219.  
  1220. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1221. ;;;;;;;;;;;;;;;;;;;;;;;;;[ Another Way ];;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1222. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1223.  
  1224.  
  1225. ;--- Create macro to perform a patch (takes OFFSET as parameter) ------------
  1226. #define PatchVer                                       \
  1227.         MoveTo  {$Offset}<?NewLine>                    \
  1228.         verify  <$ExpectToFind><?NewLine>              \
  1229.         write   <$YYDDD><?NewLine>
  1230.  
  1231. ;--- Repeat the above in a slightly better way ------------------------------
  1232. Open   <$FileToPatch>
  1233. <$PatchVer Offset='<$FirstPosn>'>
  1234. <$PatchVer Offset='<$SecondPosn>'>
  1235. close
  1236.