.; ^RATFOR LIBRARY DESCRIPTION REV 0 30 MAR 77 .; Edited to comments by EOM -- PDM 77-6-2 .; Edited for standard RUNOFF -- RLM AUG/78 .; Edited for new DEFN and removal of TIMER -- SML 4/80 .TAB STOPS 9 17 25 33 .SPACING 1 .PAPER SIZE 60,70 .LEFT MARGIN 5 .TITLE ###############^^A-RCB-0091-2 #####THE RATFOR LIBRARY\\ THIS PAGE INTENTIONALLY BLANK .NUMBER 1 .PAGE .CENTER ^^INTRODUCTION\\ .TESTPAGE 3 .PARAGRAPH ^THE ^^RATFOR\\ LIBRARY IS A SET OF ROUTINES AVAILABLE TO ^^RATFOR\\ AND ^^FORTRAN\\ PROGRAMMERS. ^MOST OF THE ROUTINES ARE WRITTEN IN ^^RATFOR\\. ^THERE ARE ROUTINES FOR STRING MANIPULATION, ^^MCR\\ LINE HANDLING, CHARACTER ^^I/O\\, AND TIMING. .SKIP .HL 1 ^^STANDARD DEFINITIONS\\ .INDEX ^STANDARD ^DEFINITIONS .PARAGRAPH ^ALL ROUTINES IN THE ^^RATFOR\\ LIBRARY USE THE SYMBOLIC NAMES DEFINED LIKE THIS:^^ .NOFILL .NOJUSTIFY .SKIP 2 .LEFT MARGIN 15 #DEFN RATLIB STANDARD DEFINITIONS # # THESE DEFINITIONS ARE CONSISTANT WITH THOSE OF THE RATFOR LIBRARY # (RATLIB) AND THE SYKES RATFOR PREPROCESSOR # # DEFINE (ALPHA=-4) DEFINE (ALPHABETIC=-4) DEFINE (ARB=10000) DEFINE (BAD=-1) DEFINE (BINARY=2) DEFINE (BLANK=32) DEFINE (CHAR=LOGICAL*1) DEFINE (CHARACTER=LOGICAL*1) DEFINE (DECIMAL=10) DEFINE (DIGIT=-20) DEFINE (DUMMYSIZE=1) DEFINE (ENDBLOCK=]) DEFINE (ENDELSE=]) DEFINE (ENDFOR=]) DEFINE (ENDIF=]) DEFINE (ENDREPEAT=]) DEFINE (ENDWHILE=]) DEFINE (EOF=-3) DEFINE (EOS=0) #END-OF-STRING !!!! DEFINE (ESCAPECHAR=64) DEFINE (HEX=16) DEFINE (HUGE=32767) DEFINE (LETTER=-30) DEFINE (MAXDIGITS=18) DEFINE (MAXLINE=132) DEFINE (NEWLINE=10) DEFINE (NO=0) DEFINE (NUMERIC=-3) DEFINE (OCTAL=8) DEFINE (PAXPAT=81) DEFINE (PRINTER=6) DEFINE (STDIN=3) DEFINE (STDLUNIN=3) DEFINE (STDLUNOUT=4) DEFINE (STDLUNTI=5) DEFINE (STDOUT=4) DEFINE (TAB=9) DEFINE (TYPER=5) DEFINE (YES=1) MACRO (DECREMENT,$=$-1) MACRO (INCREMENT,$=$+1) .LEFT MARGIN 5 .SKIP .FILL .JUSTIFY .TEST PAGE 5 \\^THESE ^^DEFINE\\ STATEMENTS CAN BE FOUND IN THE FILE ^^DEFN.RAT\\ ON THE DISTRIBUTION MEDIUM. H\\ERE IS AN EXPLANATION OF SOME OF THESE NAMES: .SKIP .LEFT MARGIN 15 ^^YES, NO, EOF:\\##^THERE ARE NO ^^LOGICAL\\ FUNCTIONS IN THE ^^RATFOR\\ LIBRARY. ^INSTEAD, ^^INTEGER\\ FUNCTIONS, THAT CAN RETURN ONE OF THESE THREE VALUES, ARE USED. ^SUCH A FUNCTION RETURNS ^^YES\\ WHEN SUCCESSFUL, ^^NO\\ WHEN THE INPUT IS INVALID, AND ^^EOF\\ WHEN THERE IS NO MORE INPUT. .SKIP ^^CHAR, EOS\\:## ^MANY ^^RATFOR\\ ROUTINES MANIPULATE STRINGS. ^ALL STRING VARIABLES ARE ^^CHAR\\ VECTORS OR SCALARS. ^EACH STRING HAS A BYTE EQUAL TO ^^EOS\\ PLACED AT THE END AS A MARKER. ^IN ^^RSX\\ AND ^^F4P\\, ZERO BYTES ARE USED TO MARK THE END OF STRINGS AND CHARACTER CONSTANTS, SO ^^EOS\\ IS DEFINED TO BE 0. ^THIS MEANS THAT A CHARACTER CONSTANT CAN BE USED AS AN ARGUMENT FOR ANY ROUTINE THAT EXPECTS A STRING ARGUMENT. .SKIP ^^NEWLINE\\:##^RETURNED BY THE ROUTINE ^^GETC\\ AT THE END OF EACH RECORD. .SKIP ^^ESCAPECHAR\\:##^USED BY THE ROUTINE ^^GETARG\\. .SKIP ^^NUMERIC, ALPHABETIC\\:##^RETURNED BY THE CHARACTER-TYPING ROUTINE ^^TYPE.\\ .SKIP ^^ARB\\:##^USED AS THE DIMENSION OF PARAMETERS WHEN THIS DIMENSION IS ARBITRARY. .SKIP ^^STD^L^U^NTI, STD^L^U^NIN, STD^L^U^NOUT\\:##^THESE STANDARD LOGICAL UNIT NUMBERS (^^^L^U^N\\S) ARE USED BY THE ROUTINES ^^SETOTL\\ AND ^^SETFLT\\. .LEFT MARGIN 5 .TESTPAGE 15 .PARAGRAPH ^SOME OF THE SYMBOLS HAVE BEEN DEFINED FOR IMPROVED PROGRAM READABILITY. ^FOR EXAMPLE, ^^ENDIF\\ AND ^^ENDELSE\\ ARE USED INSTEAD OF THE END OF BLOCK CHARACTER ']' TO COMPLEMENT ^^IF\\ AND ^^ELSE\\. .FILL .JUSTIFY .TEST PAGE 5 .PARAGRAPH ^IN GENERAL, NO ASSUMPTIONS SHOULD BE MADE ABOUT THE VALUES OF THESE SYMBOLIC CONSTANTS. ^THEY SHOULD ONLY BE USED IN TESTS OF EQUALITY. ^HOWEVER, THESE ASSUMPTIONS ARE PERMITTED: .SKIP 2 .LEFT MARGIN 15 1) ^THE VALUES OF ^^EOF, NEWLINE, ALPHABETIC, \\AND^^ NUMERIC\\ CAN BE DISTINGUISHED FROM ANY ^^ASCII\\ CHARACTER. ^A ROUTINE CAN RETURN AN ^^ASCII\\ CHARACTER OR ONE OF THESE AND THE TWO CASES CAN BE DISTINGUISHED. .SKIP 2) ^THE VALUE OF ^^EOF\\ IS A NEGATIVE INTEGER. ^A ROUTINE CAN RETURN A LINE LENGTH OR ^^EOF\\ UNAMBIGUOUSLY. .LEFT MARGIN 5 .SKIP 2 .HL 1 ^^STRING MANIPULATION ROUTINES\\ .INDEX ^STRING ^MANIPULATION ROUTINES .TESTPAGE 3 .PARAGRAPH ^FOLLOWING IS A DESCRIPTION OF THE STRING MANIPULATION ROUTINES. ^RECALL THAT STRINGS ARE STORED IN ^^CHAR\\ VECTORS WITH A BYTE, EQUAL TO ^^EOS\\, AT THE END AS A MARKER. .SKIP 2 .HL 2 ^EQUAL\\ .INDEX ^^EQUAL\\ .SKIP ^^INTEGER FUNCTION EQUAL(S1,S2)\\ .SKIP .TESTPAGE 3 .PARAGRAPH ^^EQUAL\\ IS CALLED WITH TWO STRING ARGUMENTS (^^CHAR\\ VECTORS). ^IT RETURNS ^^YES\\ IF THEY COMPARE AS EQUAL, AND ^^NO\\ OTHERWISE. ^THE STRINGS MUST BE OF THE SAME LENGTH AND MATCH AT EACH CHARACTER POSITION TO BE CONSIDERED EQUAL. ^^EQUAL\\ MUST BE DECLARED TO BE ^^INTEGER\\ IN THE CALLING PROGRAM. .TEST PAGE 5 .LEFT MARGIN 15 .NOFILL .NOJUSTIFY .SKIP ^EXAMPLES: .SKIP ^^ EQUAL('ABC','ABC') returns YES EQUAL('ABC','ABCD') returns NO EQUAL('ABC','abc') returns NO\\ .LEFT MARGIN 5 .FILL .JUSTIFY .TEST PAGE 5 .SKIP 2 .HL 2 ^^LENGTH .INDEX LENGTH\\ .SKIP ^^INTEGER FUNCTION LENGTH(STR) .SKIP .PARAGRAPH ^^LENGTH\\ RETURNS THE NUMBER OF CHARACTERS IN ITS STRING ARGUMENT. ^THE ^^EOS\\ MARKER IS NOT COUNTED IN THIS LENGTH. ^^LENGTH\\ SHOULD BE DECLARED TO BE ^^INTEGER\\ IN THE CALLING PROGRAM. .TEST PAGE 5 .SKIP .NOFILL .NOJUSTIFY .LEFT MARGIN 15 ^EXAMPLES: .SKIP ^^ LENGTH('A') returns 1 LENGTH('ABCdefH.') returns 8\\ .FILL .JUSTIFY .LEFT MARGIN 5 .SKIP 2 .HL 2 ^^SCOPY\\ .INDEX ^^SCOPY .SKIP ^^SUBROUTINE SCOPY(FROM,START1,TO,START2,MAX) .SKIP .PARAGRAPH ^^SCOPY\\ COPIES THE STRING ^^FROM\\ STARTING AT POSITION ^^START1\\ TO THE STRING ^^TO\\ STARTING AT POSITION ^^START2\\. ^NO MORE THAN ^^MAX-1\\ CHARACTERS WILL BE MOVED. (^^MAX-1\\ IS USED TO LEAVE ROOM FOR AN ^^EOS\\.) ^^FROM\\ AND ^^TO\\ MUST BE ^^CHAR\\ VECTORS; ^^START1, START2, \\AND ^^MAX\\ MUST BE ^^INTEGER.\\ ^AN ^^EOS\\ MARKER IS ALWAYS PLACED AT THE END OF ^^TO\\. .TEST PAGE 13 .SKIP .LEFT MARGIN 15 .NOFILL .NOJUSTIFY ^EXAMPLES: .SKIP ^^CHAR STR(15) INTEGER LENGTH,I STR(1)='*' CALL SCOPY('ABRACADABRA',1,STR,2,14) WRITE(5,10) (STR(I),I=1,LENGTH(STR)) 10 FORMAT(1X,15A1) .SKIP \\WILL OUTPUT .SKIP *^^ABRACADABRA\\ .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 5 .SKIP 2 .HL 2 ^^TYPE\\ .INDEX ^^TYPE .SKIP .PARAGRAPH \\^^TYPE\\ EXAMINES ITS ^^CHAR\\ ARGUMENT AND RETURNS ^^ALPHABETIC\\ IF THE CHARACTER IS AN UPPER OR LOWER CASE LETTER, ^^NUMERIC\\ IF THE CHARACTER IS ANY DIGIT, AND THE CHARACTER ^^C\\ ITSELF OTHERWISE. ^RECALL THAT ^^ALPHABETIC\\ AND ^^NUMERIC\\ ARE SYMBOLIC CONSTANTS. ^SINCE THESE TWO CONSTANTS ARE DISTINGUISHABLE FROM ANY ^^ASCII\\ CHARACTER, THE SEQUENCE .SKIP .LEFT MARGIN 15 ^^TYPE(C)==C\\ .SKIP .LEFT MARGIN 5 WILL BE ^^.TRUE.#\\IF AND ONLY IF ^C IS A NON-ALPHANUMERIC (NEITHER A LETTER NOR A DIGIT). ^THIS IS A COMMON IDIOM USED TO CHECK FOR SPECIAL CHARACTERS. ^BOTH ^^TYPE\\ AND ^C MUST BE DECLARED TO BE ^^CHAR\\ IN THE CALLING PROGRAM. .LEFT MARGIN 15 .NOFILL .NOJUSTIFY .TEST PAGE 6 .SKIP ^EXAMPLES: .SKIP ^^ TYPE('A') returns ALPHABETIC TYPE('a') returns ALPHABETIC TYPE('0') returns NUMERIC TYPE('*') returns '*' TYPE('[') returns '['\\ .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 5 .HL 2 ^^CTOI .INDEX ^^CTOI .SKIP ^^INTEGER FUNCTION CTOI(IN,I,BASE)\\ .SKIP .PARAGRAPH ^^CTOI\\ CONVERTS A ^^CHAR\\ STRING STARTING AT POSITION ^I IN ^^IN\\ TO A BASE ^^BASE\\ INTEGER AND RETURNS THIS INTEGER. ^IF ^^IN(I) \\ IS NOT A DIGIT, THE FUNCTION RETURNS 0. ^OTHERWISE, ^I IS ADVANCED TO THE FIRST NON-DIGIT AND A BASE ^^BASE\\ INTEGER IS BUILT ALONG THE WAY. ^^CTOI, BASE, \\AND ^I MUST BE DECLARED TO BE ^^INTEGER\\ IN THE CALLING PROGRAM; ^^IN\\ MUST BE A ^^CHAR\\ VECTOR WITH AN ^^EOS\\ AT THE END. ^^BASE\\ MAY RANGE FROM 2 TO 10. .TESTPAGE 3 .PARAGRAPH ^NOTE WELL: ^THIS FUNCTION HAS SIDE EFFECTS. ^THE VALUE OF ^I IS CHANGED. ^A CONSTANT MUST NOT BE USED AS THIS ARGUMENT; IF A VARIABLE IS USED, IT MUST BE SET TO THE PROPER VALUE BEFORE ^^CTOI\\ IS CALLED. ^OF COURSE, IF WE WANT TO SCAN A STRING AND PICK OUT ALL THE DELIMITED INTEGERS, THE SIDE EFFECT IS EXACTLY WHAT WE WANT. .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .TEST PAGE 6 .SKIP ^EXAMPLES: .SKIP ^^ CTOI('01234',I,10) returns 1234 (BASE 10) AND ^I == 6 CTOI('12,34,56',I,10) returns 12 (BASE 10) AND ^I == 3 CTOI('12,34,56',I,8) returns 10 (BASE 10) AND ^I == 3 CTOI('1100011,111',I,2) returns 99 (BASE 10) AND ^I == 7\\ .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 6 .SKIP 2 .HL 2 ^^CHEXTI\\ .INDEX ^^CHEXTI .SKIP ^^INTEGER FUNCTION CHEXTI(IN,I,BASE)\\ .SKIP .PARAGRAPH ^^CHEXTI\\ IS THE SAME AS THE ^^CTOI\\ FUNCTION DESCRIBED ABOVE WITH THE EXCEPTION THAT ^^BASE\\ MAY RANGE FROM 2 TO 16. THEREFORE, THE LETTERS ^A-^Z MAY BE LEGAL DIGITS WHEN ^^BASE\\ RANGES FROM 11 TO 16. .TEST PAGE 6 .SKIP 2 .HL 2 ^^ ITOC .INDEX ^^ITOC .SKIP ^^INTEGER FUNCTION ITOC(I,TO,BASE)\\ .SKIP .PARAGRAPH ^^ITOC\\ CONVERTS AN INTEGER ^I TO A ^^CHAR\\ STRING ^^TO\\ OF BASE ^^BASE\\, AND RETURNS THE SIZE OF ^^TO\\. .TEST PAGE 3 .PARAGRAPH ^IF ^^BASE\\ IS LESS THAN 2 OR GREATER THAN 16., ^^ITOC\\ WILL MAKE ^T^O A NULL STRING AND RETURN 0. .TEST PAGE 5 ^EXAMPLE: .SKIP .NOFILL .NOJUSTIFY .LEFT MARGIN 15 ^^ITOC(10,STRING,16) R\\ETURNS 1 AND '^A' IN ^^STRING. .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 6 .SKIP 2 .HL 2 ^^INDEX .INDEX ^^INDEX .SKIP ^^INTEGER FUNCTION INDEX(STR,C) .SKIP .PARAGRAPH ^^INDEX\\ SEARCHES THE STRING ^^STR\\ FOR THE CHARACTER ^C. ^IF IT IS FOUND, THE INDEX (SUBSCRIPT) OF ^C IN THE STRING IS RETURNED. ^IF IT IS NOT FOUND, 0 IS RETURNED. ^^INDEX\\ MUST BE DECLARED TO BE ^^INTEGER\\ AND ^^C\\ AND ^^STR\\ MUST BE ^^CHAR\\ IN THE CALLING PROGRAM. .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP ^EXAMPLES: .SKIP ^^ INDEX('ABCDE','A') returns 1 INDEX('ABCDE','a') returns 0 INDEX('AABBCCDDEE','E') returns 9\\ .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 10 .SKIP 2 .HL 2 ^^BRAKE .INDEX ^^BRAKE .SKIP ^^INTEGER FUNCTION BRAKE(S1,S2,S3) .SKIP .PARAGRAPH ^^BRAKE\\ IS SIMILAR TO THE ^^SNOBOL\\ FUNCTION ^^BREAK\\ AND IS SPELLED DIFFERENTLY BECAUSE ^^BREAK\\ IS A ^^RATFOR\\ RESERVED WORD. .TEST PAGE 6 .PARAGRAPH ^^BRAKE\\ WILL ELIMINATE ALL CHARACTERS IN ^S1 STARTING FROM ^S1(1) THAT ARE ^N^O^T INCLUDED IN ^S2, UP TO THE FIRST MATCH. ^THE RESULT IS THAT ^S1 IS SHORTENED BY THE BROKEN OVER CHARACTERS, AND ^S3 CONTAINS THE CHARACTERS THAT WERE REMOVED FROM ^S1. ^A SUCCESFUL CALL WILL RETURN THE NUMBER OF CHARACTERS REMAINING IN ^S1. .TEST PAGE 6 .PARAGRAPH ^^BRAKE\\ WILL FAIL IF NO CHARACTERS IN ^S1 ARE BREAK CHARACTERS. ^THE FUNCTION WILL RETURN -1 AND PLACE ^^EOS\\ IN ^S3(1). ^^BRAKE\\ WILL ALSO FAIL IF THE FIRST CHARACTER IN ^S1 IS A BREAK CHARACTER. ^THE FUNCTION WILL RETURN 0 AND PLACE ^^EOS\\ IN ^S3. .TEST PAGE 4 .PARAGRAPH ^^BRAKE\\ MUST BE DEFINED ^^INTEGER\\ AND THE PARAMETERS DEFINED ^^CHAR\\ EXCEPT THAT ^S2 MAY BE A LITERAL STRING. .TEST PAGE 6 .SKIP 2 .HL 2 ^^SPAN .INDEX ^^SPAN .SKIP ^^INTEGER FUNCTION SPAN(S1,S2,S3) .SKIP .PARAGRAPH ^^SPAN\\ IS SIMILAR TO THE ^^SNOBOL\\ FUNCTION OF THE SAME NAME. .PARAGRAPH ^^SPAN\\ REMOVES FROM ^S1 THE LONGEST STRING THAT SOLELY CONSISTS OF CHARACTERS DEFINED IN STRING ^S2 AND PLACES THEM IN ^S3. ^THE RESULT IS THAT ^S1 BECOMES A NEW STRING WITH THE SPANNED CHARACTER(S) REMOVED, AND ^S3 BECOMES A STRING THAT CONTAINS THE ONLY THE SPANNED CHARACTERS. .TEST PAGE 6 .PARAGRAPH ^ON A SUCCESSFUL CALL, ^^SPAN\\ RETURNS THE NUMBER OF CHARACTERS REMAINING IN ^S1. ^^SPAN\\ WILL FAIL IF ALL THE CHARACTERS IN ^S1 ARE CONTAINED IN ^S2. ^THE FUNCTION WILL RETURN -1 AND PLACE ^^EOS\\ IN ^S3(1), INDICATING THAT ^^SPAN\\ HAS MATCHED ^^ALL\\ CHARACTERS IN ^S1. ^^SPAN\\ WILL ALSO FAIL IF THE FIRST CHARACTER IN ^S1 IS NOT CONTAINED IN ^S2. ^THE FUNCTION WILL RETURN 0 AND PLACE ^^EOS\\ IN ^S3(1), INDICATING NO MATCH. .TEST PAGE 6 .PARAGRAPH ^^SPAN\\ IS USUALLY USED FOLLOWING THE ^^BRAKE\\ FUNCTION. ^IF ^S1 CONTAINS '^^ABCD????EFG' .SKIP .NOFILL .NOJUSTIFY .LEFT MARGIN 15 ^^BRAKE(S1,'?',S3) S1\\ NOW CONTAINS ^^'????EFG' SPAN(S1,'?',S3) S1\\ NOW CONTAINS ^^'EFG'\\ .LEFT MARGIN 5 .FILL .JUSTIFY .TEST PAGE 6 .PARAGRAPH ^^SPAN\\ MUST BE DEFINED ^^INTEGER\\ AND THE PARAMETERS AS ^^CHAR\\ EXCEPT THAT ^S2 MAY BE A LITERAL STRING. .TEST PAGE 6 .SKIP 2 .HL 2 ^^MATCH .INDEX ^^MATCH .SKIP ^^INTEGER FUNCTION MATCH(LIN,PAT) .TEST PAGE 5 .SKIP .PARAGRAPH ^^MATCH\\ WILL RETURN THE POSITION IN ^^LIN\\ OF THE FIRST IDENTICAL OCCURENCE OF THE STRING IN ^^PAT\\ WITHIN THE STRING ^^LIN\\. ^IF THERE IS NO EXACT MATCH, ^^MATCH\\ WILL RETURN ^^NO\\. ^^MATCH\\ IS TAKEN FROM ^KERNIGHAN AND ^PLAUGER '^^SOFTWARE TOOLS\\', PAGE 140, AND ALLOWS NO METACHARACTERS. .TEST PAGE 4 .PARAGRAPH ^^LIN\\ AND ^^PAT\\ MUST BE STRING OF CHAR, AND MAY BE LITERAL. ^^MATCH\\ SHOULD BE DEFINED AS ^^INTEGER\\. .TEST PAGE 6 .SKIP 2 .HL 2 ^^ANY .INDEX ^^ANY .SKIP ^^INTEGER FUNCTION ANY(S1,S2) .TEST PAGE 5 .SKIP .PARAGRAPH ^^ANY\\ WILL RETURN THE FIRST CHARACTER POSITION IN ^S1 THAT CONTAINS ANY OF THE CHARACTERS DEFINED IN ^S2. .PARAGRAPH ^^ANY\\ MUST BE DEFINED ^^INTEGER\\; ^S1 AND ^S2 AS STRING OF CHAR AND MAY BE LITERAL. .TEST PAGE 6 .SKIP 2 .HL 2 ^^NOTANY .INDEX ^^NOTANY .TEST PAGE 6 .SKIP ^^INTEGER FUNCTION NOTANY(S1,S2) .SKIP .PARAGRAPH ^^NOTANY\\ WILL RETURN THE FIRST CHARACTER POSITION IN S1 THAT DOES ^^NOT\\ CONTAIN ANY CHARACTERS DEFINED IN ^S2. .PARAGRAPH ^^NOTANY\\ MUST BE DEFINED INTEGER, AND ^S1 AND ^S2 EITHER AS STRING OF CHAR OR LITERAL. .TEST PAGE 6 .SKIP 2 .HL 2 ^^SHIFT .INDEX ^^SHIFT .SKIP .TEST PAGE 6 ^^INTEGER FUNCTION SHIFT(S1,N)\\ .SKIP .PARAGRAPH ^^SHIFT\\ WILL REMOVE THE FIRST ^N CHARACTERS FROM ^S1 AND RETURN THE NUMBER OF REMAINING CHARACTERS IN ^S1. .PARAGRAPH ^^SHIFT\\ MUST BE DECLARED ^^INTEGER\\ AND ^S1 EITHER AS STRING OF ^^CHAR\\ OR LITERAL. .TEST PAGE 5 .SKIP 2 .HL 2 ^^RPLACE .INDEX ^^RPLACE .SKIP ^^INTEGER FUNCTION RPLACE(S1,OLD,NEW) .TEST PAGE 5 .SKIP .PARAGRAPH ^^RPLACE\\ WILL REPLACE ALL OCCURRENCES OF THE CHARACTER '^^OLD\\' IN STRING ^S1 WITH THE CHARACTER '^^NEW\\'. ^ON A SUCCESSFUL CALL THE FUNCTION WILL RETURN THE NUMBER OF CHARACTERS REPLACED. .PARAGRAPH ^^RPLACE\\ MUST BE DEFINED AS ^^INTEGER\\, AND ^^OLD\\ AND ^^NEW\\ AS ^^CHAR\\ OR LITERAL. .TESTPAGE 6 .SKIP 2 .HL 2 ^^TRIM .INDEX ^^TRIM .SKIP ^^INTEGER FUNCTION TRIM(S1)\\ .PARAGRAPH ^^TRIM\\ WILL TRIM OUT ALL TRAILING BLANKS AND TABS IN STRING ^S1 BY REPOSITIONING ^^EOS\\ AND RETURN THE NUMBER OF CHARACTERS IN THE TRIMMED STRING. .TEST PAGE 3 .PARAGRAPH ^^TRIM\\ MUST BE DEFINED ^^INTEGER\\ AND ^S1 AS STRING OF ^^CHAR\\. .TEST PAGE 6 .HL 2 ^^APPEND .INDEX ^^APPEND .SKIP ^^INTEGER FUNCTION APPEND(S1,S2,COUNT) .PARAGRAPH ^^APPEND\\ WILL CONCATENATE ^S2 ONTO THE END OF ^S1 ^^COUNT\\ TIMES AND RETURN THE NEW LENGTH OF ^S1. .TEST PAGE 3 .PARAGRAPH ^^APPEND\\ MUST BE DECLARED ^^INTEGER\\. ^^COUNT\\ MUST BE AN INTEGER OR INTEGER VARIABLE. ^S1 MUST BE STRING OF ^^CHAR\\, DIMENSIONED LARGE ENOUGH TO CONTAIN THE CONCATENATION. ^S2 MUST EITHER BE STRING OF ^^CHAR\\ OR A LITERAL EXPRESSION. .TEST PAGE 6 .SKIP 2 .HL 2 ^^REMOVE .INDEX ^^REMOVE .SKIP ^^INTEGER FUNCTION REMOVE(S1,FROM,TO) .PARAGRAPH ^^REMOVE\\ WILL REMOVE A SUBSTRING FROM ^S1 BEGINNING AT POSITION ^^FROM\\ THROUGH POSITION ^^TO\\ AND RETURN THE NEW LENGTH OF ^S1. ^FUNCTION WILL FAIL IF ^^TO\\ IS ^^LE FROM\\ AND RETURN ^^EOS\\. ^FUNCTION WILL FAIL IF ^^FROM\\ IS ^^GE LENGTH(S1)\\ AND RETURN ^^EOS\\. IF ^^FROM\\ IS ^^LE\\ 1, ^^TO\\ CHARACTERS WILL BE REMOVED FROM ^S1 STARTING AT ^S1(1). ^IF ^^TO\\ IS ^^GE LENGTH(S1), S1\\ WILL BE TRUNCATED AT ^^FROM\\. .TEST PAGE 3 .PARAGRAPH ^^REMOVE\\ MUST BE DECLARED ^^INTEGER\\. ^S1 MUST BE STRING OF ^^CHAR\\. ^^FROM\\ AND ^^TO\\ MUST BE INTEGERS OR INTEGER VARIABLES. .TEST PAGE 6 .SKIP 2 .HL 2 ^^INSERT .INDEX ^^INSERT .SKIP ^^INTEGER FUNCTION INSERT(S1,FROM,S2)\\ .PARAGRAPH ^^INSERT\\ WILL INSERT STRING ^S2 INTO ^S1 AFTER ^^S1(FROM)\\ AND RETURN THE NEW LENGTH OF ^S1. ^IF ^^FROM\\ ^^GE LENGTH(S1), S2\\ WILL BE APPENDED TO ^S1. ^IF ^^FROM LT 1, S2\\ WILL BE INSERTED BEFORE ^S1. .TEST PAGE 3 .PARAGRAPH ^^INSERT\\ SHOULD BE DECLARED ^^INTEGER\\. ^S1 MUST BE STRING OF ^^CHAR\\, AND ^S2 EITHER STRING OF ^^CHAR\\ OR LITERAL EXPRESSION. ^^FROM\\ MUST BE AN INTEGER OR INTEGER VARIABLE. .TEST PAGE 6 .HL 2 ^^LPAD .INDEX ^^LPAD .SKIP INTEGER FUNCTION LPAD(S1,N) .PARAGRAPH ^^LPAD\\ WILL INSERT ^N BLANKS BEFORE ^S1 AND RETURN THE NEW LENGTH OF ^S1. .PARAGRAPH ^^LPAD\\ MUST BE DECLARED ^^INTEGER\\. ^S1 MUST BE STRING OF ^^CHAR.\\ ^N MUST BE EITHER AN INTEGER OR INTEGER VARIABLE. .TEST PAGE 6 .SKIP 2 .HL 2 ^^RPAD .INDEX ^^RPAD .SKIP ^^INTEGER FUNCTION RPAD(S1,N) .PARAGRAPH ^^RPAD\\ WILL APPEND ^S1 WITH ^N BLANKS AND RETURN THE NEW SIZE OF ^S1. .PARAGRAPH ^^RPAD MUST BE DECLARED ^^INTEGER\\. ^S1 MUST BE STRING OF ^^CHAR\\. ^N MUST BE EITHER AN INTEGER OR INTEGER VARIABLE. .TEST PAGE 6 .SKIP 2 .HL 2 ^^ALIGN .INDEX ^^ALIGN .SKIP ^^INTEGER FUNCTION ALIGN(S1,POS,FIELD) .PARAGRAPH ^^ALIGN\\ WILL LEFT JUSTIFY, RIGHT JUSTIFY, OR CENTER ^S1 IN A FIELD OF LENGTH ^^FIELD\\ DEPENDING ON VALUE OF ^^POS\\ AND RETURN THE NEW LENGTH OF ^S1. ^THIS IS ACCOMPLISHED BY INSERTING THE CORRECT NUMBER OF SPACES BEFORE ^S1. .PARAGRAPH ^IF ^^FIELD\\ IS ^^LE LENGTH(S1)\\ THE FUNCTION WILL FAIL AND RETURN ^^EOS\\. .TEST PAGE 6 .PARAGRAPH ^IF ^^POS\\ IS ^^LT 0, S1\\ WILL BE LEFT JUSTIFIED. ^IF ^^POS\\ IS = 0, ^S1 WILL BE CENTERED ON ^^FIELD\\. ^IF ^^POS\\ IS ^^GT\\ 0, ^S1 WILL BE RIGHT JUSTIFIED. .PARAGRAPH ^^ALIGN\\ MUST BE DECLARED ^^INTEGER\\. ^S1 MUST BE STRING OF ^^CHAR\\. ^^FIELD\\ AND ^^POS\\ MUST EITHER BE INTEGERS OR INTEGER VARIABLES. .TEST PAGE 10 .SKIP 4 .HL 1 ^^CHARACTER I/O ROUTINES\\ .INDEX ^C\\HARACTER ^I/^O ^ROUTINES .SKIP .TESTPAGE 3 .PARAGRAPH \\^THE CHARACTER ^I/^O ROUTINES ARE USED TO SIMPLIFY THE READING OR WRITING OF STRINGS OR SINGLE CHARACTERS. ^^GETL\\ AND ^^PUTL\\ READ AND WRITE STRINGS; ^^GETC \\AND^^ PUTC \\ HANDLE ONE CHARACTER AT A TIME. .TEST PAGE 6 .SKIP 2 .HL 2 ^^GETL .INDEX ^^GETL .SKIP ^^INTEGER FUNCTION GETL(LINE,MAXLIN,LUNIN) .PARAGRAPH ^^GETL\\ READS THE NEXT RECORD ON ^L^U^N ^^^L^U^NIN\\ AND RETURNS UP TO ^^MAXLIN-1\\ CHARACTERS IN ^^LINE\\. ^AN ^^EOS\\ IS ALWAYS PUT AT THE END OF THE INPUT RECORD IN ^^LINE\\. ^THE FUNCTION ITSELF RETURNS THE LENGTH OF THE RECORD. ^IF END-OF-FILE IS SIGNALLED, THE FUNCTION RETURNS ^^EOF\\, WHICH CAN BE DISTINGUISHED FROM THE NORMAL CASE, SINCE ^^EOF\\ IS A NEGATIVE INTEGER AND HENCE DIFFERENT FROM ANY POSSIBLE RECORD LENGTH. ^^GETL, MAXLIN, \\AND^^ ^L^U^NIN\\ MUST BE DECLARED TO BE INTEGERS IN THE CALLING PROGRAM; ^^LINE\\ MUST BE A ^^CHAR\\ VECTOR OF AT LEAST ^^MAXLIN\\ ELEMENTS. .TEST PAGE 9 .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP ^EXAMPLES: .SKIP ^^CHAR INPUT(100) INTEGER GETL, N, I FOR (N=GETL(INPUT,100,1); N~=EOF; N=GETL(INPUT,100,1)) WRITE(2,10) (INPUT(I),I=1,N) 10 FORMAT(99A1) CALL EXIT END .SKIP .FILL .JUSTIFY .LEFT MARGIN 5 \\^THIS PROGRAM COPIES THE FILE ON ^L^U^N 1 TO THE FILE ON ^L^U^N 2 TRUNCATING ANY RECORDS LONGER THAN 99 CHARACTERS. .TEST PAGE 6 .SKIP 2 .HL 2 ^^PUTL .INDEX ^^PUTL .SKIP ^^SUBROUTINE PUTL(LINE,LUNOUT) .SKIP ^^PUTL\\ WRITES A RECORD CONTAINING THE STRING ^^LINE\\ ONTO ^L^U^N ^^^L^U^NOUT.\\ ^IF THE STRING HAS ZERO LENGTH, A NULL RECORD IS WRITTEN. ^^PUTL\\ INSERTS NO CARRIAGE CONTROL, ALTHOUGH THE CALLING PROGRAM MAY HAVE SET THE FIRST CHARACTER IN ^^LINE\\ TO A CARRIAGE CONTROL CHARACTER. ^^LINE\\ MUST BE A ^^CHAR\\ VECTOR IN THE MAIN PROGRAM, AND ^^^L^U^NOUT\\ MUST BE AN ^^INTEGER\\. .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .TEST PAGE 5 .SKIP ^EXAMPLE: .SKIP ^^CALL PUTL('THE RAIN IN SPAIN FALLS MAINLY IN THE PLAIN',1) .SKIP .FILL .JUSTIFY .LEFT MARGIN 5 \\^THIS CALL WRITES THE CHARACTER STRING SHOWN AS THE NEXT RECORD ON ^L^U^N 1. .TEST PAGE 6 .HL 2 ^^GETC .INDEX ^^GETC .SKIP ^^CHAR FUNCTION GETC(C)\\ .PARAGRAPH ^^GETC\\ RETURNS THE NEXT CHARACTER ON ^L^U^N ^^STD^L^U^NIN\\ IN BOTH ^^GETC AND C.\\ ^AT THE END OF THE FIRST RECORD ON ^^STD^L^U^NIN\\, THE CHARACTER ^^NEWLINE\\ IS SENT. ^THE NEXT CALL TO ^^GETC\\ WILL CAUSE A NEW RECORD TO BE READ IN. ^AFTER THE LAST CHARACTER OF EACH INPUT RECORD IS SENT, THE NEXT CALL TO ^^GETC\\ WILL RETURN THE ^^NEWLINE\\ CHARACTER AND THE CALL AFTER THAT WILL CAUSE A NEW RECORD TO BE READ AND ITS FIRST CHARACTER RETURNED. ^NOTE THAT ^^NEWLINE\\ IS DISTINGUISHABLE FROM ANY ^^ASCII\\ CHARACTER. ^AT THE END OF FILE, ^^EOF\\ IS SENT. .TESTPAGE 3 .PARAGRAPH ^IN THE CALLING PROGRAM, BOTH ^^GETC\\ AND ^C MUST BE OF TYPE ^^CHAR\\. ^^GETC\\ TRUNCATES ANY INPUT RECORD LONGER THAN 132 CHARACTERS. ^MIXING ^^GETC\\ WITH ANY OTHER TYPE OF INPUT ON ^^STD^L^U^NIN\\ CAN YIELD STRANGE RESULTS. ^SUCH A TRICK SHOULD ONLY BE ATTEMPTED IMMEDIATELY AFTER A ^^NEWLINE\\ IS RETURNED BY ^^GETC\\. .TEST PAGE 13 .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP ^EXAMPLES: .SKIP ^^CHAR GETC,C INTEGER COUNT COUNT=0 WHILE (GETC(C)~=EOF) IF (C~=NEWLINE) COUNT=COUNT+1 WRITE(5,10) COUNT 10 FORMAT(I10) CALL EXIT END .FILL .JUSTIFY .LEFT MARGIN 5 .SKIP \\^THIS PROGRAM COUNTS THE NUMBER OF CHARACTERS IN THE FILE ATTACHED TO ^^STD^L^U^NIN\\ AND PRINTS THIS COUNT. .TEST PAGE 6 .SKIP 2 .HL 2 ^^PUTC .INDEX ^^PUTC .SKIP ^^SUBROUTINE PUTC(C) .PARAGRAPH ^^PUTC\\ ACCEPTS A SINGLE CHARACTER AND BUFFERS IT FOR FUTURE OUTPUT ON ^^STD^L^U^NOUT\\. ^WHEN A ^^NEWLINE\\ IS SENT TO ^^PUTC,\\ THE BUFFER IS OUTPUT AND A NEW RECORD STARTED. ^THIS ALLOWS EASY INTERACTION BETWEEN ^^GETC\\ AND ^^PUTC\\:##^^GETC\\ TAKES RECORDS APART AND ^^PUTC\\ PUTS THEM BACK TOGETHER. ^^PUTC\\ ALSO STARTS A NEW RECORD, IF 133 CHARACTERS WITHOUT A ^^NEWLINE\\ ARE SENT. ^C MUST BE OF TYPE ^^CHAR\\ IN THE CALLING PROGRAM. .TEST PAGE 9 .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP ^EXAMPLES: .SKIP ^^CHAR C,GETC WHILE(GETC(C)~=EOF) IF(C~=BLANK _& C~=TAB) CALL PUTC(C) CALL EXIT END .SKIP 1 .FILL .JUSTIFY .LEFT MARGIN 5 \\^THIS PROGRAM COPIES THE FILE ATTACHED TO ^^STD^L^U^NIN\\ TO THE FILE ATTACHED TO ^^STD^L^U^NOUT,\\ ELIMINATING ALL BLANKS AND TABS ON THE WAY. .TEST PAGE 10 .SKIP 4 .HL 1 ^^MCR LINE ROUTINES .INDEX ^^MCR L\\INE ROUTINES .TESTPAGE 3 .PARAGRAPH \\^THE ^^RATFOR\\ LIBRARY CONTAINS SEVERAL ROUTINES FOR HANDLING ^^MCR\\ LINES AND OTHER TERMINAL ^^I/O\\. ^THE LOWEST LEVEL ROUTINES ARE ^^NXTMCR\\ AND ^^NXTFIL\\. ^^NXTMCR\\ .INDEX ^^NXTMCR .INDEX NXTFIL\\ READS THE NEXT ^^MCR\\ LINE AND PLACES IT IN A ^^COMMON\\ BUFFER. ^THIS ^^MCR\\ LINE CAN COME FROM ^^GETMCR\\, PROMPTING, OR EVEN ONE LEVEL OF INDIRECT COMMAND FILE, IF THE CALLING PROGRAM SUPPLIES ^^NXTMCR\\ WITH A DEDICATED ^L^U^N. ^THE CHOICE AMONG THESE THREE IS MADE AUTOMATICALLY BY ^^NXTMCR\\. ^THIS LINE CAN THEN BE PROCESSED, OR ^^NXTFIL\\ CAN BE USED TO PROCESS IT. ^^NXTFIL\\ SCANS THE ^^MCR\\ LINE IN THE ^^COMMON \\AREA AND RETURNS THE FILE NAMES, WITH THEIR SWITCHES, ONE BY ONE. ^^NXTFIL\\ ALSO PUTS ON DEFAULT FILE EXTENSIONS. ^WE CAN ALSO USE ^^NXTFIL\\ TO PROCESS FILE NAMES WHICH DO NOT COME FROM ^^MCR\\ LINES, BY LOADING THE ^^COMMON\\ AREA ^^MCR\\ BUFFER OURSELVES. ^FOR EXAMPLE, THIS TECHNIQUE IS USED BY THE ^^RATFOR\\ PROCESSOR TO HANDLE FILE NAMES IN ^^INCLUDE\\ STATEMENTS. .TESTPAGE 3 .PARAGRAPH ^THERE ARE TWO HIGHER-LEVEL ROUTINES FOR PROCESSING ^^MCR\\ INPUT. .INDEX ^^SETOTL .INDEX SETFLT\\ ^THESE ROUTINES GET THE NEXT ^^MCR\\ LINE, SCAN IT, AND OPEN FILES ON STANDARD ^L^U^NS. ^BEFORE DISCUSSING THEM, WE ARE GOING TO TAKE A QUICK LOOK AT THE CONCEPT OF PIPELINES, FILTERS AND OUTLETS. .TESTPAGE 3 .PARAGRAPH ^MANY PROGRAMS HAVE ONE INPUT FILE AND ONE OUTPUT FILE. ^WE CAN IMAGINE THE DATA MOVING THROUGH A PIPELINE TO THE TASK; IT IS FILTERED BY THE TASK AND ALLOWED TO MOVE ON:##PERHAPS TO THE NEXT FILTER FOR PROCESSING OR PERHAPS TO AN OUTLET WHERE THE DATA IS MADE AVAILABLE TO THE WORLD OUTSIDE OF THE PIPELINE. ^THE FUNCTION ^^SETFLT\\ WILL SET UP A FILTER-TYPE PROGRAM BY READING AN ^^MCR\\ LINE AND OPENING AN INPUT FILE ON ^^STD^L^U^NIN\\ AND AN OUTPUT FILE ON ^^STD^L^U^NOUT\\. ^THE FUNCTION ^^SETOTL\\ WILL INITIALIZE AN OUTLET-TYPE PROGRAM BY READING AN ^^MCR\\ LINE AND OPENING AN INPUT FILE ON ^^STD^L^U^NIN\\. ^BOTH THESE SUBPROGRAMS REMOVE ANY SWITCHES FROM FILE NAMES THEY ENCOUNTER AND PLACE THEM IN A ^^COMMMON\\ AREA WHICH CAN BE SCANNED USING THE FUNCTION ^^GETARG\\. .INDEX ^^GETARG\\ .TESTPAGE 3 .PARAGRAPH ^NOW FOR A DETAILED LOOK AT THE ^^MCR\\ ROUTINES. .TEST PAGE 6 .HL 2 ^^NXTMCR .INDEX ^^NXTMCR .SKIP ^^INTEGER FUNCTION NXTMCR(LUNPMT,PROMPT,LUNIND,NUMOUT)\\ .PARAGRAPH ^^NXTMCR\\ READS THE NEXT COMMAND LINE AND RETURNS IT IN ^^COMMON\\ AREA ^^MCRNFO\\. ^THIS ^^COMMON\\ AREA IS SET UP LIKE THIS: .NOFILL .NOJUSTIFY .SKIP .LEFT MARGIN 15 .TEST PAGE 3 ^^CHAR MCR(82) INTEGER POS COMMON /MCRNFO/ MCR,POS .SKIP .LEFT MARGIN 5 .FILL .JUSTIFY \\^THE COMMAND LINE IS RETURNED IN ^^MCR\\ WITH AN ^^EOS\\ AT THE END; ^^POS\\ POINTS TO THE FIRST VALID CHARACTER IN THIS LINE. ^FOR EXAMPLE, IF A PROGRAM ^^PRG\\, CALLED ^^NXTMCR\\, AND THIS PROGRAM WAS STARTED WITH .LEFT MARGIN 15 .SKIP ^^MCR>PRG FILE1=FILE2\\ .SKIP .LEFT MARGIN 5 THEN AFTER CALLING ^^NXTMCR\\ WE WOULD HAVE '^^PRG FILE1=FILE2'EOS\\ IN THE ^^MCR\\ ARRAY AND 5 IN ^^POS\\. .TESTPAGE 3 .PARAGRAPH ^^NXTMCR\\ USES THIS ALGORITHM TO GET AN ^^MCR\\ LINE: .SKIP .LEFT MARGIN 15 1) ^IF THIS IS THE FIRST TIME ^^NXTMCR\\ HAS BEEN CALLED, TRY TO READ AN ^^MCR\\ LINE USING ^^GETMCR\\. ^IF THIS IS SUCCESSFUL, AND THERE IS SOMETHING ON THE ^^MCR\\ LINE BESIDES THE PROGRAM NAME, KEEP THIS LINE. .SKIP 2) ^OTHERWISE, IF THERE IS AN INDIRECT COMMAND FILE NOW OPEN, READ THE NEXT COMMAND LINE FROM IT. .SKIP 3) ^IF NEITHER OF THE ABOVE HOLD, PROMPT FOR A COMMAND LINE ON ^^^L^U^NPMT\\. .LEFT MARGIN 5 .TESTPAGE 3 .PARAGRAPH ^^NXTMCR\\ IGNORES ANY EMPTY OR BLANK COMMAND LINES. ^WHEN A COMMAND LINE STARTING WITH AN @ IS FOUND, ^^NXTMCR\\ WILL TRY TO OPEN AN INDIRECT COMMAND FILE. ^THE CALLER MUST HAVE SUPPLIED ^^NXTMCR\\ WITH A ^L^U^N IN ^^^L^U^NIND\\ BY SETTING THIS ARGUMENT TO ANY POSITIVE INTEGER. ^IF THE CALLER IS UNABLE TO DEDICATE A ^L^U^N ENTIRELY FOR ^^NXTMCR\\'S USE, THE ^^^L^U^NIND\\ ARGUMENT IS 0. ^THEN ANY ATTEMPT AT INDIRECT COMMAND FILES WILL CAUSE ^^NXTMCR\\ TO TYPE AN ERROR MESSAGE AND PROMPT FOR ANOTHER COMMAND LINE. ^NOTE WELL:##^THE CALLING PROGRAM MUST BE WILLING TO DEDICATE A ^L^U^N SOLELY FOR ^^NXTMCR\\'S USE, IF INDIRECT COMMAND FILES ARE TO BE PERMITTED. ^IF NOT, ALWAYS CALL ^^NXTMCR\\ WITH A ^^^L^U^NIND\\ OF 0. .TESTPAGE 3 .PARAGRAPH ^THE ^^PROMPT\\ ARGUMENT IS A THREE-CHARACTER STRING USED BY ^^NXTMCR\\ WHEN PROMPTING ON THE TERMINAL. ^FOR EXAMPLE, IF THIS ARGUMENT IS '^^PRG\\', ^^NXTMCR\\ WILL PROMPT WITH ^^PRG>\\. ^THIS PROMPT IS ALSO USED BY ^^NXTMCR\\ TO IDENTIFY ANY ERROR MESSAGES IT TYPES. .TESTPAGE 3 .PARAGRAPH ^AFTER IT HAS THE ^^MCR\\ LINE, ^^NXTMCR\\ SCANS IT AND COUNTS THE NUMBER OF (POSSIBLY NULL) OUTPUT FILE NAMES. ^THIS VALUE IS RETURNED IN ^^NUMOUT\\. ^IT CAN BE USED BY THE CALLING PROGRAM TO DETERMINE HOW TO PROCESS THE ^^MCR\\ LINE. ^FOR EXAMPLE, CONSIDER THESE THREE ^^MCR\\ LINES: .SKIP .LEFT MARGIN 15 ^^OUTPUT=INPUT .BREAK ^^OUTPUT,LIST=INPUT .BREAK ,LIST=INPUT .SKIP .LEFT MARGIN 5 \\^FOR THE FIRST, ^^NUMOUT\\ WOULD BE SET TO 1. ^FOR BOTH THE SECOND AND THIRD, ^^NUMOUT\\ WOULD BE SET TO 2. ^IN THE THIRD CASE, THE CALLING PROGRAM WOULD HAVE TO RECOGNIZE THAT THE FIRST OUTPUT FILE NAME WAS NULL. .TESTPAGE 3 .PARAGRAPH ^A SUMMARY OF THE ARGUMENTS USED TO CALL ^^NXTMCR\\ IS: .SKIP .LEFT MARGIN 15 ^^^L^U^NPMT\\ IS A ^L^U^N (POSITIVE INTEGER) USED BY ^^NXTMCR\\ TO PROMPT FOR COMMAND LINES AND FOR TYPING ERROR MESSAGES. ^NORMALLY, IT WOULD BE ^^STD^L^U^NTI.\\ .SKIP ^^PROMPT\\ IS A THREE CHARACTER STRING USED BY ^^NXTMCR\\ TO PROMPT FOR COMMAND LINES. ^NORMALLY, IT IS A CHARACTER CONSTANT GIVING THE PROGRAM NAME. .SKIP ^^^L^U^NIND\\ IS A ^L^U^N USED BY ^^NXTMCR\\ FOR INDIRECT COMMAND FILE ^^I/O.\\ ^IF THE CALLING PROGRAM IS UNWILLING TO DEDICATE A ^L^U^N SOLELY FOR ^^NXTMCR\\'S USE, THIS ARGUMENT MUST BE 0. .SKIP ^^NUMOUT\\ IS RETURNED BY ^^NXTMCR\\. ^IT IS SET TO THE NUMBER OF OUTPUT FILE NAMES ON THE COMMAND LINE. ^IF THERE IS NO EQUAL SIGN (=) ON THE COMMAND LINE, ^^NUMOUT\\ IS ZERO. ^OTHERWISE, IT IS ONE MORE THAN THE NUMBER OF COMMAS PRECEDING THIS EQUAL SIGN NOT COUNTING ANY COMMAS IN ^^UIC\\S. .LEFT MARGIN 5 .TESTPAGE 3 .PARAGRAPH ^^NXTMCR\\ RETURNS ^^YES\\ IF IT HAS READ A COMMAND LINE SUCCESSFULLY, AND ^^NO\\ IF THERE IS NO MORE COMMAND-LINE INPUT. ^IF ^^NXTMCR\\ DID NOT HAVE TO PROMPT FOR A COMMAND LINE, IT WILL RETURN ^^NO\\ AS SOON AS THE FIRST COMMAND LINE (READ BY ^^GETMCR\\) IS PROCESSED. ^ANY INDIRECT COMMAND FILE ON THIS LINE WILL BE PROCESSED. ^IF ^^NXTMCR\\ HAS TO PROMPT FOR A COMMAND LINE, IT WILL CONTINUE PROMPTING UNTIL ANSWERED BY _^^Z, AND THEN IT WILL RETURN ^^NO\\. ^HENCE, MOST PROGRAMS USING ^^NXTMCR\\ HAVE A ^^WHILE\\ LOOP LIKE THIS: .NOFILL .NOJUSTIFY .SKIP .LEFT MARGIN 15 ^^WHILE (NXTMCR(STD^L^U^NTI,'PRG',1,NUMOUT)==YES) { CALL SETUP(NUMOUT) CALL PROCES } CALL EXIT END .SKIP .FILL .JUSTIFY .LEFT MARGIN 5 \\^AS LONG AS ^^NXTMCR\\ FINDS A COMMAND LINE, THIS PROGRAM WILL EXECUTE USING THE COMMAND LINE AND THEN PROCESS THE INDICATED DATA. .TESTPAGE 3 .PARAGRAPH ^^NXTMCR\\ HAS LOCAL IMPURE DATA WHICH MUST NOT CHANGE BETWEEN CALLS OF THE FUNCTION. ^HENCE, ^^NXTMCR\\ MUST RESIDE IN THE ROOT SEGMENT OF AN OVERLAID PROGRAM. .TESTPAGE 3 .PARAGRAPH ^A SPECIAL CALLING SEQUENCE IS USED TO TELL ^^NXTMCR\\ TO FLUSH THE REMAINDER OF ANY INDIRECT COMMAND FILE NOW OPEN. ^THIS SOMETIMES MUST BE DONE IF AN ERROR IS DETECTED IN COMMAND-LINE INPUT. ^IF THE ^^^L^U^NPMT\\ ARGUMENT IS NEGATIVE, THEN ANY INDIRECT COMMAND FILE OPEN ON ^^^L^U^NIND\\ WILL BE CLOSED. ^IF AN INDIRECT COMMAND FILE IS NOT OPEN, THE CALL HAS NO EFFECT. ^^NXTMCR\\ ALWAYS RETURNS ^^YES\\ AFTER THIS SPECIAL CALL. .TEST PAGE 6 .SKIP 2 .HL 2 ^^NXTFIL .INDEX ^^NXTFIL .SKIP ^^INTEGER FUNCTION NEXFIL(EXT,FNAME,MAXFM,SWITCH,MAXSW) .PARAGRAPH ^^NXTFIL\\ SCANS THE COMMAND-LINE BUFFER IN ^^COMMON\\ AREA ^^MCRNFO\\ AND RETURNS THE NEXT FILE NAME IN ^^FNAME\\. ^ANY SWITCHES ON THIS FILE NAME ARE BROKEN OFF AND STORED, AS ONE STRING, IN ^^SWITCH\\. ^ONLY THE FIRST ^^MAXFNM\\ CHRACTERS OF THE FILE NAME ARE KEPT; ONLY THE FIRST ^^MAXSW\\ CHARACTERS OF THE SWITCHES ARE KEPT. ^BOTH ^^FNAME\\ AND ^^SWITCH\\ MUST BE ^^CHAR\\ VECTORS IN THE CALLING PROGRAM; THEY ARE RETURNED WITH A TERMINATING ^^EOS\\. ^THE ARGUMENT ^^EXT\\ IS A FOUR-CHARACTER STRING WHICH SUPPLIES A DEFAULT EXTENSION FOR THE NEXT FILE IN THE COMMAND LINE. ^IF THIS NEXT FILE HAS NO EXTENSION, ^^NXTFIL\\ WILL PUT ^^EXT\\ ON THE FILE NAME RETURNED IN ^^FNAME\\. ^THE EXTENSION GIVEN IN ^^EXT\\ MUST START WITH A PERIOD (.). .TESTPAGE 3 .PARAGRAPH ^^NXTFIL\\ STARTS SCANNING THE COMMAND LINE LEFT BY ^^NXTMCR\\ IN ^^MCRNFO\\ AT POSITION ^^POS\\. ^^POS\\ IS INCREMENTED AS ^^NXTFIL\\ SCANS THE ^^MCR\\ LINE. ^WHEN ^^NXTFIL\\ EXITS, ^^POS\\ IS LEFT POINTING AT THE BEGINNING OF THE NEXT FILE NAME OR AT THE ^^EOS\\ ON THE COMMAND LINE, IF THERE ARE NO MORE FILE NAMES. ^ANY BLANKS OR TABS IN FILE NAMES ARE REMOVED; ANY LOWER CASE LETTERS ARE TRANSLATED TO UPPER CASE. .TESTPAGE 3 .PARAGRAPH ^A FILE NAME IS TERMINATED BY A SLASH (/), COMMA (,), OR EQUAL SIGN (=). ^IF THE FILE NAME ENDS IN A SLASH, THE CHARACTERS BETWEEN THIS SLASH AND THE NEXT COMMA OR EQUAL SIGN ARE STORED AS A STRING IN ^^SWITCH\\. ^THE OPENING SLASH IS NOT STORED; ANY SUBSEQUENT SLASHES ARE STORED. .TESTPAGE 3 .PARAGRAPH ^FOR EXAMPLE, SAY THIS ^^MCR\\ LINE WAS IN THE ^^COMMON\\ AREA: .SKIP .LEFT MARGIN 15 ^^PROG OUT,,L;1/-SP=INPUT.EXT/AB/CD/EF .SKIP .LEFT MARGIN 5 \\^CONSIDER THIS SEQUENCE OF CALLS TO ^^NXTFIL\\: .SKIP .LEFT MARGIN 15 .NOFILL .NOJUSTIFY ^^JUNK = NXTFIL('.OTP',FNOUT,33,SWOUT,10) JUNK = NXTFIL('.MAP',FNMAP,33,SWMAP,10) JUNK = NXTFIL('.LST',FNLST,33,SWLST,10) JUNK = NXTFIL('.INP',FNINP,33,SWINP,10) .FILL .JUSTIFY .LEFT MARGIN 5 .SKIP \\^THESE CALLS WOULD EACH SET ^^JUNK\\ TO ^^YES\\ AND WOULD LEAVE THE OTHER VARIABLES IN THESE STATES: ##(THE QUOTES AREN'T PART OF THE OUTPUT OF ^^NXTFIL\\; THEY ARE SHOWN HERE TO DELIMIT THE STRINGS RETURNED BY ^^NXTFIL\\) .NOFILL .NOJUSTIFY .SKIP .LEFT MARGIN 15 ^^FNOUT 'OUT.OTP' EOS SWOUT EOS FNMAP EOS SWMAP EOS FNLST 'L.LST;1'EOS SWLST '-SP' EOS FNINP 'INPUT.EXT'EOS SWINP 'AB/CD/EF' EOS .FILL .JUSTIFY .LEFT MARGIN 5 .SKIP \\^NOTICE THAT ^^NXTFIL\\ CONSIDERS NULL FILE NAMES VALID AND RETURNS A ZERO LENGTH STRING TO REPRESENT THEM. .TESTPAGE 3 .PARAGRAPH ^NORMALLY, ^^NXTMCR\\ AND ^^NXTFIL\\ INTERACT ON THEIR OWN; BUT WE NEED NOT WORRY ABOUT THE CONTENTS OF THE ^^MCR\\ BUFFER OR THE POINTER ^^POS\\. ^INSTEAD, WHEN ^^NXTMCR\\ RETURNS ^^YES\\, ^^NUMOUT\\ IS CHECKED AND USED TO DETERMINE THE SEQUENCE OF CALLS TO ^^NXTFIL\\. ^AFTER EACH CALL TO ^^NXTFIL\\ A CHECK MUST BE MADE FOR NULL FILE-NAMES. .TESTPAGE 3 .PARAGRAPH ^CONSIDER A PROGRAM WHICH ACCEPTS COMMAND LINES IN THESE FORMS: .LEFT MARGIN 15 .SKIP .NOFILL .NOJUSTIFY ^^OUTPUT=INPUT =INPUT INPUT .FILL .JUSTIFY .SKIP .LEFT MARGIN 5 \\^LET US WRITE A FUNCTION TO PROCESS THESE COMMAND LINES, USING ^^NXTMCR\\ AND ^^NXTFIL\\. ^THE ROUTINE WILL RETURN ^^YES\\ IF IT HAS SET THE FILES FROM A COMMAND LINE, ^^NO\\ IF THERE IS AN ERROR ON THE COMMAND LINE, AND ^^EOF\\ IF THERE ARE NO MORE COMMAND LINES. ^IF THE OUTPUT FILE IS OMITTED, ^T^I: IS USED AS THE OUTPUT FILE. ^IF THERE ARE ANY SWITCHES ON THE INPUT FILE, THEY ARE RETURNED IN ^^SWITCH\\; SWITCHES ON THE OUTPUT FILE ARE IGNORED. ^WHEN READING THIS ROUTINE, NOTICE HOW THE CASES OF NULL OUTPUT-FILES AND NO OUTPUT FILES HAVE BEEN MERGED: .SKIP .LEFT MARGIN 15 .NOFILL .NOJUSTIFY .TEST PAGE 32 ^^INTEGER FUNCTION SETUP(SWITCH) CHAR FIN(33), FOUT(33), SWITCH(16) INTEGER NXTFIL, NXTMCR, NUMOUT, JUNK IF (NXTMCR(STD^L^U^NIT, 'PRG', 0, NUMOUT)==NO) RETURN (EOF) ELSE IF (NUMOUT>>1) RETURN (NO) ELSE { IF (NUMOUT==0) FOUT(1) = EOS ELSE JUNK = NXTFIL('.OUT',FOUT,33,SWITCH,1) _# GET OUTPUT FILE IF (NXTFIL ('.INP', FIN, 33,SWITCH,16) == NO)) RETURN (NO) ELSE IF (FIN(1)==EOS || NXTFIL('.JNK',FIN,33,SWITCH,1)==YES) _# CHECK FOR EXTRA INPUT RETURN (NO) IF (FOUT(1)==EOS) OPEN (UNIT=STD^L^U^NOUT, NAME='TI:', ERR=100) ELSE OPEN (UNIT=STD^L^U^NOUT, NAME=FOUT, ERR=100) OPEN (UNIT=STD^L^U^NIN, NAME=FIN, ERR=100) RETURN (YES) } 100 RETURN (NO) END .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 6 .SKIP 2 .HL 2 ^^SETOTL .INDEX ^^SETOTL .SKIP ^^INTEGER FUNCTION SETOTL(LUNPMT,PROMPT,EXTIN,LUNIND) .PARAGRAPH ^^SETOTL\\ IS USED TO PROCESS THE COMMAND LINES OF OUTLET TYPE PROGRAMS. ^THESE COMMAND LINE MUST HAVE EXACTLY ONE FILE NAME. ^WHEN CALLED, ^^SETOTL\\ USES ^^NXTMCR\\ TO GET THE NEXT COMMAND LINE; IF THIS FAILS, ^^SETOTL\\ RETURNS ^^NO\\. ^OTHERWISE, ^^SETOTL\\ MAKES SURE THERE IS EXACTLY ONE INPUT FILE ON THE COMMAND LINE, OPENS IT ON ^^STD^L^U^NIN\\, AND RETURNS ^^YES\\. ^ANY ERRORS ON THE COMMAND LINE ARE HANDLED BY ^^SETOTL:\\##IT TYPES AN ERROR MESSAGE ON ^^^L^U^NPMT\\ AND TRIES FOR A NEW COMMAND LINE. .TESTPAGE 3 .PARAGRAPH ^ANY SWITCHES ON THE INPUT FILE ARE SAVED IN A ^^COMMON \\AREA ^^SWITCH\\ WHICH IS SET UP LIKE THIS: .LEFT MARGIN 15 .NOFILL .NOJUSTIFY .SKIP ^^CHAR SWITCH(80) COMMON /SWITCH/ SWITCH .FILL .JUSTIFY .LEFT MARGIN 5 .SKIP \\^THIS COMMON AREA IS ACCESSED BY THE ROUTINE ^^GETARG.\\ .TESTPAGE 3 .PARAGRAPH ^IF THE INPUT FILE NAME IS MISSING (I.E. THERE ARE JUST SWITCHES ON THE COMMAND LINE), ^^SETOTL\\ WILL OPEN THE FILE ^^PIPE.LYN\\ FOR INPUT. ^FURTHERMORE, THIS OPEN IS DONE WITH ^^DISP=DELETE\\ SO THAT WHEN THE INPUT FILE IS CLOSED ^^PIPE.LYN\\ IS REMOVED. ^^PIPE.LYN\\ IS ALWAYS A TEMPORARY FILE HOLDING PARTIAL RESULTS PRODUCED BY SOME OTHER PROGRAM. .TESTPAGE 3 .PARAGRAPH ^EACH TIME ^^SETOTL\\ IS CALLED, IT CLOSES ^^STD^L^U^NIN\\ BEFORE DOING ANYTHING ELSE. .TESTPAGE 3 .PARAGRAPH ^THE ARGUMENTS TO ^^SETOTL\\ HAVE THIS PURPOSE: .SKIP .LEFT MARGIN 15 ^^^L^U^NPMT\\:##^THIS ^L^U^N IS USED FOR PROMPTING (BY ^^NXTMCR)\\ AND ERROR MESSAGE TYPE OUT. ^IT IS USUALLY ^^STD^L^U^NTI\\. .SKIP ^^PROMPT\\:## ^THIS IS A THREE-CHARACTER PROGRAM NAME USED FOR PROMPTING AND ERROR MESSAGE IDENTIFICATION. .SKIP ^^EXTIN\\:##^THIS IS A FOUR-CHARACTER DEFAULT EXTENSION FOR THE INPUT FILE NAME. ^IT MUST START WITH A DOT. .SKIP ^^^L^U^NIND\\:##^IF NON-ZERO, ^^^L^U^NIND\\ PROVIDES A DEDICATED ^L^U^N FOR INDIRECT COMMAND FILES; IF ZERO, ATTEMPTS TO USE INDIRECT COMMAND FILES WILL ELICIT AN ERROR MESSAGE. .FILL .JUSTIFY .LEFT MARGIN 5 .TESTPAGE 3 .PARAGRAPH ^THIS EXAMPLE PROGRAM ACCEPTS COMMAND LINES CONTAINING EXACTLY ONE FILE NAME AND TYPES THE NUMBER OF LINES IN THE FILE. ^SINCE ^^SETOTL\\ OPENS ITS INPUT ON ^^STD^L^U^NIN\\ AND ^^GETC\\ READS FROM THIS ^L^U^N, THE TWO CO-OPERATE QUITE NICELY. .SKIP .TEST PAGE 12 .NOFILL .NOJUSTIFY .LEFT MARGIN 15 ^^CHAR GETC,C ^^INTEGER SETOTL,COUNT WHILE (SETOTL(STD^L^U^NTI,'COU','.LST',0)==YES) { COUNT = 0 WHILE (GETC(C)~=EOF) IF (C==NEWLINE) COUNT = COUNT+1 WRITE (5,10) COUNT 10 FORMAT(I10) } CALL EXIT END .LEFT MARGIN 5 .FILL .JUSTIFY .TEST PAGE 6 .SKIP 2 .HL 2 ^^SETFLT .INDEX ^^SETFLT .SKIP ^^INTEGER FUNCTION SETFLT(LUNPMT,PROMPT,EXTIN,EXTOUT,LUNIND) .PARAGRAPH ^^SETFLT\\ READS AND PROCESSES COMMAND LINES FOR FILTER-TYPE PROGRAMS. ^EACH SUCH COMMAND LINE CONTAINS NO MORE THAN 1 OUTPUT AND NO MORE THAN 1 INPUT FILE NAME. ^THE INPUT FILE IS OPENED ON ^L^U^N ^^STD^L^U^NIN\\, AND THE OUTPUT FILE IS OPENED ON ^L^U^N ^^STD^L^U^NOUT\\. ^IF THE INPUT FILE IS OMITTED, THE LATEST VERSION OF ^^PIPE.LYN\\ IS USED INSTEAD; SIMILARY IF THE OUTPUT FILE IS OMITTED, A NEW VERSION OF ^^PIPE.LYN\\ IS CREATED AND USED. ^IF THERE ARE SWITCHES ON EITHER THE INPUT FILE OR THE OUTPUT FILE, THEY ARE SAVED IN ^^COMMON\\ AREA ^^SWITCH\\ WHICH IS SET UP LIKE THIS: .LEFT MARGIN 15 .SKIP .NOFILL .NOJUSTIFY ^^CHAR SWITCH(80) COMMON /SWITCH/ SWITCH .FILL .JUSTIFY .SKIP .LEFT MARGIN 5 \\^IF SWITCHES APPEAR ON BOTH FILE-NAMES, ONLY THE INPUT FILE NAME SWITCHES ARE KEPT. ^THE ^^SWITCH\\ ^^COMMON\\ AREA IS ALSO ACCESSED BY THE ROUTINE ^^GETARG\\. .TESTPAGE 3 .PARAGRAPH ^^SETFLT\\ IS AN ^^INTEGER\\ FUNCTION AND MUST BE DECLARED TO BE ^^INTEGER \\ IN THE CALLING PROGRAM. ^IT RETURNS ^^YES\\, IF A COMMAND LINE IS SUCCESSFULLY READ AND PROCESSED, AND ^^NO\\ IF THERE IS NO MORE COMMAND-LINE INPUT. ^ANY ERRORS ON THE COMMAND LINE ARE HANDLED BY ^^SETFLT\\. ^THE OUTPUT FILE IS OPENED WITH ^^CARRIAGECONTROL='LIST'.\\ .TESTPAGE 3 .PARAGRAPH ^HERE IS A DETAILED DESCRIPTION OF ^^SETFLT\\'S ARGUMENTS: .SKIP .LEFT MARGIN 15 ^^^L^U^NPMT\\:##^THIS IS A ^L^U^N USED FOR PROMPTING AND ERROR MESSAGE PRINTING. ^IT IS USUALLY ^^STD^L^U^NTI\\. .SKIP ^^PROMPT\\:##^THIS IS A THREE-CHARACTER PROGRAM NAME USED FOR PROMPTING AND ERROR MESSAGE IDENTIFICATION. .SKIP ^^EXTIN\\:##^THIS IS THE DEFAULT EXTENSION FOR THE INPUT FILE. ^IT IS FOUR CHARACTERS LONG AND MUST START WITH A DOT. .SKIP ^^EXTOUT\\:##^THIS IS THE DEFAULT EXTENSION FOR THE OUTPUT FILE NAME. ^IT MUST BE FOUR CHARACTERS LONG AND MUST START WITH A DOT. .SKIP ^^^L^U^NIND\\:##^IF NON-ZERO, ^^^L^U^NIND\\ PROVIDES A DEDICATED ^L^U^N FOR INDIRECT COMMAND FILE ^^I/O\\. ^SETTING ^^^L^U^NIND\\ TO ZERO MEANS INDIRECT COMMAND FILES ARE NOT PERMITTED. .LEFT MARGIN 5 .TESTPAGE 3 .PARAGRAPH ^THIS EXAMPLE PROGRAM TRANSFERS ITS INPUT FILE TO THE OUTPUT, COMPRESSING ALL RUNS OF TWO OR MORE BLANKS TO A SINGLE BLANK. ^NOTICE HOW ^^SETFLT\\ OPENS THE RIGHT ^L^U^NS FOR ^^GETC\\ AND ^^PUTC\\. .LEFT MARGIN 15 .TEST PAGE 16 .SKIP .NOFILL .NOJUSTIFY ^^CHAR GETC,C ^^INTEGER SETFLT WHILE (SETFLT(STD^L^U^NTI,'BLA','.LST','.LST',0)==YES) WHILE (GETC(C)~=EOF) { IF (C==BLANK) { CALL PUTC(' ') WHILE (GETC(C)==BLANK) ; IF (C==EOF) BREAK } CALL PUTC(C) } CALL EXIT END .FILL .JUSTIFY .LEFT MARGIN 5 \\ .TEST PAGE 6 .SKIP 2 .HL 2 ^^GETARG .INDEX ^^GETARG .SKIP ^^INTEGER FUNCTION GETARG(ARGNUM,ARG,MAXARG) .PARAGRAPH ^^GETARG\\ IS USED TO PROCESS THE SWITCHES PLACED IN ^^COMMON\\ AREA ^^SWITCH\\, NORMALLY SET BY ^^SETOTL\\ OR ^^SETFLT\\. ^THIS ^^COMMON\\ AREA IS SET UP LIKE THIS: .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP .TEST PAGE 2 ^^CHAR SWITCH(80) COMMON /SWITCH/ SWITCH .SKIP \\ .LEFT MARGIN 5 .FILL .JUSTIFY ^THE PARAMETERS IN THIS AREA ARE ASSUMED TO BE SEPARATED BY SLASHES. ^A CALL TO ^^GETARG\\ PROVIDES RANDOM ACCESS TO THESE ARGUMENTS. ^ARGUMENT NUMBER ^^ARGNUM\\ IS COPIED FROM THE ^^SWITCH\\ AREA INTO THE STRING ^^ARG\\. ^ONLY THE FIRST ^^MAXARG\\-1 CHARACTERS OF THIS ARGUMENT ARE COPIED. ^^ARGNUM\\ AND ^^MAXARG\\ MUST BE INTEGERS IN THE CALLING PROGRAM; ^^ARG\\ MUST BE A ^^CHAR\\ VECTOR (ON RETURN, IT WILL BE ^^EOS\\ TERMINATED). .TESTPAGE 3 .PARAGRAPH ^IF ARGUMENT NUMBER ^^ARGNUM \\EXISTS, IT IS COPIED INTO ^^ARG\\. ^^GETARG\\ THEN RETURNS THE ARGUMENT'S LENGTH. ^IF THE VALUE OF ^^ARGNUM\\ IS TOO LARGE, ^^GETARG\\ RETURNS ^^EOF\\. ^^GETARG\\ MUST BE DECLARED TO BE ^^INTEGER\\ IN THE CALLING PROGRAM. .TESTPAGE 3 .PARAGRAPH ^ARGUMENTS ARE SEPARATED (DELIMITED) BY SLASHES. ^HENCE AN ARGUMENT NORMALLY CAN'T CONTAIN ONE OF THESE CHARACTERS. ^HOWEVER, WHEN A SLASH IS PRECEDED BY THE CHARACTER ^^ESCAPECHAR\\ (@), THE SLASH LOSES ITS SEPARATOR FUNCTION AND IS STORED AS PART OF THE CURRENT ARGUMENT. ^THE ^^ESCAPECHAR\\ IS REMOVED WHEN THIS IS DONE. ^IF THE @ CHARACTER ITSELF IS TO APPEAR IN SWITCHES PROCESSED BY ^^GETARG\\, IT MUST BE WRITTEN AS @@. .TESTPAGE 3 .PARAGRAPH ^ASSUME ^^SWITCH\\ HOLDS THESE CHARACTERS: .LEFT MARGIN 15 .SKIP .NOFILL .NOJUSTIFY ^^'ARG1/ARG2@/WITH@/SLASHES/ARGUMENTNUMBER3ISVERYLONGINDEED'EOS .FILL .JUSTIFY \\ .LEFT MARGIN 5 ^THEN .SKIP .LEFT MARGIN 15 ^^ .NOFILL .NOJUSTIFY GETARG(1,ARG,20) \\RETURNS 4 WITH ^^'ARG1'EOS \I\N ARG, GETARG(2,ARG,20) \\RETURNS 17 WITH^^'ARG2/WITH/SLASHES'EOS \I\N ARG, GETARG(3,ARG,20) \\RETURNS 19 WITH ^^'ARGUMENTNUMBER3ISVE'EOS \I\N ARG, GETARG(0,ARG,20) \\RETURNS ^^EOF, GETARG(4,ARG,20) \\RETURNS ^^EOF.\\ .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 6 .SKIP 2 .HL 2 ^^MCRERR .INDEX ^^MCRERR .SKIP ^^SUBROUTINE MCRERR(LUN,PRGNAM,MESS) .PARAGRAPH ^^MCRERR\\ WRITES THE STRING ^^MESS\\ ON LOGICAL UNIT NUMBER ^^^L^U^N\\, IDENTIFIED BY THE THREE-CHARACTER PROGRAM NAME ^^PRGNAM\\. ^IN THE CALLING PROGRAM, ^^^L^U^N\\ MUST BE AN INTEGER, ^^PRGNAM\\ A THREE-CHARACTER STRING, AND ^^MESS\\ ANY STRING (^^CHAR\\ VECTOR). .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .TEST PAGE 10 .SKIP ^EXAMPLES: .SKIP ^^CALL MCRERR(STD^L^U^NTI,'MYP','THIS IS THE MESSAGE') .SKIP \\TYPES^^ .SKIP MYP -- THIS IS THE MESSAGE .SKIP \\ON THE TERMINAL. .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 6 .SKIP 2 .HL 2 ^^CANT .INDEX ^^CANT .SKIP ^^SUBROUTINE CANT(LUN,PRGNAM,FNAME) .PARAGRAPH ^^CANT\\ IS USED TO PRINT AN ERROR MESSAGE ON ^L^U^N ^^^L^U^N\\ IDENTIFIED BY PROGRAM NAME ^^PRGNAM\\ WHICH SAYS THAT THE FILE NAMED ^^FNAME\\ CAN'T BE OPENED. ^^^L^U^N\\ MUST BE AN ^^INTEGER\\ IN THE CALLING PROGRAM, ^^PRGNAM\\ MUST BE A THREE CHARACTER STRING, AND ^^FNAME\\ ANY STRING. ^IF THE FILE NAME IS NULL, THE MESSAGE ^^NULL FILE NAME\\ IS PRINTED. .NOFILL .NOJUSTIFY .LEFT MARGIN 29 .TEST PAGE 8 .SKIP ^EXAMPLES: .SKIP ^^CALL CANT(STD^L^U^NTI,'HAL','NOFILE') .SKIP \\TYPES^^ .SKIP HAL -- CAN'T OPEN THIS FILE: NOFILE .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 6 .SKIP 2 .HL 2 ^^KILFER .INDEX ^^KILFER .SKIP ^^SUBROUTINE(KILFER) .PARAGRAPH ^^KILFER\\ (^^KIL\\L ^FILE ^E^RRORS) MAKES TWO CALLS TO THE ^^ERRSET\\ SUBROUTINE TO TURN OFF ERROR REPORTING FOR MOST ERRORS WHICH CAN OCCUR WHEN A FILE IS OPENED WITH THE ^^OPEN\\ STATEMENT. ^THE ^^ERR= \\ CONSTRUCT IS THEN USED IN THESE STATEMENTS TO HANDLE ERRORS. ^^KILFER \\IS ALWAYS CALLED BY ^^SETOTL\\ .PAGE .HL1 ^PERFORMANCE ^MEASUREMENT ^ROUTINES .INDEX ^PERFORMANCE ^MEASUREMENT ^ROUTINES .SKIP .PARAGRAPH ^A USEFUL SET OF PERFORMANCE MEASUREMENT ROUTINES MAY BE FOUND IN THE PERFORMANCE LIBRARY, ^^PERLIB\\. ^REFER TO THE DOCUMENTATION FOR ^THE ^PERFORMANCE ^LIBRARY. .PAGE .LEFT MARGIN 5 .FILL .JUSTIFY \\ .CENTER ^^ALPHABETICAL INDEX\\ .SKIP 2 .PRINT INDEX