diff options
| author | Syndamia <kamen@syndamia.com> | 2023-11-23 16:40:11 +0200 |
|---|---|---|
| committer | Syndamia <kamen@syndamia.com> | 2023-11-23 16:40:11 +0200 |
| commit | 88b99e041eed16275a4168652e4d9e50a3183fb9 (patch) | |
| tree | 1b61597f4279e076704dac3cb44aeb41ea6b62e8 /csmap.awk | |
| parent | f6eadda6718d2651a3e7b4009be8b33f2fa8cb67 (diff) | |
| download | csma-88b99e041eed16275a4168652e4d9e50a3183fb9.tar csma-88b99e041eed16275a4168652e4d9e50a3183fb9.tar.gz csma-88b99e041eed16275a4168652e4d9e50a3183fb9.zip | |
[csmap] Renamed preprocessor file and added shebang
Diffstat (limited to 'csmap.awk')
| -rwxr-xr-x | csmap.awk | 239 |
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] +} |
