aboutsummaryrefslogtreecommitdiff
path: root/csmap.awk
diff options
context:
space:
mode:
authorSyndamia <kamen@syndamia.com>2023-11-23 16:40:11 +0200
committerSyndamia <kamen@syndamia.com>2023-11-23 16:40:11 +0200
commit88b99e041eed16275a4168652e4d9e50a3183fb9 (patch)
tree1b61597f4279e076704dac3cb44aeb41ea6b62e8 /csmap.awk
parentf6eadda6718d2651a3e7b4009be8b33f2fa8cb67 (diff)
downloadcsma-88b99e041eed16275a4168652e4d9e50a3183fb9.tar
csma-88b99e041eed16275a4168652e4d9e50a3183fb9.tar.gz
csma-88b99e041eed16275a4168652e4d9e50a3183fb9.zip
[csmap] Renamed preprocessor file and added shebang
Diffstat (limited to 'csmap.awk')
-rwxr-xr-xcsmap.awk239
1 files changed, 239 insertions, 0 deletions
diff --git a/csmap.awk b/csmap.awk
new file mode 100755
index 0000000..2eae4c3
--- /dev/null
+++ b/csmap.awk
@@ -0,0 +1,239 @@
+#! /usr/bin/env -S awk -f 'csmap.awk'
+
+BEGIN {
+ stage1 = 1
+ depth = 0
+ __nvlen = 0
+
+ fileCount = 0
+ # Last stylesheet is also used for replacement
+ ARGV[ARGC] = ARGV[ARGC - 1]
+ ARGC++
+}
+
+FNR == 1 {
+ fileCount++
+}
+
+# Do substitution on last file
+stage1 && fileCount == ARGC - 1 {
+ stage1 = 0
+ stage2 = 1
+
+ depth = 0
+ macroNameOnly = 0
+
+ # Do substitutions inside definitions
+ for (name in macros) {
+ for (subname in macros) {
+ gsub(subname, macros[subname], macros[name])
+ }
+ }
+
+ fileCount = 0
+}
+
+# Comments (experimental)
+{
+ sub(/[[:blank:]]*\/\/.*$/, "")
+}
+
+#
+# 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 && macroNameOnly {
+ # Skip blank lines
+ if ($0 ~ /^[[:blank:]]*$/) {
+ next
+ }
+
+ macroNameOnly = 0
+ # We had a name, blank lines, and now the beginning of line has "{"
+ # There is a definition
+ if (sub(/^[[:blank:]]*\{/, "") > 0) {
+ depth++
+ }
+ # The name was not starting a definition
+ else {
+ 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:]]*\{/ {
+ # There is a definition
+ namevec_Push()
+ depth++
+ # Remove definition start
+ sub(/^[^{]*{[[:blank:]]*/, "")
+}
+
+stage1 && /<[^>]*>/ {
+ removeLeadingTabulation()
+
+ # Start searching for a potential opening brace
+ macroNameOnly = 1
+ macroNameLine = $0
+ namevec_Push()
+ next
+}
+
+stage1 && depth >= 1 {
+ depth += gsub("{", "{") - gsub("}", "}")
+
+ removeLeadingTabulation()
+
+ skipORS = 0
+ if (depth <= namevec_TopDepth()) {
+ # Remove macro closing braces
+ for (i = namevec_TopDepth() - depth; i >= 0; i--) {
+ sub(/}/, "")
+ }
+ skipORS = 1
+ }
+
+ # 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[namevec_At(ind)] = macros[namevec_At(ind)] $0
+ }
+
+ if (depth <= namevec_TopDepth()) {
+ namevec_Pop()
+ }
+ next
+}
+
+function removeLeadingTabulation() {
+ # Remove leading tabulation when inside macro definition
+ for (i = namevec_Length(); i > 0; i--) {
+ sub(/^ /, "")
+ }
+}
+
+#
+# Stage 2
+# Do substitution
+#
+
+# Skip over definitions
+stage2 && depth >= 1 {
+ depth += gsub("{", "{") - gsub("}", "}")
+ next
+}
+
+stage2 && macroNameOnly {
+ # Skip over blank lines
+ if ($0 ~ /^[[:blank:]]*$/) {
+ next
+ }
+
+ macroNameOnly = 0
+ # If is definition
+ if ($0 ~ /^[[:blank:]]*\{/) {
+ depth = gsub("{", "{") - gsub("}", "}")
+ macroName = ""
+ next
+ }
+ # Do substitution
+ else {
+ print macros[macroName]
+ macroName = ""
+ }
+}
+
+stage2 && /^[[:blank:]]*<[^>]*>/ {
+ # If we found a definition
+ if ($0 ~ "{") {
+ macroName = ""
+ depth = gsub("{", "{") - gsub("}", "}")
+ next
+ }
+ # If there isn't anything nonblank after the macro name then it might
+ # be the name of a potential definition, with a "{" on another line
+ else if (match($0, /<[^>]*>[[:blank:]]*[^[:blank:]]/) == 0) {
+ match($0, /<[^>]*>/)
+ macroName = substr($0, RSTART, RLENGTH)
+ 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])
+ }
+ print
+}
+
+END {
+ # Substitution for macro name at end of file
+ if (macroName != "")
+ print macros[macroName]
+
+ # print "All macros:"
+ # for (macroName in macros) {
+ # 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]
+}