# link --- linkage check # "Link" creates a linkage statement for the files specifed as arguments # in the command line. "Link" accepts the "rp" options -f, supress auto- # matic inclustion of standard definitions file, and -m, map all iden- # tifiers to lower case. "Link" uses "gfnarg" to fetch the filenames in the # argument list (those not beginning with a dash) of the command line. # "Gfnarg" observes the convention that a "-n" argument implies that # file names are to be read from an input file until EOF is reached, # rather than simply from the argument list. If the argument begins # with "-n", it indicates that file names are to be taken from a file. # ("-n" implies the standard port STDIN, "-n2" implies STDIN2, # "-n3" implies STDIN3, and "-nfilename" implies the named file.) # # An identifier needs to be in a linkage statement if it is longer # than six characters and it meets one of the following conditions: # 1) The identifier is in an external statement. # 2) The identifier is the name of a named common block. # 3) The identifier is in a subroutine name. # 4) The identifier is in a function name. # The linkage statement produced by "link" includes all identifiers # which are of one of the four types above, regardless of the number # of characters in the identifer. Because of this, "link" creates # a list of all external symbols for the modules of a given program # as well as a linkage statement # # "Link" uses the lexical analysis portion of "rp", with only a few minor # modifications and the sort for "xref" unmodified. include "link_com.i" character fname (MAXTOK), buf (MAXLINE), keep (MAXLINE) file_des tempfile1, tempfile2 file_des open, mktemp #subsystem routines integer gfnarg, state (4) #subsystem routine and a required parameter integer getlin, equal, length #subsystem routines PARSE_COMMAND_LINE ("[-fm] [-n ]"s, "Usage: link [-fm] [-n]"p) call initialize tempfile1= mktemp (READWRITE) # create temporary files tempfile2= mktemp (READWRITE) if (~ ARG_PRESENT (f)) { #Process subsystem defines unless -f option indicated Level = 1 Infile (Level) = open ("=incl=/swt_def.r.i"s, READ) call getlink_id (tempfile1) } # Process files in command line state (1) = 1 while (gfnarg (fname, state) ~= EOF) { Level = 1 Infile (Level) = open (fname, READ) Line_number (Level) = 0 call getlink_id (tempfile1) } call rewind (tempfile1) call sort (tempfile1, tempfile2) call rmtemp (tempfile1) # Unique sorted names in tempfile2 and print linkage statement call print (STDOUT, "linkage _*n"p) call rewind (tempfile2) if (getlin (keep, tempfile2) ~= EOF) { while (getlin (buf, tempfile2) ~= EOF) { if (equal (keep, buf) == NO) { keep (length (keep)) = ","c call print (STDOUT, " *s*n"p, keep) call scopy (buf, 1, keep, 1) } } call print (STDOUT, " *s"p, keep) } call rmtemp (tempfile2) stop end # getlink_id --- return names which must be included in linkage statement subroutine getlink_id (tempfile) file_des tempfile include "link_com.i" character id (MAXTOK) file_des open call getsym # get next token while (Symbol ~= EOF) { select (Symbol) when (DEFINESYM) { call getsym if (Symbol == '('c) call enter_definition else SYNERR ("Left paren must follow 'define'"p) } when (UNDEFINESYM) { call getsym if (Symbol == '('c) call remove_definition else SYNERR ("Left paren must follow 'undefine'"p) } when (INCLUDESYM) { if (Level >= MAXLEVEL) call error ("Includes nested too deeply"p) call getsym call get_long_name (id) Level += 1 Line_number (Level) = 0 Infile (Level) = open (id, READ) if (Infile (Level) == ERR) { call error ("can't open include file"p) Level = Level - 1 } } when (SUBROUTINESYM, FUNCTIONSYM) { call getsym if (Symbol == IDSYM) { call get_long_name (id) call print (tempfile,"*s*n"p, id) } else SYNERR ("identifier expected in subprogram declaration"p) } when (EXTERNALSYM) { call getsym while (Symbol ~= NEWLINE) { if (Symbol == IDSYM) { call get_long_name (id) call print (tempfile,"*s*n"p, id) } call getsym } } when (COMMONSYM) { call getsym if (Symbol == '/'c) { call getsym if (Symbol == IDSYM) { call get_long_name (id) call print (tempfile,"*s*n"p, id) } else SYNERR ("identifier expected in named common statement"p) } } call getsym } return end