home *** CD-ROM | disk | FTP | other *** search
- # From Jon Bentley's article in Computer Language June '90 (v7n6)
- # LISTING 4
-
- function error(s) {
-
- print "m1: " s >"CON" #
- exit 1
- }
-
- function dofile(fname, savefile, savebuffer, newstring) {
-
- if (fname in activefiles)
- error("recursively reading file: " fname)
- activefiles[fname] = 1
- savefile = file
- file = fname
- savebuffer = buffer
- buffer = ""
- while (readline() != EOF) {
- if (index($0, "@") == 0) {
- print $0
- }
- else if ($0 ~ /^@define[ \t]/) {
- dodef(1) #
- }
- else if ($0 ~ /^@default[ \t]/) {
- dodef(0) #
- }
- else if ($0 ~ /^@include[ \t]/) {
- if (NF != 2) error("bad inlcude line")
- dofile(dosubs($2))
- }
- else if ($0 ~ /^@if[ \t]/) {
- if (NF != 2) error("bad if line")
- if (!($2 in symtab) || symtab[$2] == 0) gobble()
- }
- else if ($0 ~ /^@unless[ \t]/) {
- if (NF != 2) error("bad unless line")
- if (($2 in symtab) && symtab[$2] != 0) gobble()
- }
- else if ($0 ~ /^@fi[ \t]?/) { # could do error checking
- }
- else if ($0 ~ /^@comment[ \t]?/) {
- }
- else {
- newstring = dosubs($0)
- if ($0 == newstring || index(newstring, "@") == 0)
- print newstring
- else
- buffer = newstring "\n" buffer
- }
- }
- close(fname)
- delete activefiles[fname]
- file = savefile
- buffer = savebuffer
- }
-
- function readline( i, status) {
-
- status = ""
- if (buffer != "") {
- i = index(buffer, "\n")
- $0 = substr(buffer, 1, i - 1)
- buffer = substr(buffer, i + 1)
- }
- else {
- if (file == "-") { #
- i = getline #
- } #
- else { #
- i = getline < file #
- } #
- status = i <= 0 ? "EOF" : "" #
- }
- return status
- }
-
- function gobble( ifdepth) {
-
- ifdepth = 1
- while (readline()) {
- if ($0 ~ /^@(if|unless)[ \t]/) ifdepth++
- if ($0 ~ /^@fi[ \t]?/ && --ifdepth <= 0) break
- }
- }
-
- function dosubs(s, l, r, i, m) {
-
- if (index(s, "@") == 0) return s
- l = "" # Left of current pos: ready for output
- r = s # Right of current: unexamined at this time
- while ((i = index(r, "@")) != 0) {
- l = l substr(r, 1, i - 1)
- r = substr(r, i + 1) # Currently scanning @
- i = index(r, "@")
- if (i == 0) {
- l = l "@"
- break
- }
- m = substr(r, 1, i - 1)
- r = substr(r, i + 1)
- if (m in symtab) {
- r = symtab[m] r
- }
- else {
- l = l "@" m
- r = "@" r
- }
- }
- return l r
- }
-
- function dodef(def, str, name) {
-
- name = $2
- sub(/^[ \t]*[^ \t]+[ \t]+[^ \t]+[ \t]+/, "") # $0=$P($0,FS,3,NF)
- str = $0
- while (str ~ /\\$/) {
- if (readline() == EOF)
- error("EOF inside definition")
- sub(/^[ \t]+/, "")
- sub(/[ \t]*\\$/, "\n" $0, str)
- }
- if (def || !(name in symtab)) #
- symtab[name] = str
- }
-
- BEGIN {
-
- EOF = "EOF"
- if (ARGC == 1) dofile("-") #
- else if (ARGC == 2) dofile(ARGV[1])
- else {
- print "Usage: m1 [file]" >"CON" #
- exit
- }
- }