Trailing-Edge
-
PDP-10 Archives
-
fortv11
-
sta1.bli
There are 12 other files named sta1.bli in the archive. Click here to see a list.
!COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1972, 1987
!ALL RIGHTS RESERVED.
!
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
!ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
!INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
!COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
!OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
!TRANSFERRED.
!
!THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
!AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
!CORPORATION.
!
!DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
!SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!AUTHOR: F.J. INFANTE, D. B. TOLMAN/SJW/DCE/TFV/EDS/CKS/AHM/AlB/TJK/MEM
MODULE STA1(RESERVE(0,1,2,3),SREG=#17,FREG=#16,VREG=#15,DREGS=4)=
BEGIN
GLOBAL BIND STA1V = #11^24 + 0^18 + #4551; ! Version Date: 25-Aug-86
! LEXNAM, FIRST, TABLES, META72, ASHELP
SWITCHES NOLIST;
REQUIRE FTTENX.REQ; ![4526]
REQUIRE LEXNAM.BLI;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
REQUIRE META72.BLI;
REQUIRE ASHELP.BLI;
SWITCHES LIST;
%(
***** Begin Revision History *****
57 ----- ----- FIX COMPLEX CONSTANTS IN DATA STATEMENTS SO THAT
THE ENTIRE CONSTANT CAN BE SIGNED
58 ----- ----- OPENCLOSE - FIX BUG THAT UNIT = WOULD DESTROY
THE CODE OF THE LAST PARAMETER .
AND WHILE WE ARE THERE FIX UP A FEW PARAMETER
VALUE LEGALITY CHECKS
59 ----- ----- CHECK FOR ILLEGAL LIST DIRECTED REREAD
60 ----- ----- IN DATAGEN - MUST CHECK THE SIGN OF THE
REPEAT COUNT ITSELF NOT JUST SIGNFLG
BECAUSE OF POSSIBLE NEGATIVE PARMETERS
61 ----- ----- FIX ERROR MESSAGE CALL FOR NON-ARRAY OPEN
STATEMENT PARAMETER VALUES
62 313 16666 FIX DIALOG WITH NO =
63 VER5 ----- HANDLE ERR= IN OPENCLOSE, (SJW)
64 424 QA690 ERROR IF DIRECTORY= NOT LITERAL OR ARRAY
NAME IN OPENCLOSE, (SJW)
***** Begin Version 5A ***** 7-Nov-76
65 521 QA900 FIX E15 PARAMS TO FATLEX IN OPENCLOSE, (SJW)
66 531 20323 GIVE WARNING FOR PARAMETER USED AS ASSOC VAR ,(DCE)
***** Begin Version 6 *****
67 760 TFV 1-Jan-80 -----
Add new OPEN arguments and keyword based I/O (for FORTRAN 77)
68 761 TFV 1-Mar-80 -----
Add indices for folding /GFLOATING constants
69 1005 TFV 1-Jul-80 ------
Fix OPENCLOSE to handle unit specifiers without the unit=
70 1014 TFV 27-Oct-80 Q10-04556
Allow list directed rereads, making reread just like ACCEPT, TYPE, etc.
71 1015 TFV 27-Oct-80 Q10-04743
FMT= is not optional for type, accept ,reread, etc.
72 1016 TFV 27-Oct-80 Q10-04759
Report names for misspelled OPEN/CLOSE parameters
73 1017 TFV 27-Oct-80 Q10-04733
Fix IOSTAT processing in OPEN/CLOSE. Param table had wrong
dispatch value. Also fix test for formal argument used as
an associate variable.
74 1020 TFV 27-Oct-80 Q10-04575
Add synonms for PDP-11 FORTRAN compatibility to OPEN/CLOSE.
INITIALSIZE= - FILESIZE=
NAME= - DIALOG=
TYPE= - STATUS=
Also fix ERR= processing. Only allow ERR=label.
75 1030 TFV 25-Nov-80 ------
Fix ERR=label in OPENCLOSE to check for labelex not constlex.
76 1032 EDS 1-Dec-80 10-30251
Fix DATAGEN processing of DATA statements. SAVSPACE was
not called to free space used by constant options or
repeat list.
77 1042 TFV 15-Jan-81 -------
Prohibit list directed encode/decode.
78 1045 TFV 20-Jan-81 -------
Fix edit 1030. NONIOINIO and LOOK4LABEL have to be reset.
79 1071 CKS 22-May-81
Remove TAPEMODE from OPEN keyword plit
81 1076 TFV 8-Jun-81 ------
Allow list-directed I/O without an iolist
84 1124 AHM 21-Sep-81 Q20-01651
Set STORD for IOSTAT variables and ASSOCIATEVARIABLES so they get
put back in subprogram epilogues.
***** Begin Version 7 *****
80 1202 DCE 1-Jul-80 -----
Change calls to DATALIST to be calls to LISTIO for expressions
on output lists.
82 1233 CKS 28-Jun-81
Alter some .s and @s in BLDIO1 and BLDEDCODE to conform to new STK
%! produced by using %OPTCOMMA% instead of [ COMMA ] in the BNF.
% See comments in STA0.
83 1245 TFV 3-Aug-81 ------
Fix OPENCLOSE to convert character constant args to HOLLERITH
until FOROTS knows how to cope with character data.
85 1267 AHM 6-Oct-81 ------
Define a stub routine INQUSTA for the INQUIRE statement so we don't
get undefined symbols when linking.
86 1410 CKS 28-Oct-81
Modify DATASTA to read the modified tree shape caused by the optional
comma in DATA A/1/,B/1/.
1527 CKS 27-Apr-82
Rewrite OPENCLOSE to allow expressions as open specifiers
1546 CKS 31-May-82
Move PRINSTA, RERESTA, TYPESTA to STA0 for uniformity.
1571 CKS 27-Jun-82
Don't set parent pointer under OPEN if expression is omitted.
(DIALOG, READONLY.)
1622 CKS 25-Aug-82
Correctly handle ASSOCIATEVARIABLE=arrayref and IOSTAT=arrayref.
Don't blindly call NAMSET on the "variable" if it's an array ref.
1662 TFV 2-Nov-82
Fix INQUSTA to give the error Exxx (NYI) 'INQUIRE statement is
not yet implemented.'
1676 CKS 18-Nov-82
Allow hollerith constants as open specifiers.
1677 CKS 20-Nov-82
Use action routine KEYSCAN to parse FIND, ENCODE, REWIND.
1716 TFV 17-Jan-83 Q20-06103
Fix OPENCLOSE. FLGREG is trashed if UNIT is not specified.
***** End V7 Development *****
2043 TJK 24-Feb-84
Have OPEN and CLOSE recognize the LIMIT= keyword once again.
This keyword takes an integer expression. Entries were added
to the tables OPNKWD and IOCKVEC in OPENCLOSE, and KEYWFLAG in
CFCHECK. LIMIT= is illegal for INQUIRE and is flagged as both
an ANSI and a VAX incompatibility. Note that this edit was
somewhat different for V7A and V10. Among other things, V7A
didn't have to change TABLES but V10 did.
***** End Revision History *****
***** Begin Version 10 *****
2200 TFV 17-Mar-83
Implement INQUIRE. Merge it with OPENCLOSE. All INQUIRE
keyword values are modified by the statement except ERR, FILE,
and UNIT. Only IOSTAT and ASSOCIATEVARIABLE are modified by
OPEN and CLOSE. Give a warning for probable user error of
character constant where numeric expression is required. I.e.
RECL='40' is treated as RECL=28118614016.
2247 AlB 22-Dec-83
Add Compatibility Flagging for BACKFILE statement.
Routine:
BKSPST
2252 AlB 27-Dec-83
Change edit 2247 to use ISN instead of LEXLINE for line number.
Add compatibility flagging for FIND statement.
Routines:
BKSPST, FINDSTA
2274 AlB 24-Jan-84
Added compatibility flagging for OPEN/CLOSE keywords.
Added CFCHECK and CFSEARCH routines.
CARRIAGECONTROL keyword now accepted by the INQUIRE statement.
Routines:
CFCHECK CFSEARCH OPENCLOSE
2316 AlB 27-Feb-84
Changes made in order that this module more nearly conform
to programming conventions. The only change in functionality
is to CFCHECK, which no longer returns a value.
2370 MEM 5-Jun-84
Changes were made so that specifiers more than 6 characters could be
recognized past the sixth character in open/close statements. The
contents of the five tables OPNKWD, IOCKVAL, INQUVAL, IOCKCODE and
KEYWFLAG are combined and stored in the macro THEKEYS. Previously,
IOCKVAL, INQUVAL and IOCKCODE had been stored in one table called
IOCKEYVEC.
2413 MEM 5-Jul-84
Add the keyword TAPEFORMAT.
2424 MEM 10-Jul-84
Add the keyword DIALOGUE and correct the error message for putting a
READONLY keyword in an inquire statement. Previously it gave
'Found ")" when expecting keyword', and now it gives 'Unrecognized
keyword READONLY'. Error messages E300 and E182 were corrected also.
2426 MEM 16-Jul-84
Don't allow a specifier to occur multiple times with different
spellings in the same open/close/inquire statement. Fix broken
DIALOG by placing DIALOG(without =) at end of table.
2455 MEM 30-Aug-84
Replace all occurrences of VAX with VMS.
2461 CDM 28-Sep-84
Add octal and hexadecimal constants for the Military Standard
MIL-STD-1753 to DATA statements.
2467 RVM 17-Oct-84
Add the OPEN/CLOSE keyword DISP= (a VAX synonym for DISPOSE=).
2476 MEM 7-Nov-84
Fix index number into THEKEYS for DIALOGUE and READONLY so
compatability message has full specifier in it instead of the
abbreviated 6 character specifier.
2477 AlB 15-Nov-84
Use the global flagger prefixes in CFCHECK.
2503 MEM 27-Nov-84
Fix index number into THEKEYS for ASSOCIATEVARIABLE, CARRAIGECONTROL,
and DISPOSE.
2511 MEM 7-Jan-85
Fixed a couple of error messages in OPENCLOSE which were passing an
ascii argument when a sixbit argument was expected. Changed an entry
in THEKEYS to make RECORDTYPE and TAPEFORMAT legal in an inquire
statement.
2523 MEM 11-Mar-85
Separate open and close keywords specifiers.
***** End V10 Development *****
2552 MEM 16-Sep-85
Removed open specifier RECTYPE.
***** End Revision History *****
***** Begin Version 11 *****
4500 MEM 22-Jan-85
Entries in THEKEYS for BYTESIZE, KEY=, ORGANIZATION, SHARED, USEROPEN,
and KEYED were added. Add KEYED as a valid vms access value.
4502 MEM 22-Jan-85
Created routine DELESTA to perform ANSI flagging for DELETE statement
and to perform keyword processing.
4512 CDM 26-Aug-85
Delete old never called routines. TMPGEN, STRNGSCAN, ZSIXBIT.
4526 MEM 3-Dec-85
Give an error when RMS stuff is used on TOPS10.
4544 MEM 7-Aug-86
Flag associatevariables that are dummys as vms incompatible.
4551 MEM 25-Aug-86
Fix error message for receiving something other than a function name
for useropen.
ENDV11
)%
!THE NUMBER IN COMMENT'S IS THE STATEMENTS LOCATION IN THE HASH TABLE .
FORWARD
% 63% BKSPST, !BACKSPACE OR BACKFILE
% 39% REWISTA, !REWIND
% 84% ENDFSTA, !ENDFILE
% 34% FINDSTA, !FIND
DELESTA, !DELETE
CMPLXCONGEN(2),
SIGNEDREAL(1),
DATAGEN(1),
% 3% DATASTA, !DATA
%2370% COMPARE, ! comparison used in routine SEARCH
%2370% SEARCH, ! search for open/close/inquire keyword
OPENCLOSE(1),
%2316% CFSEARCH(2), !Search a table for Compatibility Flagger
%2316% CFCHECK(4), !Compatibility Flagger for OPEN/CLOSE/INQUIRE
% 18% OPENSTA, !OPEN
% 83% CLOSSTA, !CLOSE
%???% INQUSTA; ![1267] INQUIRE
EXTERNAL
%2477% ANSIPLIT, ! 'Extension to Fortran-77: '
BLDREPT,
BLDUTILITY,
BLDVAR,
%2477% BOTHPLIT, ! 'Fortran-77 and VMS: '
C1H,
C1L,
C2H,
C2L,
%2252% CFLAGB, ! Put out flagger warning
CNSTCM,
CNVNODE,
COPRIX,
CORMAN,
DATALIST,
DATASUBCHK,
E164,
E182,
E183,
E196,
E212, ! CHARACTER constant used where numeric expression required.
E213, ! INQUIRE - neither UNIT nor FILE keywords were specified
E214, ! INQUIRE - both UNIT and FILE keywords were specified
E215, ! HOLLERITH constant used where numeric expression required.
%2455% E226, ! VMS incompatibility: Different default file name
%2252% E239, ! Extension to Fortran-77: FIND statement
%2455% E247, ! Fortran-77 or VMS: Keyword xxxxx
%2455% E248, ! Fortran-77 or VMS: Keyword value for xxxxx
%4502% E267, ! Extension to Fortran-77: xxxxx statement
%2247% E268, ! Extension to Fortran-77: xxxxx statement
%2455% E275, ! VMS incompatibility: ASSOCIATEVARIBLE not set by VMS on OPEN
%2370% E299, ! replaced E184
%2424% E300, ! replaced E15
%2511% E305, ! same as E196 but has ascii, instead of sixbit, argument
%4500% E316, ! VMS keyword ?B ignored
%4500% E317, ! Too many keys specified for indexed file
%4500% E320, ! Illegal key type - must be INTEGER or CHARACTER
%4526% E322, ! TOPS20 ONLY: xxx
%4544% E325, ! VMS incompatible associate variable is a dummy variable
EXPRESS,
GSTCSCAN,
GSTKSCAN,
GSTSSCAN,
KDNEGB,
KDPRL,
%2370% KEYBUFFER, ! 4 word buffer containing keyword found in LEXICA
%2370% KEYLENGTH, ! number of characters in KEYBUFFER
KGFRL,
KTYPCB,
KTYPCG,
LABELS,
LEXEMEGEN,
LEXICAL,
LEXL,
LOOK4CHAR,
NAME,
NAMREF,
NAMSET,
NEWENTRY,
NOLABELS,
NONIOINIO,
SAVSPACE,
STK,
SP,
TYPE,
%2477% VMSPLIT; !' VMS incompatibility: '
!MEM
! THEKEYS is a macro which contains the contents of the tables OPNKWD,
! IOCKVAL, OPNCKVAL, IOCKCODE, and KEYWFLAG. These five tables are each
! expanded separately. Since all five of these tables must match,
! combining them together simplifies the task of adding to these tables
! at a later date. The tables OPNKWD, IOCKVAL, OPNCKVAL and IOCKCODE are
! used in routine OPENCLOSE and KEYWFLAG is used in routine CFCHECK.
BIND
IL = 0, ! illegal keyword for statement
CE = 1, ! character expression, numeric scalar,
! or numeric arrayref
IE = 2, ! integer expression
AR = 3, ! array name or char expression
LB = 4, ! label
CV = 5, ! character variable or array ref
IV = 6, ! integer variable or array ref
LV = 7, ! logical variable or array ref
%4500% NV = 8; ! no alloc variable
MACRO
CFANSI = 0$, ! Keyword is not recognized by Fortran-77
CFVMS = 1$, ! Keyword is not recognized by VMS
CFVANSI = 2$, ! Keyword is recognized by ANSI, but extra
! tests must be done
CFVVMS = 3$, ! Keyword is recognized by VMS, but extra
! tests must be done
%4526% CFTOPS10 = 4$, ! Keyword is not recognized on TOPS10
%4526% CFVTOPS10 = 5$, ! Keyword is recognized by TOPS10, but extra
%4526% ! tests must be done
![2370] created macro THEKEYS which has 5 fields
! field 1 = keyword names for open/close/inquire statements
! field 2 = inquire value types
! field 3 = close value types
! field 4 = open value types
! field 5 = FOROTS keyword numbers
! field 6 = flags which determine whether any given keyword is to be
! flagged as an extension to Fortran-77, an incompatibility
! with VMS, or both or incompatible with TOPS10.
THEKEYS(XX) =
XX(NACCESS INDEXES PLIT ASCIZ 'ACCESS',
%2455% CV, CE, CE, OPNCACCESS,1^CFVANSI+1^CFVVMS+1^CFVTOPS10),
%2503% XX(PLIT ASCIZ 'ASSOCI',
%2455% IL, IV, IV, OPNCASSOCIATE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'ASSOCIATE',
%2455% IL, IV, IV, OPNCASSOCIATE,1^CFANSI+1^CFVMS),
%2503% XX(NASSOC INDEXES PLIT ASCIZ 'ASSOCIATEVARIABLE',
%2455% IL, IV, IV, OPNCASSOCIATE,1^CFANSI+1^CFVVMS),
XX(PLIT ASCIZ 'BLANK',
CV, CE, CE, OPNCBLANK, 0),
XX(PLIT ASCIZ 'BLOCKS',
IL, IE, IE, OPNCBLOCKSIZE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'BLOCKSIZE',
IL, IE, IE, OPNCBLOCKSIZE,1^CFANSI),
XX(PLIT ASCIZ 'BUFFER',
IL, IE, IE, OPNCBUFCOUNT,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'BUFFERCOUNT',
IL, IE, IE, OPNCBUFCOUNT,1^CFANSI),
%4500% XX(PLIT ASCIZ 'BYTESIZE',
%4500% IV, IL, IE, IOCBYTESIZE,1^CFANSI+1^CFVMS),
%2503% XX(PLIT ASCIZ 'CARRIA',
%2455% CV, CE, CE, OPNCCARRIAGE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'CARRIAGE',
%2455% CV, CE, CE, OPNCCARRIAGE,1^CFANSI+1^CFVMS),
%2503% XX(NCARR INDEXES PLIT ASCIZ 'CARRIAGECONTROL',
%2455% CV, CE, CE, OPNCCARRIAGE,1^CFANSI+1^CFVVMS),
%4500% XX(NDFILE INDEXES PLIT ASCIZ 'DEFAULTFILE',
%4500% CE, IL, CE, IOCDEFAULTF,1^CFANSI),
XX(PLIT ASCIZ 'DENSIT',
%2455% IL, CE, CE, OPNCDENSITY, 1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'DENSITY',
%2455% IL, CE, CE, OPNCDENSITY, 1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'DEVICE',
%2455% IL, CE, CE, OPNCDEVICE, 1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'DIALOG',
%2455% IL, AR, AR, OPNCDIALOG, 1^CFANSI+1^CFVMS),
%2424% XX(PLIT ASCIZ 'DIALOGUE',
%2455% IL, AR, AR, OPNCDIALOG, 1^CFANSI+1^CFVMS),
XX(NDIRECT INDEXES PLIT ASCIZ 'DIRECT',
%2455% CV, AR, AR, OPNCDIRECT, 1^CFVANSI+1^CFVVMS),
XX(PLIT ASCIZ 'DIRECTORY',
%2455% CV, AR, AR, OPNCDIRECT, 1^CFANSI+1^CFVMS),
%2503% XX(PLIT ASCIZ 'DISP',
%2467% IL, CE, CE, OPNCDISPOSE, 1^CFANSI+1^CFVVMS),
XX(PLIT ASCIZ 'DISPOS',
%2455% IL, CE, CE, OPNCDISPOSE, 1^CFANSI+1^CFVMS),
%2503% XX(NDISPOS INDEXES PLIT ASCIZ 'DISPOSE',
%2455% IL, CE, CE, OPNCDISPOSE, 1^CFANSI+1^CFVVMS),
XX(NERR INDEXES PLIT ASCIZ 'ERR',
LB, LB, LB, OPNCERREQ, 0),
XX(PLIT ASCIZ 'EXIST',
LV, IL, IL, IOCEXIST, 0),
%4500% XX(PLIT ASCIZ 'EXTENDSIZE',
%4500% IL, IL, IE, OPNCEXTEND, 1^CFANSI),
XX(NFILE INDEXES PLIT ASCIZ 'FILE',
CE, CE, CE, OPNCFILE, 1^CFVANSI),
XX(PLIT ASCIZ 'FILESI',
%2455% IL, IE, IE, OPNCFILESIZE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'FILESIZE',
%2455% IL, IE, IE, OPNCFILESIZE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'FORM',
CV, CE, CE, OPNCFORM, 0),
XX(PLIT ASCIZ 'FORMAT',
CV, IL, IL, IOCFORMATTED,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'FORMATTED',
CV, IL, IL, IOCFORMATTED,0),
XX(PLIT ASCIZ 'INITIA',
%2455% IL, IE, IE, OPNCFILESIZE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'INITIAL',
%2455% IL, IE, IE, OPNCFILESIZE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'INITIALIZE',
%2455% IL, IE, IE, OPNCFILESIZE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'INITIALSIZE',
%2455% IL, IE, IE, OPNCFILESIZE,1^CFANSI),
XX(NIOSTAT INDEXES PLIT ASCIZ 'IOSTAT',
IV, IV, IV, OPNCIOSTAT, 0),
%4500% XX(NKEY INDEXES PLIT ASCIZ 'KEY',
%4526% IL, IL, IE, OPNCKEY,1^CFANSI+1^CFTOPS10),
%4500% XX(PLIT ASCIZ 'KEYED',
%4526% CE, IL, IL, IOCKEYED,1^CFANSI+1^CFTOPS10),
XX(PLIT ASCIZ 'LIMIT',
%2455% IL, IE, IE, OPNCLIMIT, 1^CFANSI+1^CFVMS),
%4500% XX(PLIT ASCIZ 'MAXREC',
%4500% IL, IL, IE, OPNCMAXREC, 1^CFANSI),
XX(PLIT ASCIZ 'MODE',
%2455% IL, CE, CE, OPNCMODE, 1^CFANSI+1^CFVMS),
XX(NNAME INDEXES PLIT ASCIZ 'NAME',
CV, AR, AR, IOCNAME, 1^CFVANSI),
XX(PLIT ASCIZ 'NAMED',
LV, IL, IL, IOCNAMED, 0),
XX(PLIT ASCIZ 'NEXTRE',
IV, IL, IL, IOCNEXTREC, 1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'NEXTREC',
IV, IL, IL, IOCNEXTREC, 0),
XX(PLIT ASCIZ 'NUMBER',
IV, IL, IL, IOCNUMBER, 0),
XX(PLIT ASCIZ 'OPENED',
LV, IL, IL, IOCOPENED, 0),
%4500% XX(NORGAN INDEXES PLIT ASCIZ 'ORGANIZATION',
%4526% AR, IL, AR, IOCORGANIZATION,1^CFANSI+1^CFVVMS+1^CFTOPS10),
XX(PLIT ASCIZ 'PADCHA',
%2455% IL, CE, CE, OPNCPADCHAR, 1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'PADCHAR',
%2455% IL, CE, CE, OPNCPADCHAR, 1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'PARITY',
%2455% IL, CE, CE, OPNCPARITY, 1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'PROTEC',
%2455% IL, IE, IE, OPNCPROTECTION,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'PROTECTION',
%2455% IL, IE, IE, OPNCPROTECTION,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'RECL',
IV, IE, IE, OPNCRECORDSIZE,0),
XX(PLIT ASCIZ 'RECORD',
IL, IE, IE, OPNCRECORDSIZE,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'RECORDSIZE',
IL, IE, IE, OPNCRECORDSIZE,1^CFANSI),
XX(PLIT ASCIZ 'RECORDTYPE',
%2511% CE, CE, CE, IOCRECTYPE, 1^CFANSI),
XX(PLIT ASCIZ 'SEQUEN',
CV, IL, IL, IOCSEQUENTIAL,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'SEQUENTIAL',
CV, IL, IL, IOCSEQUENTIAL,0),
XX(NSTATUS INDEXES PLIT ASCIZ 'STATUS',
%2455% IL, CE, CE, OPNCSTATUS, 1^CFVANSI+1^CFVVMS),
%2413% XX(PLIT ASCIZ 'TAPEFO',
%2511% AR, IL, AR, IOCTAPEFO,1^CFANSI+1^CFVMS),
%2413% XX(PLIT ASCIZ 'TAPEFORMAT',
%2511% AR, IL, AR, IOCTAPEFO,1^CFANSI+1^CFVMS),
XX(NTYPE INDEXES PLIT ASCIZ 'TYPE',
%2455% IL, CE, CE, OPNCSTATUS, 1^CFANSI+1^CFVVMS),
XX(PLIT ASCIZ 'UNFORM',
CV, IL, IL, IOCUNFORMATTED,1^CFANSI+1^CFVMS),
XX(PLIT ASCIZ 'UNFORMATTED',
CV, IL, IL, IOCUNFORMATTED,0),
XX(NUNIT INDEXES PLIT ASCIZ 'UNIT',
IE, IE, IE, OPNCUNIT, 0),
%4500% XX(NUSER INDEXES PLIT ASCIZ 'USEROPEN',
%4500% IL, IL, NV, OPNCUSEROPEN, 1^CFANSI),
XX(PLIT ASCIZ 'VERSIO',
%2455% IL, IE, IE, OPNCVERSION, 1^CFANSI+1^CFVMS),
XX(KWDN INDEXES PLIT ASCIZ 'VERSION',
%2455% IL, IE, IE, OPNCVERSION, 1^CFANSI+1^CFVMS),
%2426% ! start of table entries without =
%2426% XX(NDIALOG INDEXES PLIT ASCIZ 'DIALOG',
%2455% IL, 0, 0, OPNCNEDIALOG, 1^CFANSI+1^CFVMS),
%2426% XX(PLIT ASCIZ 'DIALOGUE',
%2455% IL, 0, 0, OPNCNEDIALOG, 1^CFANSI+1^CFVMS),
%4500% XX(NNOSPAN INDEXES PLIT ASCIZ 'NOSPANBLOCKS',
%4500% IL, IL, 0, OPNCNOSPAN, 1^CFANSI),
%2426% XX(NREADO INDEXES PLIT ASCIZ 'READON',
%2426% IL, IL, 0, OPNCREADONLY,1^CFANSI+1^CFVMS),
%2426% XX(PLIT ASCIZ 'READONLY',
%2476% IL, IL, 0, OPNCREADONLY,1^CFANSI),
%4500% XX(NSHARE INDEXES PLIT ASCIZ 'SHARED',
%4526% IL, IL, 0, OPNCSHARED, 1^CFANSI+1^CFTOPS10),
$;
! table of keyword names for open/close/inquire statements
MACRO XX1(A,B,C,D,E,F) = A $;
BIND OPNKWD = PLIT(THEKEYS(XX1));
! table of inquire value types
MACRO XX2(A,B,C,D,E,F) = B $;
BIND INQUKVAL = PLIT(THEKEYS(XX2));
! table of close value types
MACRO XX3(A,B,C,D,E,F) = C $;
BIND CLOSKVAL = PLIT(THEKEYS(XX3));
! table of open value types
MACRO XX4(A,B,C,D,E,F) = D $;
BIND OPNKVAL = PLIT(THEKEYS(XX4));
! table of FOROTS keyword numbers
MACRO XX5(A,B,C,D,E,F) = E $;
BIND IOCKCODE = PLIT(THEKEYS(XX5));
! table of flags which determine whether any given keyword is to be
! flagged as an extension to Fortran-77, an incompatibility with VMS,
! or both.
MACRO XX6(A,B,C,D,E,F) = F $;
BIND KEYWFLAG = PLIT(THEKEYS(XX6));
GLOBAL ROUTINE BKSPST=
BEGIN
REGISTER R;
BIND DUM = PLIT( SP NAMES 'SPACE?0', FIL NAMES 'FILE?0' );
R _ BACKDATA;
LOOK4CHAR _ SP<36,7>;
DECR I FROM 1 TO 0
DO
BEGIN
IF LEXICAL(.GSTSSCAN) NEQ 0
THEN
BEGIN % GOT ONE %
%2247% IF FLAGEITHER !Compatibility check
%2247% THEN
%2247% IF .R EQL BKFILDATA
%2252% THEN CFLAGB((PLIT 'BACKFILE?0')<0,0>,E268);
IF SYNTAX(UTILSPEC) LSS 0 THEN RETURN .VREG;
RETURN BLDUTILITY(.R)
END;
R _ BKFILDATA; ! TRY FILE
LOOK4CHAR _ FIL<36,7>
END;
RETURN FATLEX(E12<0,0>); !MISSPELLED
END; ! of BKSPST
GLOBAL ROUTINE REWISTA=
%1677% BLDUTILITY(REWIDATA);
GLOBAL ROUTINE ENDFSTA=
%1677% BLDUTILITY(ENDFDATA);
GLOBAL ROUTINE FINDSTA=
%2252% BEGIN
%2252% IF FLAGANSI THEN WARNERR(.ISN,E239<0,0>); !Compatibility flagger
%1677% BLDUTILITY(FINDDATA)
%2252% END;
GLOBAL ROUTINE DELESTA=
!++
! FUNCTIONAL DESCRIPTION:
!
! To build a delete statement node and flag it as incompatible with ANSI
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! STK Points to the address of the block of specifiers built by
! KEYSCAN
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! None
!
!--
BEGIN ![4502] New
%4526% IF NOT FTTENEX THEN FATLEX (UPLIT ASCIZ 'DELETE statement',E322<0,0>);
IF FLAGANSI THEN WARNERR((PLIT ASCIZ 'DELETE')<0,0>,.ISN,E267<0,0>); !Compatibility flagger
BLDUTILITY(DELEDATA)
END;
ROUTINE CMPLXCONGEN(PTR,SIGNN)=
BEGIN
!BUILDS A COMPLEX CONSTANT NODE FROM DATA LIST
REGISTER
SIGNFLG,
BASE T1,
BASE T2;
LOCAL
BASE REALPT,
BASE IMAGPT;
! PROCESS REAL PART
T1 _ .PTR;
SIGNFLG _ .SIGNN;
IF .T1[ELMNT] NEQ 0 !IS IT SIGNED?
THEN
BEGIN
IF .T1[ELMNT] EQL 2 THEN SIGNFLG _ -1 -.SIGNN;
T1_.T1+1;
END;
REALPT_SIGNEDREAL(.T1[ELMNT1],.SIGNFLG);
! PROCESS IMAGINARY PART
SIGNFLG _ .SIGNN;
T1_.T1+2; !SKIP TO IMAG PART
IF .T1[ELMNT] NEQ 0
THEN
BEGIN
IF .T1[ELMNT] EQL 2 THEN SIGNFLG_ -1 -.SIGNN;
T1_.T1+1;
END;
IMAGPT _ SIGNEDREAL(.T1[ELMNT1],.SIGNFLG);
! NOW MAKE ACOMPLEX CONSTANT NODE
RETURN MAKECNST(COMPLEX,.REALPT,.IMAGPT);
END; ! of CMPLXCONGEN
ROUTINE SIGNEDREAL(CONST,SIGNFLG)=
BEGIN
!***************************************************************
! GIVEN A PTR TO A CONSTANT TABLE ENTRY FOR THE REAL OR
! IMAGINARY PART OF A COMPLEX CONST, (WHERE THAT PART MAY ITSELF
! BE ANY TYPE) RETURN THE SINGLE-WD REAL VALUE TO BE USED FOR
! THAT PART OF THE CONSTANT. THE REGISTER-VARIABLE "SIGNFLG" IS
! ASSUMED TO BE "TRUE" IF THE CONSTANT INDICATED BY "CONST"
! SHOULD BE NEGATED.
! SIGNN - IS THE SIGN OF THE TOTAL CONSTANT
!***************************************************************
MAP PEXPRNODE CONST;
C1H_.CONST[CONST1]; !HI ORDER PART
C1L_.CONST[CONST2]; !LOW ORDER PART
%(***IF CONST IS NOT REAL, CONVERT IT TO REAL. THE CONSTANT FOLDING
ROUTINE TAKES ITS ARG IN THE GLOBALS C1H,C1L***)%
IF .CONST[VALTYPE] NEQ REAL
THEN
BEGIN
COPRIX_KKTPCNVIX(REAL2,.CONST[VALTP2]); !INDEX INTO CONSTNT FOLDER
! FOR THE TYPE-CONV DESIRED
CNSTCM(); !CONVERT THE CONST IN C1H,C1L
! LEAVING RESULT IN C2H,C2L;
C1H_.C2H;
C1L_.C2L
END;
%(***ROUND THE 2 WD REAL TO A SINGLE-WD REAL***)%
IF .CONST[VALTYPE] NEQ DOUBLOCT
THEN
BEGIN !DONT ROUND DOUBLE-OCTAL
![761] Convert DP to Sp based on /GFLOATING
%[761]% IF .GFLOAT !INDEX INTO THE CONST FOLDER FOR ROUNDING
%[761]% THEN COPRIX_KGFRL ! DOUBLE-WD REAL TO SINGLE-WD REAL
%[761]% ELSE COPRIX_KDPRL;
CNSTCM(); !ROUND THE DOUBLE-WD REAL IN C1H-C1L, LEAVING
! RESULT IN C2H
C1H_ .C2H
END;
%(***IF THE VALUE SHOULD BE NEGATED, DO SO***)%
IF .SIGNFLG
THEN RETURN -.C1H
ELSE RETURN .C1H
END; ! of SIGNEDREAL
GLOBAL ROUTINE DATAGEN(CONLIST)=
!++
! FUNCTIONAL DESCRIPTION:
!
! Routine builds a list of DATA constants and keeps count for
! later use by the DATA list processing routines.
!
! FORMAL PARAMETERS:
!
! CONLIST List of the constants read in by the BNF
!
! IMPLICIT INPUTS:
!
! Unknown
!
! IMPLICIT OUTPUTS:
!
! Unknown
!
! ROUTINE VALUE:
!
! Returns a linked list of DATA constants.
!
! SIDE EFFECTS:
!
! Unknown
!
!--
BEGIN
MACRO ERR54 = ( FATLEX(E54<0,0>))$;
MACRO DNEG(X,Y)= ! Double precision negate
BEGIN
C1H _ X[CONST1]; !HIGH ORDER
C1l _ X[CONST2]; !LOW ORDER
COPRIX _ KDNEGB;
CNSTCM(); !CONVERT TO NEG
MAKECNST(Y,.C2H,.C2L)
END$;
LOCAL BASE CONNODE, ! Data constant node
BASE CONPTR, ! Pointer to the list of constants returned
COUNT, ! Number of words
DATCSIZ, ! Size for this constant (w/o repeat)
REPEAT, ! Repeat count (if any)
SIGNFLG; ! Set if negative sign was read
LABEL DAT1;
REGISTER
BASE T1,
BASE T2;
MAP BASE CONLIST;
CONPTR _ 0;
COUNT _ 0;
INCR CONITEM FROM .CONLIST TO .CONLIST+.CONLIST<LEFT> BY 2
DO
BEGIN ! Each constant
MAP BASE CONITEM;
REPEAT _ 1; !INITIALIZE
SIGNFLG _ 0;
! See if constant is:
!
! 1 Octal/Hexadecimal
! 2 Literal
! 3 [+/-] Number
%2461% ! If the constant is octal or hex, then the information
%2461% ! was put on the stack by an action routine. The parser
%2461% ! insists on putting the position of the production in
%2461% ! the grammar AFTER anything put on STK, so the
%2461% ! information is in a different order for this case.
%2461%
%2461% IF .CONITEM[ELMNT1] EQL 1
%2461% THEN
%2461% BEGIN ! Octal/hex constant
%2461%
%2461% ! Pointer to constant
%2461% T2 = .CONITEM[ELMNT]<RIGHT>;
%2461%
%2461% ! Count of number of words it uses
%2461% COUNT = .COUNT + (IF .T2[VALTYPE] EQL OCTAL
%2461% THEN 1 ! Single word
%2461% ELSE 2); ! Double word
%2461%
%2461% END ! Octal/hex constant
%2461% ELSE IF .CONITEM[ELMNT] EQL 2
%2461% THEN
BEGIN ! Literal
T2 _ .CONITEM[ELMNT1]; !PTR TO LITERAL STRING NODE
COUNT _ .COUNT + .T2[LITSIZ];
END ! Literal
%2461% ELSE
DAT1: BEGIN ! Number, CONITEM[ELMNT] = 3
! Ptr to 2 or 3 word set CONST [* CONST]
T1 _ .CONITEM[ELMNT1];
IF .T1[ELMNT] NEQ 0
THEN
BEGIN ! Signed constant
IF .T1[ELMNT] EQL 2 ! Minus
THEN SIGNFLG_-1 ELSE SIGNFLG_0;
T1 _ .T1+1; ! To get past the sign
END ! Signed constant
ELSE SIGNFLG _ 0;
! Now decide whether we have a constant or
! complex constant
IF .T1[ELMNT1] EQL 2
THEN
BEGIN ! Complex constant
T2 _ CMPLXCONGEN( .T1[ELMNT2] , .SIGNFLG );
COUNT _ .COUNT + 2;
SIGNFLG _ 0; !COMPLEX SIGNS ARE DONE
END ! Complex constant
ELSE
BEGIN ! Number
T1 _ .T1[ELMNT2]; !POINTER TO CONSTANT-OPTION
T2 _ .T1[ELMNT]; !PTR TO FIRST CONSTANT OR REPEAT COUNT
IF .T1[ELMNT1] NEQ 0
THEN
BEGIN ! Repeat count exists
! Check for errors. Non-integer
! or negative repeat counts are
! not allowed.
IF .T2[VALTYPE] NEQ INTEGER
THEN (ERR54; REPEAT _ 0; LEAVE DAT1);
%DO THIS IN CASE OF NEGATIVE PARAMETER VALUES%
IF .SIGNFLG NEQ 0
THEN T2 _ MAKECNST(INTEGER,0,-.T2[CONST2]);
IF .T2[CONST2] LSS 0
THEN (ERR54; REPEAT _ 0; LEAVE DAT1);
REPEAT _ .T2[CONST2]; !REPEAT VALUE
%[1032]% T2 _ .T1; !SAVE PTR
T1 _ .T1[ELMNT2]; !PTR TO REPEATED CONST OR LITERAL
%[1032]% SAVSPACE(.T2<LEFT>,.T2);
T2 _ .T1[ELMNT2]; !PTR TO ACTUAL CONSTANT OR LITSTRING NODE
! A repeat count has been
! processed, now do the constant
! to repeat.
! Have:
! 1 octhex constant
! 2 literal constant
! 3 [+/-] number
%2461% IF .T1[ELMNT2] EQL 1
%2461% THEN
%2461% BEGIN ! Octal/hex
%2461%
%2461% T2 _ .T1[ELMNT1]; ! Const
%2461% IF .T2[OPERSP]EQL OCTAL
%2461% THEN DATCSIZ = 1 ! 1 word
%2461% ELSE DATCSIZ = 2; ! 2 words
%2461%
%2461% END ! Octal/hex
%2461% ELSE IF .T1[ELMNT1] EQL 2
%2461% THEN
%2461% BEGIN ! Literal
DATCSIZ _ .T2[LITSIZ]
%2461% END ! Literal
%2461% ELSE IF .T1[ELMNT1] EQL 3
THEN
BEGIN ! Number
IF .T2[ELMNT] NEQ 0
THEN
BEGIN ! Signed number
IF .T2[ELMNT] EQL 2
THEN SIGNFLG_-1
ELSE SIGNFLG_0;
T2 _ .T2+1
END ! Signed number
ELSE SIGNFLG _ 0;
%NOW WHAT KIND OF CONSTANT DO WE HAVE%
IF .T2[ELMNT1] EQL 2
THEN
BEGIN %COMPLEX%
T2_ CMPLXCONGEN( .T2[ELMNT2] , .SIGNFLG );
COUNT _ .COUNT+2;
SIGNFLG _ 0
END
ELSE
BEGIN %REAL OR INTEGER OR DOUBLE%
T2 _ .T2[ELMNT2]; !CONSTANT LEXEME
DATCSIZ _ IF .T2[DBLFLG]
THEN 2
ELSE 1
END
END; ! Number
END ! Repeat count exists
ELSE
BEGIN ! No repeat
DATCSIZ _ IF .T2[DBLFLG] THEN 2 ELSE 1;
%[1032]% SAVSPACE(.T1<LEFT>,.T1);
END; ! No repeat
COUNT _ .COUNT + .DATCSIZ * .REPEAT;
IF .SIGNFLG NEQ 0 !NEGATE THE NUMBER
THEN IF .T2[VALTP1] EQL INTEG1
THEN T2 _ MAKECNST(INTEGER,0,-.T2[CONST2])
ELSE T2 _ DNEG(.T2,.T2[VALTYPE]);
%[1032]% END; ! Number
%[1032]%
%[1032]% T1 _ .CONITEM[ELMNT1];
%[1032]% SAVSPACE(.T1<LEFT>,.T1);
END; !Number
! Build and link a data constant node
NAME<LEFT> _ 2;
CONNODE _ CORMAN();
IF .CONPTR EQL 0
THEN (CONPTR<LEFT> _ CONPTR<RIGHT> _ .CONNODE)
ELSE
BEGIN
CONPTR[CLINK] _ .CONNODE;
CONPTR<RIGHT> _.CONNODE;
END;
CONPTR[DATARPT] _ .REPEAT;
CONPTR[DCONST] _ .T2;
END; ! Each constant
RETURN .COUNT^18+ .CONPTR<LEFT>;
END; ! of DATAGEN
GLOBAL ROUTINE DATASTA=
!++
! Processing for DATA statements
!--
BEGIN
REGISTER BASE T1;
REGISTER BASE R1:R2;
LOCAL ITEMLIST,CONLIST;
!SEMANTIC ANALYSIS BEGINS
[email protected][0]; !T1_LOC(DATASPEC OR LIST A,LINEND)
%1410% ! The optional comma preceding the first DATALIST is not allowed. It
%1410% ! is too hard to prevent it in the BNF syntax, so check here.
%1410% R1 _ .T1[ELMNT]; ! point to first DATALIST
%1410% IF .R1[ELMNT] NEQ 0 ! check for comma preceding it
%1410% THEN FATLEX(.LEXNAM[IDENTIFIER],.LEXNAM[COMMA],E0<0,0>);
%1410% ! "Found comma when expecting identifier"
INCR DAT FROM .T1 TO .T1+.T1<LEFT> DO
BEGIN !PROCESS LIST OF DATA SPECIFICATIONS
MAP BASE DAT;
R1 _ .DAT[ELMNT]; !PTR TO 3 ITEM LIST - 1.OPTIONAL COMMA [1410]
! 2.DATALIST PTR
! 3.CONLIST PTR
%1410% T1 _ .R1[ELMNT2]; !PROCESS CONLIST PTR FIRST FO COUNT NUMBER OF CONSTANTS
!T1 POINTS TO 3 WORD LIST (SLASH,CONLISTPTR,SLASH)
R2 _ .T1[ELMNT1]; !GET PTR TO LIST OF CONSTANT SPECS
SAVSPACE (.T1<LEFT>,.T1); !GET BACK SPACE
CONLIST _ DATAGEN(.R2);
SAVSPACE(.R2<LEFT>,.R2);
!
!NOW PROCESS LIST OF DATA ITEM SPECIFICATIONS
!USE THE SAME ROUTINE AS USED BY IO LISTS AND RETURN PTR
!TO SAME KIND OF LIST STRUCTURE AS IO LISTS
!
TYPE _ DATALST; !SIGNAL DATA STATEMENT TO DATALIST ROUTINE
SP _ 0; !RESET FOR USE IN DATALIST
%1410% ITEMLIST _ DATALIST(.R1[ELMNT1]); !USEING FIRST ITEM POINTED TO BY R1
DATASUBCHK(.ITEMLIST<LEFT>,0,0); !CHECK SUBSCRIPTS ON LIST ITEMS FOR VALIDITY
SAVSPACE(.R1<LEFT>,.R1); !RETRIEVE SOME SPACE
!
!NOW BUILD A DATA STATEMENT NODE AND LINK TO ANY PREVIOUS ONES
!
NAME _ DATATAB; !ID OF DATA TABLE FOR NEWENTRY
R2 _ NEWENTRY();
!FILL IN PTRS TO LISTS IN DATA NODE
!
R2[DATITEMS] _ .ITEMLIST<LEFT>; R2[DATCONS] _ .CONLIST;
R2[DATCOUNT] _ .CONLIST<LEFT>; !NUMBER OF CONSTANTS SPECIFIED
R2[DATISN]_.ISN; !STMNT NUMBER (NEEDED FOR ERROR MESSAGES
! IN ALLOCATION ROUTINE)
END; !OF INCR LOOP
T1 _ @.STK[0]; SAVSPACE(.T1<LEFT>,.T1); SAVSPACE(0,.STK[0]);
.VREG
END; ! of DATASTA
ROUTINE KEYEQ =
!++
! FUNCTIONAL DESCRIPTION:
!
! parses KEY=(<kspec> {, <kspec>}) in OPEN statements
! where kspec is <integer expression> : <integer expression> [: <type>]
! where type is INTEGER | CHARACTER
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! LEXL current lexeme
!
! IMPLICIT OUTPUTS:
!
! LOOK4CHAR Pointer to character string to look for
!
! ROUTINE VALUE:
!
! IOKEY field of source tree node for open stm
!
! SIDE EFFECTS:
!
! None
!
!--
! New [4500] MEM
BEGIN
BIND
INT = UPLIT(ASCIZ 'INTEGER')<36,7>,
CHR = UPLIT(ASCIZ 'CHARACTER')<36,7>;
LOCAL OPNKEYLIST KEYTAB; ! list of keys
LOCAL BASE V; ! general scratch
LOCAL COUNT, ! number of keys
MORE; ! we have another key coming
! allocate space for max number of keys
NAME<LEFT> = MAXKEYS*KEYSIZE;
KEYTAB = CORMAN();
! we should start with a lparen
LEXL = LEXEMEGEN();
IF .LEXL<LEFT> NEQ LPAREN
THEN RETURN FATLEX(.LEXNAM[LPAREN],.LEXNAM[.LEXL<LEFT>],E0<0,0>);
COUNT=0;
MORE=TRUE;
DO
BEGIN
COUNT = .COUNT+1;
EXPRESS(); ! get integer expression
KEYTAB[.COUNT,KEYLOW] = V = .STK[.SP];
SP = .SP - 1;
IF .V[VALTYPE] EQL CHARACTER
THEN RETURN FATLEX(E164<0,0>); ! Character expression used where
! numeric expression required
IF .LEXL<LEFT> NEQ COLON ! colon should follow integer expression
THEN RETURN FATLEX(.LEXNAM[COLON],.LEXNAM[.LEXL<LEFT>],E0<0,0>);
LEXL = LEXEMEGEN();
EXPRESS(); ! get another integer expression
KEYTAB[.COUNT,KEYHIGH] = V = .STK[.SP];
SP = .SP - 1;
IF .V[VALTYPE] EQL CHARACTER
THEN RETURN FATLEX(E164<0,0>); ! Character expression used where
! numeric expression required
IF .LEXL<LEFT> EQL COLON ! optionally can have : INTEGER
THEN ! or : CHARACTER
BEGIN
LOOK4CHAR = CHR;
IF LEXICAL(.GSTSSCAN) EQL 0
THEN ! CHARACTER not found
BEGIN
LOOK4CHAR = INT;
IF (V = LEXICAL(.GSTSSCAN)) EQL 0
THEN RETURN FATLEX(V,E320<0,0>) ! INTEGER not found
ELSE KEYTAB[.COUNT,KEYTYPE] = INTEGER;
END
ELSE KEYTAB[.COUNT,KEYTYPE] = CHARACTER;
LEXL = LEXEMEGEN();
END
ELSE KEYTAB[.COUNT,KEYTYPE] = CHARACTER; ! default = CHARACTER
IF .LEXL<LEFT> EQL COMMA
THEN
BEGIN
IF .COUNT LSS MAXKEYS THEN LEXL = LEXEMEGEN()
ELSE RETURN FATLEX(E317<0,0>); ! Too many keys
END
ELSE MORE = FALSE;
END
WHILE .MORE;
! we should end with a rparen
IF .LEXL<LEFT> NEQ RPAREN
THEN RETURN FATLEX(.LEXNAM[RPAREN],.LEXNAM[.LEXL<LEFT>],E0<0,0>)
ELSE LEXL = LEXEMEGEN();
KEYTAB[NUMKEYS] = .COUNT; ! store count
! return space in rest of KEYTAB
SAVSPACE((MAXKEYS - .COUNT)*KEYSIZE -1,KEYTAB[.COUNT+1]);
! return KEYTAB
RETURN .KEYTAB
END;
ROUTINE COMPARE(TBLINDEX) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Compare will compare KEYBUFFER and OPNKWD[.TBLINDEX] to test if they
! are equivalent.
!
! FORMAL PARAMETERS:
!
! TBLINDEX present index into OPNKWD
!
! IMPLICIT INPUTS:
!
! KEYBUFFER contains an open/close/inquire specifier which was found
! in LEXICA
! KEYLENGTH number of characters in KEYBUFFER
! OPNKWD table of open/close/inquire keywords
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! If KEYBUFFER < OPNKWD[.TBLINDEX] then compare will return 0
! = 1
! > 2
!
! SIDE EFFECTS:
!
! None
!
!--
! New [2370] MEM
BEGIN
REGISTER ITEM; ! ptr to present word in OPNKWD[.TBLINDEX] being compared
REGISTER NWORDS; ! number of words that have to be compared since
! OPNKWD[.TBLINDEX] may be up to 4 words long
ITEM = .OPNKWD[.TBLINDEX];
NWORDS = @(.ITEM-1)-1; ! (.ITEM-1) fetches the number of words in this
! table entry from the count in the plit
! one more must be subtracted since we are
! counting from 0 instead of from one
INCR INDEX FROM 0 TO .NWORDS
DO
BEGIN
IF .KEYBUFFER[.INDEX] LSS @.ITEM
THEN RETURN 0 ! KEYBUFFER < OPNKWD[.TBLINDEX]
ELSE IF .KEYBUFFER[.INDEX] GTR @.ITEM
THEN RETURN 2 ! KEYBUFFER > OPNKWD[.TBLINDEX]
ELSE ITEM = .ITEM + 1; ! set item to point to next
! word in OPNKWD[.TBLINDEX]
END;
IF .KEYLENGTH/5 GTR .NWORDS ! KEYLENGTH = number of characters in
THEN RETURN 0 ! KEYBUFFER
! KEYLENGTH/5 = number of words in
! KEYBUFFER
! if KEYLENGTH/5 > NWORDS
! then KEYBUFFER > OPNKWD[TBLINDEX]
ELSE RETURN 1; ! KEYBUFFER = OPNKWD[TBLINDEX]
END;
ROUTINE SEARCH(FIRST,LAST) =
!++
! FUNCTIONAL DESCRIPTION:
!
! search performs a binary search to see if KEYBUFFER is in OPNKWD
!
! FORMAL PARAMETERS:
!
! FIRST index to first entry in part of table (OPNKWD) to be searched
! LAST index to last entry in part of table (OPNKWD) to be searched
!
! IMPLICIT INPUTS:
!
! KEYBUFFER contains an open/close/inquire specifier which was found
! in LEXICA
! OPNKWD table of open/close/inquire keywords
!
!
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! search will return -1 if KEYBUFFER is not found in OPNKWD
! otherwise, search will return the index of the entry in OPNKWD
! which matches KEYBUFFER
!
! SIDE EFFECTS:
!
! None
!
!--
!R ewritten [4500] MEM
BEGIN
REGISTER MID, ! index to middle of part of table to be searched
ISEQUAL; ! = 0 if KEYBUFFER < OPNKWD[MID]
! = 1 if KEYBUFFER = OPNKWD[MID]
! = 2 if KEYBUFFER > OPNKWD[MID]
MID=(.FIRST + .LAST)/2;
WHILE (.MID LEQ .LAST) AND (.MID GEQ .FIRST)
DO
BEGIN
IF (ISEQUAL=COMPARE(.MID)) EQL 1
THEN RETURN .MID ! KEYBUFFER = OPNKWD[MID] so return MID
ELSE IF .ISEQUAL EQL 0
THEN LAST = .MID-1 ! KEYBUFFER < OPNKWD[MID] so search
! between OPNKWD[FIRST] and
! OPNKWD[MID-1]
ELSE FIRST = .MID+1; ! KEYBUFFER > OPNKWD[MID] so search
! between OPNKWD[MID+1] and
! OPNKWD[LAST]
MID=(.FIRST + .LAST)/2;
END;
RETURN -1; ! KEYBUFFER is not in OPNKWD
END;
GLOBAL ROUTINE OPENCLOSE(OPENCLOSDATA)=
BEGIN
%2200% ! modified for INQUIRE by TFV, 16-Mar-83
! Routine to parse the open keyword list (olist) in OPEN, CLOSE and
! INQUIRE statements. The list can have the following forms:
!
! (u,keywords)
! (keywords)
!
! where
! u is an integer expression specifying the unit number
! keywords is a list of either KEYWORD=EXPRESSION or just KEYWORD
!
! The keywords DIALOG, READONLY and SHARED cause problems if they are
! specified first in the keyword list because they are not followed
! by =. Therefore it is ambiguous whether they are a keyword or a variable
! name specifying the unit number. READONLY is not a valid variable
! name so it is parsed as a keyword. DIALOG and SHARED are parsed as a
! unit expression.
!
! OPEN and CLOSE must have a unit specifier. INQUIRE must have either a
! unit or a file specifier, but not both.
%4500% REGISTER BASE K:V;
%4500% REGISTER INDEX;
%4500% LOCAL BASE NODE:KEYINFO;
LOCAL FIRSTP;
LABEL DLP;
%4500% OWN OPNVAL [MAXKWD+1];! value of keyword, pointer to expression node
%4500% ! into the entries between maxotskwd and maxkwd
%4500% ! will be stored the keyword values for the
%4500% ! VMS keywords that we accept but ignore, since
%4500% ! we ignore what is after maxotsword there is no
%4500% ! point to initially zero it out below
%4500% KEYINFO = 0; ! no KEY= info
FIRSTP = -1; ! FIRSTP is true iff we are at first item in
! list
DECR I FROM MAXKWD+1 TO 0 DO OPNVAL[.I] = 0; ! clear keyword value table
IF LEXEMEGEN() NEQ LPAREN^18 THEN RETURN ERR0V(LPARPLIT);
! read left paren to start list
DO
BEGIN ! loop until right paren
K = LEXICAL(.GSTKSCAN); ! look for "KEYWORD="
IF .K EQL 0 ! keyword not found
THEN ! check for DIALOG, SHARED and READONLY
BEGIN ! not keyword
IF .FIRSTP ! if first thing in list
THEN ! must be unit expression
BEGIN ! unit expression
%4500% INDEX = NUNIT; ! set keyword number
IF EXPRESS() LSS 0 THEN RETURN .VREG; ! read expression
V = .STK[.SP]; ! pop expression off stack
SP = .SP - 1;
IF .V[VALTYPE] NEQ INTEGER ! convert to integer
THEN V = CNVNODE(.V,INTEGER,0); ! if necessary
END ! unit expression
ELSE
BEGIN
LOOK4CHAR = (UPLIT ASCIZ 'READONLY')<36,7>;
%2424% IF LEXICAL(.GSTSSCAN) NEQ 0
THEN
BEGIN
%2424% IF (.OPENCLOSDATA EQL INQUDATA)
%2523% OR (.OPENCLOSDATA EQL CLOSDATA)
%2424% THEN RETURN FATLEX(KEYBUFFER,E183<0,0>)
ELSE
BEGIN
%4500% INDEX = NREADO+1; ! set keyword number
V = -1; ! set keyword value (none)
END;
END
ELSE
BEGIN
LOOK4CHAR = (UPLIT ASCIZ 'READON')<36,7>;
%2424% IF LEXICAL(.GSTSSCAN) NEQ 0
%2424% THEN
%2424% BEGIN
%2424% IF (.OPENCLOSDATA EQL INQUDATA)
%2523% OR (.OPENCLOSDATA EQL CLOSDATA)
%2424% THEN RETURN FATLEX(KEYBUFFER,E183<0,0>)
%2424% ELSE
%2424% BEGIN
%4500% INDEX = NREADO; ! set keyword number
%2424% V = -1; ! set keyword value (none)
%2424% END;
%2424% END
ELSE
BEGIN ! either DIALOG (or DIALOGUE) without = or error
%2424% LOOK4CHAR = (UPLIT ASCIZ 'DIALOGUE')<36,7>;
%2424% IF LEXICAL(.GSTSSCAN) NEQ 0
%2424% THEN
%2424% BEGIN
%2424% IF .OPENCLOSDATA EQL INQUDATA
%2424% THEN RETURN FATLEX(KEYBUFFER,E183<0,0>)
%2424% ELSE
%2424% BEGIN
%4500% INDEX = NDIALOG+1; ! set keyword number
%2424% V = -1; ! set keyword value (none)
%2424% END;
%2424% END
%2424%
%2424% ELSE
%2424% BEGIN
LOOK4CHAR = (UPLIT ASCIZ 'DIALOG')<36,7>;
IF LEXICAL(.GSTSSCAN) NEQ 0
THEN
BEGIN
%2424% IF .OPENCLOSDATA EQL INQUDATA
%2424% THEN RETURN FATLEX(KEYBUFFER,E183<0,0>)
ELSE
BEGIN
%4500% INDEX = NDIALOG; ! set keyword number
V = -1; ! set keyword value (none)
END;
END
%4500% ELSE
%4500% BEGIN
%4500% LOOK4CHAR = (UPLIT ASCIZ 'SHARED')<36,7>;
%4500% IF LEXICAL(.GSTSSCAN) NEQ 0
%4500% THEN
%4500% BEGIN
%4500% IF (.OPENCLOSDATA EQL INQUDATA)
%4500% OR (.OPENCLOSDATA EQL CLOSDATA)
%4500% THEN RETURN FATLEX(KEYBUFFER,E183<0,0>)
%4500% ELSE
%4500% BEGIN
%4500% INDEX = NSHARE; ! set keyword number
%4500% V = -1; ! set keyword value (none)
%4500% END;
%4500% END
%4500% ELSE
%4500% BEGIN
%4500% LOOK4CHAR = (UPLIT ASCIZ 'NOSPANBLOCKS')<36,7>;
%4500% IF LEXICAL(.GSTSSCAN) NEQ 0
%4500% THEN
%4500% BEGIN
%4500% IF (.OPENCLOSDATA EQL INQUDATA)
%4500% OR (.OPENCLOSDATA EQL CLOSDATA)
%4500% THEN RETURN FATLEX(KEYBUFFER,E183<0,0>)
%4500% ELSE
%4500% BEGIN
%4500% INDEX = NNOSPAN; ! set keyword number
%4500% V = -1; ! set keyword value (none)
%4500% END;
%4500% END
ELSE
BEGIN ! error - found whatever when expecting keyword
LEXL = LEXEMEGEN();
RETURN ERR0L (UPLIT ASCIZ 'keyword');
END; ! error - found whatever when expecting keyword
%4500% END; ! either NOSPANBLOCKS or error
%4500% END; ! either SHARED or error
END; ! either DIALOG, SHARED or error
END; ! either DIALOGUE, DIALOG, SHARED or error
END; ! either READON, DIALOGUE, DIALOG, SHARED or error
END; ! either READONLY, READON, DIALOGUE, DIALOG, SHARED or error
END ! not keyword
ELSE
BEGIN ! keyword
%4500% INDEX = SEARCH(0,KWDN); ! search for KEYBUFFER in OPNKWD
%2370% ! if it is found then its index is returned
%2370% ! otherwise -1 is returned
%4500% IF .INDEX LSS 0 ! if keyword not found
%2370% THEN RETURN FATLEX(KEYBUFFER,E183<0,0>); ! say so and abort statement
%2200% ! dispatch on the legal values for this keyword in this
%2200% ! type of statement, i.e. OPEN and CLOSE vs. INQUIRE
%2200% CASE (IF .OPENCLOSDATA EQL INQUDATA
%2370% THEN .INQUKVAL[.INDEX] ! INQUIRE statement
%2523% ELSE IF .OPENCLOSDATA EQL CLOSDATA
%2523% THEN .CLOSKVAL[.INDEX] ! CLOSE statement
%2523% ELSE .OPNKVAL[.INDEX]) ! OPEN statement
%2200% OF SET
%2200% ! illegal keyword for this statement, say so and abort
%2200% BEGIN
%2370% RETURN FATLEX(KEYBUFFER,E183<0,0>)
%2200% END;
! character expression, numeric scalar, or numeric arrayref
BEGIN
IF EXPRESS() LSS 0 THEN RETURN .VREG;
V = .STK[.SP]; ! pop expression off stack
SP = .SP - 1;
! Any character expression is OK. Numeric expression
! must be scalar or arrayref. More complex expressions
! are hereby decreed meaningless, unVMSish and illegal.
IF .V[VALTYPE] NEQ CHARACTER
THEN IF .V[OPRCLS] EQL DATAOPR THEN %OK%
ELSE IF .V[OPRCLS] EQL ARRAYREF THEN %OK%
%2370% ELSE FATLEX(KEYBUFFER,E299<0,0>);
! "Illegal <keyword> specifier"
END;
! integer expression
BEGIN
%4500% IF .INDEX EQL NKEY THEN KEYINFO = KEYEQ()
%4500% ELSE
%4500% BEGIN
IF EXPRESS() LSS 0 THEN RETURN .VREG;
V = .STK[.SP]; ! pop expression off stack
SP = .SP - 1;
! Convert numeric expressions to integer if necessary.
! Character expressions are an error, except convert
! character constants to hollerith.
IF .V[VALTYPE] EQL CHARACTER
THEN IF .V[OPERATOR] EQL CHARCONST
THEN
%2200% BEGIN
%2200% WARNLEX(E212<0,0>);
%2200% ! CHARACTER constant used where
%2200% ! numeric expression required
%2200% V[OPERATOR] = HOLLCONST
%2200% END
ELSE FATLEX(E164<0,0>)
! Character expression used where
! numeric expression required
%2200% ELSE IF .V[OPERATOR] EQL HOLLCONST
%2200% THEN WARNLEX(E215<0,0>)
%2200% ! HOLLERITH constant used where
%2200% ! numeric expression required
%2200% ELSE IF .V[VALTYPE] NEQ INTEGER
THEN V = CNVNODE(.V,INTEGER,0);
%4500% END;
END;
% char expr or numeric array name %
BEGIN
FLGREG<FELFLG> = 1; ! allow bare array names
IF EXPRESS() LSS 0 THEN RETURN .VREG;
V = .STK[.SP]; ! pop expression off stack
SP = .SP - 1;
! If expression is numeric, it must be an array name.
! Use NAMREF to check this. If expression is character,
! it can be anything but an array or function name.
IF .V[VALTYPE] NEQ CHARACTER
%1676% AND .V[VALTYPE] NEQ HOLLERITH
THEN IF .V[OPRCLS] EQL DATAOPR
THEN NAMREF(ARRAYNM1,.V)
%2511% ELSE FATLEX(UPLIT'array or character expression',KEYBUFFER,E305<0,0>)
ELSE IF .V[OPRSP1] GEQ ARRAYNM1
%2511% THEN FATLEX(UPLIT'array or character expression',KEYBUFFER,E305<0,0>);
END;
% label %
BEGIN
LABELS();
NONIOINIO = 1;
V = LEXL = LEXEMEGEN(); ! read label
NOLABELS();
NONIOINIO = 0;
IF .V<LEFT> NEQ LABELEX ! check that it is
THEN RETURN ERR0L(.LEXNAM[LABELEX]); ! a label
END;
%2200% % char variable %
BEGIN
IF SYNTAX(VARIABLESPEC) LSS 0 THEN RETURN .VREG;
V = BLDVAR(.STK[.SP]); ! pop variable off stack
SP = .SP - 1;
IF .V[OPRCLS] EQL ARRAYREF ! call NAMSET; this stmt
THEN NAMSET(ARRAYNM1,.V[ARG1PTR]) ! modifies the
ELSE NAMSET(VARIABL1,.V); ! variable
%2200% IF .V[VALTYPE] NEQ CHARACTER ! must be type char
%2200% THEN FATLEX (UPLIT'CHARACTER', .V[IDSYMBOL], E196<0,0>);
END;
% integer variable %
BEGIN
IF SYNTAX(VARIABLESPEC) LSS 0 THEN RETURN .VREG;
V = BLDVAR(.STK[.SP]); ! pop variable off stack
SP = .SP - 1;
%1622% IF .V[OPRCLS] EQL ARRAYREF ! call NAMSET; this stmt
%1622% THEN NAMSET(ARRAYNM1,.V[ARG1PTR]) ! modifies the
ELSE NAMSET(VARIABL1,.V); ! variable
IF .V[VALTYPE] NEQ INTEGER ! must be type integer
THEN FATLEX (UPLIT'INTEGER', .V[IDSYMBOL], E196<0,0>);
END;
%2200% % logical variable %
BEGIN
IF SYNTAX(VARIABLESPEC) LSS 0 THEN RETURN .VREG;
V = BLDVAR(.STK[.SP]); ! pop variable off stack
SP = .SP - 1;
IF .V[OPRCLS] EQL ARRAYREF ! call NAMSET; this stmt
THEN NAMSET(ARRAYNM1,.V[ARG1PTR]) ! modifies the
ELSE NAMSET(VARIABL1,.V); ! variable
%2200% IF .V[VALTYPE] NEQ LOGICAL ! must be type logical
%2200% THEN FATLEX (UPLIT'LOGICAL', .V[IDSYMBOL], E196<0,0>);
END;
%4500% %no alloc fnname%
%4500% BEGIN
%4500% LEXL = LEXEMEGEN();
%4500% V = .LEXL<RIGHT>;
%4500% IF .V[OPR1] NEQ FNNAMFL
%4551% THEN FATLEX(UPLIT'FUNCTION NAME',.V[IDSYMBOL],E196<0,0>);
%4500% V[IDATTRIBUT(NOALLOC)] = 1;
%4500% END;
TES;
END; ! keyword
%4500% IF .OPNVAL[.IOCKCODE[.INDEX]] NEQ 0 ! if keyword already specified, error
%4500% THEN FATLEX (.OPNKWD[.INDEX], E182<0,0>);
! "KEYWRD may only be specified once"
%4500% IF .INDEX NEQ NKEY ! if keyword is not KEY=
%4500% THEN OPNVAL[.IOCKCODE[.INDEX]] = .V; ! set value of keyword
FIRSTP = 0; ! not first in list any more
%4500% IF .IOCKCODE[.INDEX] GTR MAXOTSKWD ! VMS keyword is ignored
%4500% THEN WARNLEX(.OPNKWD[.INDEX],E316<0,0>);
%4526% IF NOT FTTENEX
%4526% THEN
%4526% BEGIN
%4526% IF (1^CFTOPS10 AND .KEYWFLAG[.INDEX]) NEQ 0
%4526% THEN FATLEX (.OPNKWD[.INDEX],E322<0,0>)
%4526% ELSE IF (1^CFVTOPS10 AND .KEYWFLAG[.INDEX]) NEQ 0
%4526% THEN
%4526% BEGIN
%4526% MACRO X (LITVAL) = (UPLIT ASCIZ 'LITVAL')<36,7>$;
%4526%
%4526% IF .INDEX EQL (NACCESS)
%4526% THEN IF .V[OPR1] EQL CONSTFL
%4526% THEN IF CFSEARCH(.V,UPLIT(X (KEYED),0))
%4526% THEN FATLEX (UPLIT ASCIZ 'ACCESS=''KEYED''',E322<0,0>)
%4526% END;
%4526% END;
%2274% IF FLAGEITHER ! If flagging incompatibilities, check keywords and their values
%4500% THEN CFCHECK(.INDEX,.OPNKWD[.INDEX],.V,.OPENCLOSDATA);
IF .LSAVE NEQ 0 THEN LSAVE = 0 ELSE LEXL = LEXEMEGEN(); ! read lexeme
END
WHILE .LEXL<LEFT> EQL COMMA; ! while comma-separated list
IF .LEXL<LEFT> NEQ RPAREN THEN RETURN ERR0L(RPARPLIT); ! read terminating )
IF LEXEMEGEN() NEQ LINEND^18 THEN RETURN ERR0V(EOSPLIT); ! followed by EOS
%2200% ! Check that UNIT (or FILE for INQUIRE) got specified else
%2200% ! return fatal error now.
%2200% IF .OPENCLOSDATA NEQ INQUDATA
%2200% THEN
%2200% BEGIN ! OPEN/CLOSE
%4500% IF .OPNVAL[.IOCKCODE[NUSER]] EQL 0
%4500% THEN IF .OPNVAL[.IOCKCODE[NUNIT]] EQL 0
%2424% THEN RETURN FATLEX (UPLIT'specified',.(OPNKWD+NUNIT),E300<0,0>);
%2200% END ! OPEN/CLOSE
%2200% ELSE
%2200% BEGIN ! INQUIRE
%2426% IF .OPNVAL[.IOCKCODE[NUNIT]] EQL 0 !No unit specified
%2200% THEN
%2200% BEGIN ! No unit specifier
%2426% IF .OPNVAL[.IOCKCODE[NFILE]] EQL 0 !No file specified
%4500% THEN IF .OPNVAL[.IOCKCODE[NDFILE]] EQL 0!no defaultfile
%2200% THEN RETURN FATLEX(E213<0,0>);
%2200% END ! No unit specifier
%2200% ELSE ! unit specifier - check for file specifier too
%2426% IF .OPNVAL[.IOCKCODE[NFILE]] NEQ 0
%2200% THEN RETURN FATLEX(E214<0,0>); ! both unit and file
%2200% END; ! INQUIRE
%2455% ! Since VMS default file names differ from ours, if we are flagging
%2455% ! VMS incompatibilities we put out a warning if no file name was
%2274% ! specified in an OPEN statement.
%2455% IF FLAGVMS
%2274% THEN
%2274% IF.OPENCLOSDATA EQL OPENDATA AND
%2426% .OPNVAL[.IOCKCODE[NFILE]] EQL 0 AND .OPNVAL[.IOCKCODE[NNAME]] EQL 0
%4500% AND .OPNVAL[.IOCKCODE[NDFILE]] EQL 0
%2455% THEN WARNLEX (E226<0,0>); ! VMS has different default file name
! Make a statement node and fill it in
NAME = IDOFSTATEMENT = .OPENCLOSDATA;
NAME<RIGHT> = SORTAB;
%4500% NODE = NEWENTRY(); ! NODE points to empty statement node
%4500% NODE[IOUNIT] = .OPNVAL[.IOCKCODE[NUNIT]]; ! set UNIT=
%4500% NODE[IOFILE] = .OPNVAL[.IOCKCODE[NFILE]]; ! set FILE=
%4500% NODE[IOERR] = .OPNVAL[.IOCKCODE[NERR]]; ! set ERR=
%4500% NODE[IOIOSTAT] = .OPNVAL[.IOCKCODE[NIOSTAT]]; ! set IOSTAT=
! clear values out of table
%2426% OPNVAL[.IOCKCODE[NUNIT]] = OPNVAL[.IOCKCODE[NFILE]]
%2426% = OPNVAL[.IOCKCODE[NERR]] = OPNVAL[.IOCKCODE[NIOSTAT]] = 0;
%4500% IF .NODE[IOUNIT] NEQ 0
%2200% THEN
%2200% BEGIN
%4500% K = .NODE[IOUNIT]; ! set UNIT expression parent pointer
IF .K[OPRCLS] NEQ DATAOPR
%4500% THEN K[PARENT] = .NODE;
%2200% END;
%4500% IF .NODE[IOFILE] NEQ 0
%2200% THEN
%2200% BEGIN
%4500% K = .NODE[IOFILE]; ! set FILE expression parent pointer
IF .K[OPRCLS] NEQ DATAOPR
%4500% THEN K[PARENT] = .NODE;
%2200% END;
%4500% IF .NODE[IOIOSTAT] NEQ 0
%2200% THEN
%2200% BEGIN
%4500% K = .NODE[IOIOSTAT]; ! set IOSTAT expression parent pointer
IF .K[OPRCLS] NEQ DATAOPR
%4500% THEN K[PARENT] = .NODE;
%2200% END;
NODE[IOKEY] = .KEYINFO; ! store IOKEY into NODE
! Count keywords and copy into their block
V = 0; ! V gets keyword count
DECR I FROM MAXOTSKWD TO 0 DO
IF .OPNVAL[.I] NEQ 0 THEN V = .V + 1;
IF .V GTR 0
THEN
BEGIN ! copy keywords into block
%4500% NAME<LEFT> = NODE[OPSIZ] = .V; ! set keyword count
%4500% NODE[OPLST] = V = CORMAN(); ! get block, store its address
DECR I FROM MAXOTSKWD TO 0 DO ! copy from OPNVAL into block
IF .OPNVAL[.I] NEQ 0
THEN
BEGIN
K = .OPNVAL[.I]; ! copy expression ptr
(.V)<RIGHT> = (IF .K LSS 0 THEN 0 ELSE .K);
%2370% (.V)<LEFT> = .I; ! set Forots code
%1571% IF .K GEQ 0 ! unless DIALOG or READONLY
THEN IF .K[OPRCLS] NEQ DATAOPR ! set parent pointer if
%4500% THEN K[PARENT] = .NODE; ! subnode is an expression
V = .V + 1; ! next keyword
END;
END; ! copy keywords into block
END; ! of OPENCLOSE
ROUTINE CFSEARCH (VALUE,TABLE) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Search TABLE for entry containing VALUE
!
! FORMAL PARAMETERS:
!
! TABLE is the address of a list of pointers to sixbit values.
! VALUE is a pointer to the expression node containing the character
! constant to be found in the table.
!
! IMPLICIT INPUTS:
!
! CONST1 entry in CONTAB
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! True if VALUE is found in TABLE, False otherwise
!
! SIDE EFFECTS:
!
! None
!
!--
!New [2274] AlB
BEGIN
REGISTER
TPTR, ! Byte pointer to table value
VPTR, ! Byte pointer to value for which we search
V, ! Character from value
T; ! Character from table
LOCAL
BASE CONTAB, ! Entry in constant table
CONSTV; ! Byte pointer to constant value
LABEL INNERLOOP;
CONTAB=.VALUE; ! Construct a byte pointer to
CONSTV=(CONTAB[CONST1])<36,7>; ! the character string to be found
WHILE (TPTR = ..TABLE) NEQ 0 DO ! Zero implies end of list
BEGIN
VPTR=.CONSTV;
INNERLOOP: ! Try to match current table entry
WHILE (T = SCANI(TPTR)) NEQ 0 DO ! Entry is delimited by null byte
BEGIN
V=SCANI(VPTR); ! Character from VALUE
IF .V GTR "Z" THEN V=.V-32; ! Lower- to Upper case
IF .V NEQ .T THEN LEAVE INNERLOOP !No match
END;
IF .T EQL 0
THEN RETURN TRUE; ! Match with current table entry
TABLE=.TABLE+1 ! Try next table entry
END;
RETURN FALSE ! VALUE does not match any entry in TABLE
END; ! of CFSEARCH
ROUTINE CFCHECK (KX,KNAME,KVALUE,STYPE) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Check for compatibility of an OPEN/CLOSE/INQUIRE keyword with
! Fortran-77 and/or VMS.
! This routine is entered if and only if incompatibilities are
! being flagged.
!
! FORMAL PARAMETERS:
!
! KX is the index into the keyword tables.
! KNAME is pointer to the name of the keyword.
! KVALUE is pointer to the value expression node
! STYPE is type of statement (OPEN, CLOSE or INQUIRE)
!
! IMPLICIT INPUTS:
!
! Value of the flagger bits in F2 (FLAGANSI and FLAGVMS)
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! Compiler warning messages may be issued.
!
!--
!New [2274] AlB
BEGIN
%2316% MACRO X (LITVAL) = (UPLIT ASCIZ 'LITVAL')<36,7>$;
! Table of ACCESS values acceptable to Fortran-77
BIND ACCESSA = UPLIT (
X (DIRECT),
X (SEQUENTIAL),
0);
! Table of ACCESS values acceptable to VMS
BIND ACCESSV = UPLIT (
X (APPEND),
X (DIRECT),
%4500% X (KEYED),
X (SEQUENTIAL),
0);
! Table of STATUS values acceptable to Fortran-77 on OPEN
BIND STATUSO = UPLIT (
X (NEW),
X (OLD),
X (SCRATCH),
X (UNKNOWN),
0);
! Table of STATUS values acceptable on CLOSE
BIND STATUSC = UPLIT (
X (DELETE),
X (KEEP),
0);
! Table of CARRIAGECONTROL values acceptable to VMS
BIND CARRIAGEV = UPLIT (
X (FORTRAN),
X (LIST),
0);
! Table of DISPOSE values acceptable to VMS
BIND DISPOSEV = UPLIT (
X (DELETE),
X (KEEP),
X (PRINT),
X (SAVE),
0);
![4500] Table of ORGANIZATION values acceptable to VMS
BIND ORGANIV = UPLIT (
X (INDEXED),
X (RELATIVE),
X (SEQUENTIAL),
0);
LOCAL
KF, ! Conditions to be tested
KTABLE, ! Pointer to table to be searched
BASE KV, ! Pointer to keyword value
PREFIX; ! The prefix for any warning
KV=.KVALUE; ! Pointer to keyword value
!Retain only conditions to be tested
KF = .KEYWFLAG[.KX] AND
%2455% (FLAGANSI*(1^CFANSI + 1^CFVANSI) + FLAGVMS*(1^CFVMS + 1^CFVVMS));
IF .KF<CFVANSI,1>
THEN
BEGIN ! Extra processing for Fortran-77
IF .KX EQL (NFILE)
THEN !FILE keyword
BEGIN
KF=.KF - 1^CFVANSI; ! Turn off 'keyword value'
IF .STYPE EQL CLOSDATA ! If it is CLOSE,
THEN KF=.KF OR 1^CFANSI ! then turn on 'keyword'
END
ELSE
IF .KX EQL (NNAME) OR .KX EQL (NDIRECT)
THEN !NAME, DIRECT or DIRECTORY keyword
BEGIN
KF=.KF-1^CFVANSI; ! Turn off 'keyword value'
IF .STYPE NEQ INQUDATA ! Unless it is INQUIRE,
THEN KF=.KF+1^CFANSI ! Turn on 'keyword'
END
ELSE
BEGIN ! Test for keyword values
KTABLE=0; ! Start with no table
IF .KV[OPR1] EQL CONSTFL ! Check only constants
THEN ! Test values
IF .KX EQL (NACCESS) THEN KTABLE = ACCESSA
ELSE
IF .KX EQL (NSTATUS)
THEN
IF .STYPE EQL CLOSDATA
THEN KTABLE = STATUSC
ELSE KTABLE = STATUSO;
IF .KTABLE EQL 0
THEN ! No table, so no warning
KF = .KF - 1^CFVANSI
ELSE ! If value in table, no warning
IF CFSEARCH(.KV, .KTABLE)
THEN KF = .KF - 1^CFVANSI
END
END; ! Extra processing for Fortran-77
%2455% IF .KF<CFVVMS,1>
THEN
%2455% BEGIN ! Extra processing for VMS
IF .KX EQL (NASSOC)
%2455% THEN !ASSOCIATEVARIABLE not set by VMS on OPEN
BEGIN
%2455% KF = .KF - 1^CFVVMS; ! Turn off the bit
IF .STYPE EQL OPENDATA THEN WARNLEX(E275<0,0>);
%4544% IF .KV[IDATTRIBUT(DUMMY)] THEN WARNLEX(E325<0,0>);
END
ELSE
IF .KX EQL (NDIRECT)
THEN !DIRECT or DIRECTORY keyword
BEGIN
%2455% KF = .KF - 1^CFVVMS; ! Turn off 'keyword values'
IF .STYPE NEQ INQUDATA ! Unless it is INQUIRE,
%2455% THEN KF = .KF + 1^CFVMS ! turn on 'keyword'
END
ELSE
BEGIN ! Looking at values
KTABLE=0; ! Start with no table
IF .KV[OPR1] EQL CONSTFL ! Check only constants
THEN ! Test values
IF .KX EQL (NACCESS) THEN KTABLE = ACCESSV
ELSE
IF .KX EQL (NCARR) THEN KTABLE = CARRIAGEV
ELSE
IF .KX EQL (NDISPOS) THEN KTABLE = DISPOSEV
%4500% ELSE
%4500% IF .KX EQL (NORGAN) THEN KTABLE = ORGANIV
ELSE
IF .KX EQL (NSTATUS) OR .KX EQL (NTYPE)
THEN
IF .STYPE EQL CLOSDATA
THEN KTABLE = STATUSC
ELSE KTABLE = STATUSO;
IF .KTABLE EQL 0
THEN ! No table, so no warning
%2455% KF = .KF - 1^CFVVMS
ELSE ! If value in table, no warning
IF CFSEARCH(.KV, .KTABLE)
%2455% THEN KF = .KF - 1^CFVVMS
END ! Looking at values
%2455% END; ! Extra processing for VMS
%2316% IF .KF EQL 0 THEN RETURN; ! Go away if we found nothing
! Special names for the keywords
! IF .KX EQL NREADO [2370] removed
! THEN KNAME=PLIT ASCIZ 'READON'
! ELSE
! IF .KX EQL NDIALOG
! THEN KNAME=PLIT ASCIZ 'DIALOG';
!Determine prefix for any keyword warning
IF .KF<CFANSI,1>
THEN
%2455% IF .KF<CFVMS,1>
%2477% THEN PREFIX = BOTHPLIT ! Both
%2477% ELSE PREFIX = ANSIPLIT ! Fortran-77 only
ELSE
%2455% IF .KF<CFVMS,1>
%2477% THEN PREFIX = VMSPLIT ! VMS only
ELSE PREFIX = 0;
IF .PREFIX NEQ 0
THEN WARNLEX(.KNAME,.PREFIX,E247<0,0>); ! Keyword .KNAME
!Determine prefix for any keyword value warning
IF .KF<CFVANSI,1>
THEN
%2455% IF .KF<CFVVMS,1>
%2477% THEN PREFIX = BOTHPLIT ! Both
%2477% ELSE PREFIX = ANSIPLIT ! Fortran-77 only
ELSE
%2455% IF .KF<CFVVMS,1>
%2477% THEN PREFIX = VMSPLIT ! VMS only
ELSE PREFIX = 0;
IF .PREFIX NEQ 0
%2316% THEN WARNLEX(.KNAME,.PREFIX,E248<0,0>) ! Keyword value for .KNAME
END; ! of CFCHECK [2316]
GLOBAL ROUTINE OPENSTA=
OPENCLOSE(OPENDATA);
GLOBAL ROUTINE CLOSSTA=
OPENCLOSE(CLOSDATA);
GLOBAL ROUTINE INQUSTA=
OPENCLOSE(INQUDATA); ![2200] Rewritten by TFV on 23-Mar-83
END
ELUDOM