BEGIN { stage1 = 1 depth = 0 nql = 0 } function nameQueuePush(name) { prename = "" if (nql > 0) { name = nameQueue[nql-1] "/" name } nameQueue[nql++] = name nameClose[name] = depth } function nameQueueTop() { return "<" nameQueue[nql - 1] ">" } function nameQueueGet(ind) { return "<" nameQueue[ind] ">" } function nameCloseTop() { return nameClose[nameQueue[nql - 1]] } function nameQueuePop() { delete nameClose[nameQueue[nql - 1]] delete nameQueue[--nql] } # Comments /^\/\/.*$/ { next } # # Stage 1 # Gather definitions # # function printNQ() { # print "All in nameQueue:" # for (ind in nameQueue) { # print "[" ind "] " nameQueue[ind] " | " nameClose[nameQueue[ind]] # } # } # # stage1 { # print "" # print $0 # print "Depth: " depth # printNQ() # } stage1 && gotNameOnly { if ($0 ~ /^[[:blank:]]*$/) { next } gotNameOnly = 0 if ($0 ~ /^[[:blank:]]*\{/) { depth++ next } else { nameQueuePop() for (ind in nameQueue) { macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS nameOnly } } } stage1 && /<[^>]*>[[:blank:]]*\{/ { match($0, /<[^>]*>/) nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2)) sub(/^[^{]*{[[:blank:]]*/, "") depth++ if ($0 == "") next } # Macro placement stage1 && /<[^>]*>/ { for (i = 0; i < length(nameQueue); i++) { sub(/^ /, "") } nameOnly = $0 match($0, /<[^>]*>/); nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2)) gotNameOnly = 1 next } stage1 && depth >= 1 { depth += gsub("{", "{") - gsub("}", "}") for (i = 0; i < length(nameQueue); i++) { sub(/^ /, "") } skipORS = 0 if (depth <= nameCloseTop()) { sub(/[[:blank:]]*}[[:blank:]]*$/, "") skipORS = 1 } for (ind in nameQueue) { if (length(macros[nameQueueGet(ind)]) != 0 && !skipORS) { macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS } macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] $0 } if (depth <= nameCloseTop()) { nameQueuePop() } next } ENDFILE { if (stage1) { stage1 = 0 stage2 = 1 depth = 0 gotNameOnly = 0 for (name in macros) { for (subname in macros) { gsub(subname, macros[subname], macros[name]) } } } } # # Stage 2 # Do placements # stage2 && depth >= 1 { depth += gsub("{", "{") - gsub("}", "}") next } stage2 && gotNameOnly { if ($0 ~ /^[[:blank:]]*$/) { next } gotNameOnly = 0 # If is definition if ($0 ~ /^[[:blank:]]*\{/) { depth = 1 macroName = "" next } else { print macros[macroName] macroName = "" } } stage2 && /^[[:blank:]]*<[^>]*>/ { match($0, /<[^>]*>/) macroName = substr($0, RSTART, RLENGTH) if ($0 ~ "{") depth = 1 else gotNameOnly = 1 next } stage2 && depth == 0 { while(match($0, /<[^>]*>/)) { macroName = substr($0, RSTART, RLENGTH) sub(macroName, macros[macroName]) } print } END { if (macroName != "") print macros[macroName] # print "All macros:" # for (macroName in macros) { # print macroName ORS macros[macroName] # } }