.; ^RATFOR LIBRARY DESCRIPTION REV 4 22 OCT 80 .; 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 .; New routines ALLDIG, CLOWER, CUPPER, FOLD, ADDSET, GETWRD, .; PUTDEC,SKIPBL,UPPER,and AMATCH added -- SML 9/80 .TAB STOPS 9 17 25 33 .SPACING 1 .PAPER SIZE 60,70 .LEFT MARGIN 5 .TITLE ^^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, AND CHARACTER ^^I/O\\. .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 DEFINE (ALPHA=-4) DEFINE (ALPHABETIC=ALPHA) 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=-5) DEFINE (DUMMYSIZE=1) _#LENGTH OF ARGUMENT ARRAYS IN SUBROUTINES 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) _#ARBITRARILY LARGE NUMBER DEFINE (LETTER=-30) DEFINE (MAXDIGITS=18) _# MAXIMUM NUMBER OF DIGITS FOR INTEGER AS STRING DEFINE (MAXLINE=132) DEFINE (NEWLINE=10) DEFINE (NO=0) DEFINE (NUMERIC=DIGIT) DEFINE (OCTAL=8) DEFINE (PRINTER=6) DEFINE (STDIN=3) DEFINE (STDLUNIN=3) DEFINE (STDLUNOUT=4) DEFINE (STDLUNIND=2) 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\\. .SKIP ^Synonyms exist in several cases. For example NUMERIC and DIGIT are identical. .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 AND FROM EACH OTHER. ^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) .BREAK ################################ and ^I == 6 CTOI('12,34,56',I,10) returns 12 (BASE 10) and .BREAK ################################ ^I == 3 CTOI('12,34,56',I,8) returns 10 (BASE 10) and .BREAK ################################ ^I == 3 CTOI('1100011,111',I,2) returns 99 (BASE 10) and .BREAK ################################ ^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 SUCCESSFUL 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 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 ^^AMATCH .INDEX ^^AMATCH .SKIP ^^INTEGER FUNCTION AMATCH(LIN,FROM,PAT) .TEST PAGE 5 .SKIP .PARAGRAPH AMATCH performs an anchored match to determine if the string in LIN beginning at FROM matches PAT. If the strings don't match the function returns 0; if they do match the value of the function points one character beyond the last matching character. ^^AMATCH\\ 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. ^^AMATCH\\ 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 OR 0 IF NO CHARACTERS WERE 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 6 .SKIP 2 .HL 2 ALLDIG .INDEX ^^ALLDIG\\ .SKIP ^^INTEGER FUNCTION ALLDIG(S1) .PARAGRAPH ALLDIG tests a string to see if it contains only digits. The string is an ascii character array terminated with an EOS marker. Returns YES if string is all digits, otherwise NO. .PARAGRAPH S1 may be CHAR or a literal, ALLDIG must be declared INTEGER. .TESTPAGE 6 .SKIP 2 .HL 2 CLOWER .INDEX CLOWER .SKIP CHARACTER FUNCTION CLOWER(C) .PARAGRAPH CLOWER folds the character 'C' to lower case, if not already there. If 'C' is not alphabetic, it is returned unchanged. The function value returns the converted character. .PARAGRAPH 'C' may be CHAR or a literal and CLOWER must be declared CHAR. .TESTPAGE 6 .SKIP 2 .HL 2 CUPPER .INDEX CUPPER .SKIP CHARACTER FUNCTION CUPPER(C) .PARAGRAPH CUPPER converts the character 'C' to upper case, if not already there. Non-alphabetic characters are returned unchanged. The function returns the converted character. .PARAGRAPH 'C' may be CHARACTER or a literal and CUPPER must be declared CHAR. .TESTPAGE 6 .SKIP 2 .HL 2 FOLD .INDEX FOLD .SKIP SUBROUTINE FOLD(STR) .PARAGRAPH FOLD converts the character array 'STR' to lower case characters. Non-alphabetic characters are left unchanged. The 'STR' array is ascii characters terminated by an EOS marker. .TESTPAGE 6 .SKIP 2 .HL 2 UPPER .INDEX UPPER .SKIP SUBROUTINE UPPER(STR) .PARAGRAPH UPPER converts the array 'STR' to upper case, if not already there. If any characters are non-alphabetic, it leaves them unchanged. 'STR' is an ascii character array terminated with an EOS marker. .TESTPAGE 6 .SKIP 2 .HL 2 ADDSET .INDEX ADDSET .SKIP .PARAGRAPH INTEGER FUNCTION ADDSET(C,ARRAY,J,MAXSIZ) .PARAGRAPH ADDSET adds a character,C, at a specified position, J, of the character array ARRAY and increments J. It also checks that there's enough room to do so as determined by MAXSIZ. .PARAGRAPH ARRAY must be declared CHAR. 'C' is a single ascii character and ADDSET must be declared INTEGER. YES is returned if the routine succeeded, otherwise NO. .TESTPAGE 6 .SKIP 2 .HL 2 GETWRD .INDEX GETWRD .SKIP INTEGER FUNCTION GETWRD(IN,I,OUT) .PARAGRAPH Starting at position 'I' in array 'IN', skips any leading blanks and tabs and returns the next word and its length as the function value. A word is any series of characters terminated by a BLANK, TAB, or NEWLINE. The terminator is not returned as part of the word. 'I' is incremented to the position just past the end of the word. The word is returned in array 'OUT'. Both 'IN' and 'OUT' are ascii character arrays terminated with an EOS marker. GETWRD must be declared INTEGER. .TESTPAGE 6 .SKIP 2 .HL 2 SKIPBL .INDEX SKIPBL .SKIP SUBROUTINE SKIPBL(STR, I) .PARAGRAPH SKIPBL starts at position 'I' of character array 'STR' and increments I while STR(I) is a BLANK or TAB. 'STR' is an ascii character array terminated with an EOS marker. .TESTPAGE 6 .SKIP 2 .HL 2 SUBFOR .INDEX SUBFOR .SKIP INTEGER FUNCTION SUBFOR (STR, OLD, NEW) .PARAGRAPH SUBFOR replace each occurance of the character string 'OLD' with the string 'NEW' in the character array STR and returns the new length of STR. If the string 'OLD' was not found, then 0 is returned. The array STR must be of sufficient length to hold the new strings. .PARAGRAPH SUBFOR must be defined as INTEGER, and OLD and NEW as CHAR or literal. .SKIP .TEST PAGE 10 .SKIP 4 .HL 1 ^^CHARACTER I/O ROUTINES\\ .INDEX ^C\\HARACTER ^I/^O ^ROUTINES .SKIP .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. ^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 ^^MAXLINE\\ + 1 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. .TESTPAGE 6 .SKIP 2 .HL 2 PUTDEC .INDEX ^^PUTDEC\\ .SKIP ^^SUBROUTINE PUTDEC(N,W) .PARAGRAPH PUTDEC writes onto STDLUNOUT the number N as a string of at least W characters, including a sign if N is negative. If fewer than W characters are needed, blanks are inserted to the left to make up the count; if more than W are needed, more are provided. .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. .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 _# GET OUTPUT FILE JUNK = NXTFIL('.OUT',FOUT,33,SWITCH,1) IF (NXTFIL ('.INP', FIN, 33,SWITCH,16) == NO)) RETURN (NO) ELSE IF (FIN(1)==EOS || _# CHECK FOR EXTRA INPUT NXTFIL('.JNK',FIN,33,SWITCH,1)==YES) 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