aboutsummaryrefslogtreecommitdiff
path: root/preproc.awk
diff options
context:
space:
mode:
Diffstat (limited to 'preproc.awk')
-rw-r--r--preproc.awk180
1 files changed, 111 insertions, 69 deletions
diff --git a/preproc.awk b/preproc.awk
index 4eb1718..abc44d4 100644
--- a/preproc.awk
+++ b/preproc.awk
@@ -1,38 +1,39 @@
BEGIN {
stage1 = 1
depth = 0
- nql = 0
-}
+ __nvlen = 0
-function nameQueuePush(name) {
- prename = ""
- if (nql > 0) {
- name = nameQueue[nql-1] "/" name
- }
- nameQueue[nql++] = name
- nameClose[name] = depth
+ fileCount = 0
+ # Last stylesheet is also used for replacement
+ ARGV[ARGC] = ARGV[ARGC - 1]
+ ARGC++
}
-function nameQueueTop() {
- return "<" nameQueue[nql - 1] ">"
+FNR == 1 {
+ fileCount++
}
-function nameQueueGet(ind) {
- return "<" nameQueue[ind] ">"
-}
+# Do substitution on last file
+stage1 && fileCount == ARGC - 1 {
+ stage1 = 0
+ stage2 = 1
-function nameCloseTop() {
- return nameClose[nameQueue[nql - 1]]
-}
+ depth = 0
+ macroNameOnly = 0
+
+ # Do substitutions inside definitions
+ for (name in macros) {
+ for (subname in macros) {
+ gsub(subname, macros[subname], macros[name])
+ }
+ }
-function nameQueuePop() {
- delete nameClose[nameQueue[nql - 1]]
- delete nameQueue[--nql]
+ fileCount = 0
}
-# Comments
-/^\/\/.*$/ {
- next
+# Comments (experimental)
+{
+ sub(/[[:blank:]]*\/\/.*$/, "")
}
#
@@ -54,107 +55,107 @@ function nameQueuePop() {
# printNQ()
# }
-stage1 && gotNameOnly {
+stage1 && macroNameOnly {
+ # Skip blank lines
if ($0 ~ /^[[:blank:]]*$/) {
next
}
- gotNameOnly = 0
- if ($0 ~ /^[[:blank:]]*\{/) {
+ macroNameOnly = 0
+ # We had a name, blank lines, and now the beginning of line has "{"
+ # There is a definition
+ if (sub(/^[[:blank:]]*\{/, "") > 0) {
depth++
- next
}
+ # The name was not starting a definition
else {
- nameQueuePop()
- for (ind in nameQueue) {
- macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS nameOnly
+ namevec_Pop()
+ # Since the line didn't start a new definition, we need to add it
+ # "back" verbatim to the current definition(s)
+ for (ind in __nvnames) {
+ macros[namevec_At(ind)] = macros[namevec_At(ind)] ORS macroNameLine
}
}
}
stage1 && /<[^>]*>[[:blank:]]*\{/ {
- match($0, /<[^>]*>/)
- nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2))
- sub(/^[^{]*{[[:blank:]]*/, "")
+ # There is a definition
+ namevec_Push()
depth++
- if ($0 == "") next
+ # Remove definition start
+ sub(/^[^{]*{[[:blank:]]*/, "")
}
-# Macro placement
stage1 && /<[^>]*>/ {
- for (i = 0; i < nql; i++) {
- sub(/^ /, "")
- }
- nameOnly = $0
- match($0, /<[^>]*>/);
- nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2))
- gotNameOnly = 1
+ removeLeadingTabulation()
+
+ # Start searching for a potential opening brace
+ macroNameOnly = 1
+ macroNameLine = $0
+ namevec_Push()
next
}
stage1 && depth >= 1 {
depth += gsub("{", "{") - gsub("}", "}")
- for (i = 0; i < nql; i++) {
- sub(/^ /, "")
- }
+ removeLeadingTabulation()
skipORS = 0
- if (depth <= nameCloseTop()) {
- sub(/[[:blank:]]*}[[:blank:]]*$/, "")
+ if (depth <= namevec_TopDepth()) {
+ # Remove macro closing braces
+ for (i = namevec_TopDepth() - depth; i >= 0; i--) {
+ sub(/}/, "")
+ }
skipORS = 1
}
- for (ind in nameQueue) {
- if (length(macros[nameQueueGet(ind)]) != 0 && !skipORS) {
- macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS
+ # Add line to definition and parent definitions
+ for (ind in __nvnames) {
+ if (length(macros[namevec_At(ind)]) != 0 && !skipORS) {
+ macros[namevec_At(ind)] = macros[namevec_At(ind)] ORS
}
- macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] $0
+ macros[namevec_At(ind)] = macros[namevec_At(ind)] $0
}
- if (depth <= nameCloseTop()) {
- nameQueuePop()
+ if (depth <= namevec_TopDepth()) {
+ namevec_Pop()
}
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])
- }
- }
+function removeLeadingTabulation() {
+ # Remove leading tabulation when inside macro definition
+ for (i = namevec_Length(); i > 0; i--) {
+ sub(/^ /, "")
}
}
#
# Stage 2
-# Do placements
+# Do substitution
#
+# Skip over definitions
stage2 && depth >= 1 {
depth += gsub("{", "{") - gsub("}", "}")
next
}
-stage2 && gotNameOnly {
+stage2 && macroNameOnly {
+ # Skip over blank lines
if ($0 ~ /^[[:blank:]]*$/) {
next
}
- gotNameOnly = 0
+ macroNameOnly = 0
# If is definition
if ($0 ~ /^[[:blank:]]*\{/) {
depth = 1
macroName = ""
next
}
+ # Do substitution
else {
print macros[macroName]
macroName = ""
@@ -163,18 +164,22 @@ stage2 && gotNameOnly {
stage2 && /^[[:blank:]]*<[^>]*>/ {
match($0, /<[^>]*>/)
+ # If we found a definition
if ($0 ~ "{") {
macroName = ""
depth = gsub("{", "{") - gsub("}", "}")
}
+ # Macro name could begin a potential definition, with a "{" on a new line
else {
macroName = substr($0, RSTART, RLENGTH)
- gotNameOnly = 1
+ macroNameOnly = 1
}
next
}
+# Outside definition
stage2 && depth == 0 {
+ # Do macro substitutions on line
while(match($0, /<[^>]*>/)) {
macroName = substr($0, RSTART, RLENGTH)
sub(macroName, macros[macroName])
@@ -183,6 +188,7 @@ stage2 && depth == 0 {
}
END {
+ # Substitution for macro name at end of file
if (macroName != "")
print macros[macroName]
@@ -191,3 +197,39 @@ END {
# print macroName ORS macros[macroName]
# }
}
+
+#
+# namevec "structure"
+#
+
+function namevec_Top() {
+ return namevec_At(__nvlen - 1)
+}
+
+function namevec_TopDepth() {
+ return __nvdepth[__nvlen - 1]
+}
+
+function namevec_At(_ind) {
+ return "<" __nvnames[_ind] ">"
+}
+
+function namevec_Length() {
+ return __nvlen
+}
+
+function namevec_Push() {
+ match($0, /<[^>]*>/)
+ name = substr($0, RSTART + 1, RLENGTH - 2)
+ if (__nvlen > 0) {
+ name = __nvnames[__nvlen-1] "/" name
+ }
+
+ __nvnames[__nvlen] = name
+ __nvdepth[__nvlen++] = depth
+}
+
+function namevec_Pop() {
+ delete __nvnames[--__nvlen]
+ delete __nvdepth[__nvlen]
+}