Annotation of researchv10no/cmd/monk/db/a4, revision 1.1.1.1

1.1       root        1: BEGIN {
                      2:                myname = "a4:"
                      3:                list["\["] = "\]"; list["{"] = "}"; list["("] = "\\)"; list["<"] = ">"
                      4:                # it is unclear what the proper format is,
                      5:                # but let's give it a try
                      6:                if (summary) {
                      7:                        summary = summary ".sum"
                      8:                        print "\n\n" summary, "doc", "type\n" >  summary
                      9:                        summarypipe = "sort -u" ">> " summary
                     10:                }
                     11:                while(--ARGC) {
                     12:                        i++
                     13:                        include(ARGV[i])
                     14:                }
                     15:        }
                     16: 
                     17: function show(a) { # debugging aid
                     18:        print ">>>", a |"cat 1>&2"
                     19: #      print ">>>", a
                     20: }
                     21: 
                     22: function include(file, l,m,i) { # include file handling
                     23:        gsub( / +|\)/, "", file)
                     24:        push( file )
                     25:        while( (i = getline l < file ) > 0) {
                     26:                NR++
                     27:                if (match(l, /^\|include\(/)) {
                     28:                        include( substr(l, RSTART+RLENGTH))
                     29:                } else {
                     30:                        if ((m = process(l)) !~ /^$/ ) {
                     31:                                print m
                     32:                        }
                     33:                }
                     34:        }
                     35:        if ( i < 0 )
                     36:                error("Cannot open: " file)
                     37:        else {
                     38:                close file
                     39:                pop()
                     40:        }
                     41: }
                     42: 
                     43: function push(new) {
                     44:        stack[top++] = NR " " FILENAME
                     45:        NR = 0; FILENAME = new
                     46: }
                     47: 
                     48: function pop(          a) {
                     49:        if (--top < 0)
                     50:                error("Internal error include stack")
                     51:        split(stack[top], a)
                     52:        NR = a[1]; FILENAME = a[2]
                     53: }
                     54: 
                     55: function error(s) {
                     56:        print myname, s | "cat 1>&2"; exit -1
                     57: }
                     58: 
                     59: function warn(b1, b2) {
                     60:        print myname, FILENAME", line", NR ":", b1, b2 | "cat 1>&2"
                     61:        warned++
                     62: }
                     63: 
                     64: function process(line,         s, t) { # does all the work
                     65: # show(line)
                     66: 
                     67:        if (summary && line ~ /\|comment<summary: /) {
                     68:                sub(/[ \t]*\|comment<summary: /, "", line)
                     69:                sub(/>$/, "", line)
                     70:                print line | summarypipe
                     71:                return ""
                     72:        }
                     73:        if (comment == 0 && line ~ /\|comment[\[{(<]/ ) {
                     74:                match(line, /\|comment[\[{(<]/)
                     75:                comment =  substr(line, RSTART+RLENGTH-1, 1)
                     76:                closecomment = list[comment]
                     77:        }
                     78:        if (comment != 0 && line ~ /[\]})>]/) {
                     79:                if (match(line, closecomment))
                     80:                        comment = 0 ;
                     81:                return ""
                     82:        }
                     83:        if (comment != 0) {
                     84:                return ""
                     85:        }
                     86: 
                     87:        if (line ~ /^$/) { # ignore empty lines
                     88:                return ""
                     89:        }
                     90:        if (line ~ /^[\.'][ \t]*\\"/) { # wipe out lines of troff comments
                     91:                return ""
                     92:        }
                     93:        if (line ~ /[ \t]+\\".*/) { # wipe out more troff comments
                     94:                sub(/[ \t]+\\".*/, "", line)
                     95:        }
                     96: 
                     97:        if (line ~ /\|REGISTER\(/) {
                     98:                sub(/\|REGISTER\(/, "", line)
                     99:                match(line, /[A-Za-z][A-Za-z_0-9]*/)
                    100:                s = substr(line, RSTART, RLENGTH)
                    101:                line = substr(line, RLENGTH+1)
                    102:                if (s in name) {
                    103:                        warn("redefinition of register name:", s)
                    104:                }
                    105:                match(line, /[@-Za-z0-0%|:;.][@-Za-z0-9%|%;.]*/)
                    106:                t = substr(line, RSTART, RLENGTH)
                    107:                chklen2(t)
                    108:                name[s] = t
                    109:                type[s] = "register"
                    110:                return ""
                    111:        }
                    112: 
                    113:        if (line ~ /\|LITERAL\(/) {
                    114:                sub(/\|LITERAL\(/, "", line)
                    115:                match(line, /[A-Za-z][A-Za-z_0-9]*/)
                    116:                s = substr(line, RSTART, RLENGTH)
                    117:                line = substr(line, RSTART+RLENGTH)
                    118: # show(line)
                    119:                if (s in name) {
                    120:                        warn("redefinition of constant name:", s)
                    121:                }
                    122:                sub(/, */, "", line); sub(/ *\).*/, "", line)
                    123:                t = hunt(line)
                    124:                name[s] = t
                    125:                type[s] = "value"
                    126:                return ""
                    127:        }
                    128: 
                    129:        if (line ~ /\|STRING\(/) {
                    130:                sub(/\|STRING\(/, "", line)
                    131:                match(line, /[A-Za-z][A-Za-z_0-9]*/)
                    132:                s = substr(line, RSTART, RLENGTH)
                    133:                line = substr(line, RLENGTH+1)
                    134: # show(line)
                    135:                if (s in name) {
                    136:                        warn("redefinition of string name:", s)
                    137:                }
                    138:                match(line, /[@-Za-z0-;%][@-Za-z0-;%]*/)
                    139:                t = substr(line, RSTART, RLENGTH)
                    140:                chklen2(t)
                    141:                name[s] = t
                    142:                type[s] = "string"
                    143:                return ""
                    144:        }
                    145: 
                    146:        if (line ~ /\|STRING_ARRAY\(/) {
                    147:                sub(/\|STRING_ARRAY\(/, "", line)
                    148:                match(line, /[A-Za-z][A-Za-z_0-9]*/)
                    149:                s = substr(line, RSTART, RLENGTH)
                    150:                line = substr(line, RLENGTH+1)
                    151:                if (s in name) {
                    152:                        warn("redefinition of string array:", s)
                    153:                }
                    154:                match(line, /[@-Za-z0-;%][@-Za-z0-;%]*/)
                    155:                t = substr(line, RSTART, RLENGTH)
                    156:                chklen1(t)
                    157:                name[s] = t
                    158:                type[s] = "string_array"
                    159:                return ""
                    160:        }
                    161: 
                    162:        # anything else
                    163:        t = hunt(line)
                    164:        gsub(/^[ \t]+/, "", t)  # remove leading blanks
                    165:        if (match(t, /^(\\!)?[\.'][ \t]/)) { # remove space after troff's control char
                    166:                sub(/[ \t]+/, "", t)
                    167:        }
                    168:        if (match(t, /^(\\!)?[\.'][a-z][a-z] /)) { # remove space after troff request
                    169:                sub(/ /, "", t)
                    170:        }
                    171:        return t
                    172: }
                    173: 
                    174: function chklen2(s) {
                    175:        if (length(s) > 2) {
                    176:                warn("name too long:", t)
                    177:        }
                    178: }
                    179: 
                    180: function chklen1(s) {
                    181:        if (length(s) > 1) {
                    182:                warn("name too long:", t)
                    183:        }
                    184: }
                    185: 
                    186: # match up to a closing parenthesis, while ignoring matching parentheses
                    187: 
                    188: function parmatch(s,           l, r) {
                    189:        l = match(s, /\(/)
                    190:        r = match(s, /\)/)
                    191: 
                    192:        if ( l == 0 || r < l ) {
                    193:                return r
                    194:        } else {
                    195:                sub(/\(/, " ", s)
                    196:                sub(/\)/, " ", s)
                    197:                r = parmatch(s)
                    198:                return r
                    199:        }
                    200: 
                    201: }
                    202: 
                    203: 
                    204: # find all occurrences of macros in s and replace as text
                    205: function hunt(s,               r, b, t, before, after, i, j) {
                    206: 
                    207:        # 'operator' stuff
                    208:        while(match(s, /[A-Z][A-Z]*[_A-Z][_A-Z]*\(/)) {
                    209:                b = substr(s, 1, RSTART-1)
                    210:                i = RLENGTH
                    211:                j = RSTART
                    212:                if(parmatch(substr(s, RSTART + i))) {
                    213:                        t = substr(s, j, RSTART + i -1)
                    214:                        s = substr(s, j+i+RSTART)
                    215:                        r = operator(t, i)
                    216:                } else {
                    217:                        warn("syntax error:", s)
                    218:                        return s
                    219:                }
                    220:                before = before b r
                    221:        }
                    222:        before = before s
                    223:        s = before
                    224:        before = ""
                    225:        # find macro stuff
                    226:        while(match(s, /[A-Za-z][A-Za-z_0-9]*/)) {
                    227:                b = substr(s, 1, RSTART-1)
                    228:                t = substr(s, RSTART, RLENGTH)
                    229:                s = substr(s, RSTART+RLENGTH)
                    230:                r = replace(t)
                    231:                if( r !~ t) {
                    232:                        if ( t in name && type[t] == "string_array") {
                    233:                                if (!match(s, /^\[[\$A-Za-z0-9][A-Za-z_0-9]*\]/)) {
                    234:                                        warn("Illegal or missing subscript of:", t)
                    235:                                } else
                    236:                                        r = r subscript(substr(s, RSTART+1, RLENGTH-2))
                    237:                                s = substr(s, RSTART+RLENGTH)
                    238:                        } else {
                    239:                                if (match(b, /'$/) && match(s, /^'/)) {
                    240:                                        sub(/'$/, "", b)
                    241:                                        sub(/^'/, "", s)
                    242:                                }
                    243:                        }
                    244:                        r = hunt(r)
                    245:                }
                    246:                before = before b r
                    247:                after = s
                    248:        }
                    249:        if ( before || after) {
                    250:                s = before after
                    251:        }
                    252:        return s        
                    253: }
                    254: 
                    255: # replace string s with defined name, if in table
                    256: function replace(s) {
                    257:        if (s in name)
                    258:                return name[s]
                    259:        else
                    260:                return s        
                    261: }
                    262: 
                    263: # check and maybe generate form for substript
                    264: function subscript(s) {
                    265:        if ( s ~ /^[0-9]$/) {
                    266:                return s
                    267:        }
                    268:        if ( s ~ /^\$/ )
                    269:                return s
                    270:        if ( s in name && type[s] == "register") {
                    271:                return interpolreg(name[s])
                    272:        } else {
                    273:                warn("Illegal subscript")
                    274:        }
                    275:        return s
                    276: }
                    277: 
                    278: # turn register suitable for troff interpolation
                    279: function interpolreg(r) {
                    280:        if (length(r) == 1 )
                    281:                return "\\n" r
                    282:        else if (length(r) == 2)
                    283:                return "\\n(" r
                    284:        else
                    285:                warn("Register name too long")
                    286:        return r
                    287: }
                    288: 
                    289: function interpolstr(r) {
                    290:        if (length(r) == 1 )
                    291:                return "\\*" r
                    292:        else
                    293:                return "\\*(" r
                    294: }
                    295: 
                    296: function operator(s,i,         t,u,a) {
                    297:        oper = substr(s, 1, i - 1)
                    298: #      match(s, /\)/)
                    299: #      t = substr(s, i + 1, RSTART - 1 + RLENGTH - (i + 1))
                    300:        t = substr(s, i+1)
                    301:        gsub(/ /, "", t)
                    302:        i = split(t, a, ",")
                    303:        if ( oper ~ "^GE$") {
                    304:                if (!chckargs(oper, i, 2))
                    305:                        return t
                    306:                t = sprintf("\"%s>=%s\"", args(a[1]), args(a[2]))
                    307:        } else if (oper ~ "^GT$") {
                    308:                if (!chckargs(oper, i, 2))
                    309:                        return t
                    310:                t = sprintf("\"%s>%s\"", args(a[1]), args(a[2]))
                    311:        } else if (oper ~ "^LE$") {
                    312:                if (!chckargs(oper, i, 2))
                    313:                        return t
                    314:                t = sprintf("\"%s<=%s\"", args(a[1]), args(a[2]))
                    315:        } else if (oper ~ "^LT$") {
                    316:                if (!chckargs(oper, i, 2))
                    317:                        return t
                    318:                t = sprintf("\"%s<%s\"", args(a[1]), args(a[2]))
                    319:        } else if (oper ~ "^NULL$") {
                    320:                if (!chckargs(oper, i, 1))
                    321:                        return t
                    322:                t = sprintf("\"@%s@@\"", args(a[1]))
                    323:        } else if (oper ~ "^NOTNULL$") {
                    324:                if (!chckargs(oper, i, 1))
                    325:                        return t
                    326:                t = sprintf("\"!@%s@@\"", args(a[1]))
                    327:        } else if (oper ~ "^EQUAL$") {
                    328:                if (!chckargs(oper, i, 2))
                    329:                        return t
                    330:                u = args(a[1])
                    331:                if (u ~ /\\n\(\.z$/)  {# diversion!
                    332:                        t = sprintf("\"@%s@%s@\"", u, args(a[2]))
                    333:                } else if ( argtype ~ /^register$/ ) {
                    334:                        t = sprintf("\"%s=%s\"", u, args(a[2]))
                    335:                } else
                    336:                        t = sprintf("\"@%s@%s@\"", u, args(a[2]))
                    337:        } else if (oper ~ "^UNEQUAL$") {
                    338:                if (!chckargs(oper, i, 2))
                    339:                        return t
                    340:                u = args(a[1])
                    341:                if (u ~ /^\\n\(\.z$/)  {# diversion!
                    342:                        t = sprintf("\"!@%s@%s@\"", u, a[2])
                    343:                } else if ( argtype ~ /^register$/ ) {
                    344:                        t = sprintf("\"%s!=%s\"", u, args(a[2]))
                    345:                } else
                    346:                        t = sprintf("\"!@%s@%s@\"", u, args(a[2]))
                    347:        } else if (oper ~ "^VALUE$") {
                    348:                if (!chckargs(oper, i, 1))
                    349:                        return t
                    350:                t = sprintf("\"%s\"", args(a[1]))
                    351:        } else
                    352:                warn("Unknown operation: " oper)
                    353:        return t
                    354: }
                    355: 
                    356: function chckargs(o, i, ii) {
                    357:        if ( i != ii) {
                    358:                warn(ii " arguments required for " oper " (is " i ")")
                    359:                return 0
                    360:        } else
                    361:                return 1
                    362: }
                    363: 
                    364: function args(a,               after, result, i, j) {
                    365:        if ( a ~ /^$/ ) {
                    366:                warn("Missing argument", a)
                    367:                return a
                    368:        }
                    369:        if (match(a, /^'/)) {
                    370:                a = substr(a, 2)
                    371:                match(a, /'/)
                    372:                after = substr(a, RSTART+1)
                    373:                a = substr(a, 1, RSTART-1)
                    374:        }
                    375:        if (match(a, /\[/)) {
                    376:                i = RSTART
                    377:                if (!match(a, /\]/)) {
                    378:                        warn("syntax error")
                    379:                        return a after
                    380:                } else
                    381:                        j = substr(a, i+1, RSTART - 1 - i)
                    382:                a = substr(a, 1, i -1)
                    383:        }
                    384: 
                    385:        if ( a ~ /^[0-9]+$/ && type[a] !~ "string_array")
                    386:                return a after
                    387:        if ( a ~ /\$/ )         # possible monk variable
                    388:                return a after
                    389:        if ( a in name ) {
                    390: # show("a: " a " name[a]: " name[a] " type[a]: " type[a])
                    391:                argtype = type[a]
                    392:                if (argtype ~ "^register$" )
                    393:                        result = interpolreg(name[a])
                    394:                else if (argtype ~ "^value$")
                    395:                        result = name[a]
                    396:                else if (argtype ~ "^string$")
                    397:                        result = interpolstr(name[a])
                    398:                else if (argtype ~ "^string_array$")
                    399:                        result = interpolstr(name[a] args(j))
                    400:                else
                    401:                        warn("Internal error, unknown type: " type[a] " (" a ")")
                    402:        } else {
                    403:                warn("Unknown variable: ", a)
                    404:                result = a after
                    405:        }
                    406:        return result after
                    407: }
                    408: 
                    409: END {
                    410:                # to signal make etc. that not everything is dandy
                    411:                # if (warned)
                    412:                #       exit -1
                    413:        }

unix.superglobalmegacorp.com

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