Annotation of researchv10dc/cmd/icon/ipl/source/ipxref.icn, revision 1.1.1.1

1.1       root        1: #      IPXREF
                      2: #
                      3: #      Create Icon program cross-reference
                      4: #
                      5: #      Allan J. Anderson
                      6: #
                      7: #      Last modified 4/29/86 by Ralph E. Griswold
                      8: #
                      9: 
                     10: global resword, linenum, letters, digits, var, buffer, qflag, f, fflag, xflag
                     11: global inmaxcol, inlmarg, inchunk, localvar, lin
                     12: 
                     13: record procrec(pname,begline,lastline)
                     14: 
                     15: procedure main(a)
                     16:    local word, w2, p, prec, i, L, ln
                     17:    initial {
                     18:       resword := ["break","by","case","default","do","dynamic","else",
                     19:          "end","every","fail","global","if","initial","link",
                     20:          "local","next","not","of","procedure",
                     21:          "record","repeat","return","static","suspend","then",
                     22:          "to","until","while"]
                     23:       linenum := 0
                     24:       var := table()           # var[variable[proc]] is list of line numbers
                     25:       prec := []               # list of procedure records
                     26:       localvar := []           # list of local variables of current routine
                     27:       buffer := []             # a put-back buffer for getword
                     28:       proc := "global"
                     29:       letters := &lcase ++ &ucase ++ '_'
                     30:       digits := '1234567890'
                     31:       }
                     32:    i := 0
                     33:    while p := a[i +:= 1] do
                     34:       case p of {
                     35:          "-q":  qflag := 1
                     36:          "-x":  xflag := 1
                     37:          "-w":  inmaxcol := integer(a[i +:= 1])
                     38:          "-l":  inlmarg := integer(a[i +:= 1])
                     39:          "-c":  inchunk := integer(a[i +:= 1])
                     40:          default:  if f := open(p,"r") then fflag := 1
                     41:             else stop("usage:  [-q -x -w -l -c] file")
                     42:             }
                     43:    while word := getword() do
                     44:       if word == "link" then {
                     45:          buffer := []
                     46:          lin := ""
                     47:          next
                     48:          }
                     49:       else if word == "procedure" then {
                     50:          put(prec,procrec("",linenum,0))
                     51:          proc := getword() | break
                     52:          p := pull(prec)
                     53:          p.pname := proc
                     54:          put(prec,p)
                     55:          }
                     56:       else if word == ("global" | "link" | "record") then {
                     57:          word := getword() | break
                     58:          addword(word,"global",linenum)
                     59:          while (w2 := getword()) == "," do {
                     60:             if Find(word,resword) then break
                     61:             word := getword() | break
                     62:             addword(word,"global",linenum)
                     63:             }
                     64:          put(buffer,w2)
                     65:          }
                     66:       else if word == ("local" | "dynamic" | "static") then {
                     67:          word := getword() | break
                     68:          put(localvar,word)
                     69:          addword(word,proc,linenum)
                     70:          while (w2 := getword()) == "," do {
                     71:             if Find(word,resword) then break
                     72:             word := getword() | break
                     73:             put(localvar,word)
                     74:             addword(word,proc,linenum)
                     75:             }
                     76:          put(buffer,w2)
                     77:          }
                     78:       else if word == "end" then {
                     79:          proc := "global"
                     80:          localvar := []
                     81:          p := pull(prec)
                     82:          p.lastline := linenum
                     83:          put(prec,p)
                     84:          }
                     85:       else if Find(word,resword) then 
                     86:          next
                     87:       else {
                     88:          ln := linenum
                     89:          if (w2 := getword()) == "(" then
                     90:             word ||:= " *"                     # special mark for procedures
                     91:          else
                     92:             put(buffer,w2)                     # put back w2
                     93:          addword(word,proc,ln)
                     94:          }
                     95:    every write(!format(var))
                     96:    write("\n\nprocedures:\tlines:\n")
                     97:    L := []
                     98:    every p := !prec do
                     99:       put(L,left(p.pname,16," ") || p.begline || "-" || p.lastline)
                    100:    every write(!(sort(L)))
                    101: end
                    102: 
                    103: procedure addword(word,proc,lineno)
                    104:    if any(letters,word) | \xflag then {
                    105:       /var[word] := table()
                    106:       if /var[word]["global"] | Find(word,\localvar) then {
                    107:          /(var[word])[proc] := [word,proc]
                    108:          put((var[word])[proc],lineno)
                    109:          }
                    110:       else {
                    111:          /var[word]["global"] := [word,"global"]
                    112:          put((var[word])["global"],lineno)
                    113:          }
                    114:       }
                    115: end
                    116: 
                    117: procedure getword()
                    118:    local j, c
                    119:    static i, nonwhite
                    120:    nonwhite := ~' \t\n'
                    121:    repeat {
                    122:       if *buffer > 0 then return get(buffer)
                    123:       if /lin | i = *lin + 1 then
                    124:          if lin := myread() then {
                    125:             i := 1
                    126:             linenum +:= 1
                    127:             }
                    128:          else fail
                    129:       if i := upto(nonwhite,lin,i) then {   # skip white space
                    130:          j := i
                    131:          if lin[i] == ("'" | '"') then {   # don't xref quoted words
                    132:             if /qflag then {
                    133:                c := lin[i]
                    134:                i +:= 1
                    135:                repeat
                    136:                   if i := upto(c ++ '\\',lin,i) + 1 then
                    137:                      if lin[i - 1] == c then break
                    138:                      else i +:= 1
                    139:                   else {
                    140:                      i := 1
                    141:                      linenum +:= 1
                    142:                      lin := myread() | fail
                    143:                      }
                    144:                }
                    145:             else i +:= 1
                    146:             }
                    147:          else if lin[i] == "#" then {  # don't xref comments; get next line
                    148:             i := *lin + 1
                    149:             }
                    150:          else if i := many(letters ++ digits,lin,i) then
                    151:             return lin[j:i]
                    152:          else {
                    153:             i +:= 1
                    154:             return lin[i - 1]
                    155:             }
                    156:          }
                    157:       else
                    158:          i := *lin + 1
                    159:    }      # repeat
                    160: end
                    161: 
                    162: procedure format(T)
                    163:    local V, block, n, L, lin, maxcol, lmargin, chunk, col
                    164:    initial {
                    165:       maxcol := \inmaxcol | 80
                    166:       lmargin := \inlmarg | 40
                    167:       chunk := \inchunk | 4
                    168:       }
                    169:    L := []
                    170:    col := lmargin
                    171:    every V := !T do
                    172:       every block := !V do {
                    173:          lin := left(block[1],16," ") || left(block[2],lmargin - 16," ")
                    174:          every lin ||:= center(block[3 to *block],chunk," ") do {
                    175:             col +:= chunk
                    176:             if col >= maxcol - chunk then {
                    177:                lin ||:= "\n\t\t\t\t\t"
                    178:                col := lmargin
                    179:                }
                    180:             }
                    181:          if col = lmargin then lin := lin[1:-6] # came out exactly even
                    182:          put(L,lin)
                    183:          col := lmargin
                    184:          }
                    185:    L := sort(L)
                    186:    push(L,"variable\tprocedure\t\tline numbers\n")
                    187:    return L
                    188: end
                    189: 
                    190: procedure Find(w,L)
                    191:    every if w == !L then return
                    192: end
                    193: 
                    194: procedure myread()
                    195:    if \fflag then return read(f) else return read()
                    196: end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.