Pulled all the recent changes to `d.awk` into `hashd.awk`

#! /usr/bin/awk -f

##
# hashd.awk
# =========
#
# Converts Markdown in code comments to HTML of languages that use `#` symbols
# for code comments.
#
# <https://github.com/wernsey/d.awk>
#
#     (c) 2016 Werner Stoop
#     Copying and distribution of this file, with or without modification,
#     are permitted in any medium without royalty provided the copyright
#     notice and this notice are preserved. This file is offered as-is,
#     without any warranty.

BEGIN {

    # Configuration options
    if(Title== "") Title = "Documentation";
    if(Theme== "") Theme = 1;
    if(Pretty== "") Pretty = 1;
    if(Mermaid== "") Mermaid = 1;
    if(HideToCLevel== "") HideToCLevel = 3;
    if(Lang == "") Lang = "en";
    #TopLinks = 1;
    #classic_underscore = 1;
    if(MaxWidth=="") MaxWidth="1080px";
    if(NumberHeadings=="") NumberHeadings = 1;
    if(NumberH1s=="") NumberH1s = 0;

    Mode = (Clean)?"p":"none";
    ToC = ""; ToCLevel = 1;
    CSS = init_css(Theme);
    for(i = 0; i < 128; i++)
        _ord[sprintf("%c", i)] = i;
    srand();
}

Single && $0 !~ /^#/ {
    if(Mode == "ul" || Mode == "ol") {
        while(ListLevel > 1)
            Buf = Buf "\n</" Open[ListLevel--] ">";
        Out = Out tag(Mode, Buf "\n");
    } else {
        Buf = trim(scrub(Buf));
        if(Buf)
            Out = Out tag(Mode, Buf);
    }
    Mode = "none";
    Single = 0;
    Buf = "";
    Prev = "";
}
Single && /^#+/ {
    sub(/^#+/,"");
    Out = Out filter($0);
}
!Single && /^##+/ {
    sub(/^##+/,"");
    Single = 1;
    Mode = "p";
    Out = Out filter($0);
}

END {

    if(Mode == "ul" || Mode == "ol") {
        while(ListLevel > 1)
            Buf = Buf "\n</" Open[ListLevel--] ">";
        Out = Out tag(Mode, Buf "\n");
    } else if(Mode == "pre") {
        while(ListLevel > 1)
            Buf = Buf "\n</" Open[ListLevel--] ">";
        Out = Out tag(Mode, Buf "\n");
    } else {
        Buf = trim(scrub(Buf));
        if(Buf)
            Out = Out tag(Mode, Buf);
    }

    print "<!DOCTYPE html>\n"
    print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">";
    print "<title>" Title "</title>";
    if(StyleSheet)
        print "<link rel=\"stylesheet\" href=\"" StyleSheet "\">";
    else
        print "";
    if(ToC && match(Out, /!\[toc[-+]?\]/))
        print "";
    print "";
    if(Out) {
        Out = fix_footnotes(Out);
        Out = fix_links(Out);
        Out = fix_abbrs(Out);
        Out = make_toc(Out);

        print trim(Out);
        if(footnotes) {
            footnotes = fix_links(footnotes);
            print "

\n" footnotes "
";
        }
    }

    if(Pretty && HasPretty) {
        print "";
    }
    if(Mermaid && HasMermaid) {
        print "";
        print "";
    }
    print ""
}

function escape(st) {
    gsub(/&/, "\\&", st);
    gsub(/</, "\\<", st);
    gsub(/>/, "\\>", st);
    return st;
}
function strip_tags(st) {
    gsub(/<\/?[^>]+>/,"",st);
    return st;
}
function trim(st) {
    sub(/^[[:space:]]+/, "", st);
    sub(/[[:space:]]+$/, "", st);
    return st;
}
function filter(st,       res,tmp, linkdesc, url, delim, edelim, name, def, plang, mmaid) {
    if(Mode == "p") {
        if(match(st, /^[[:space:]]*\[[-._[:alnum:][:space:]]+\]:/)) {
            linkdesc = ""; LastLink = 0;
            match(st,/\[.*\]/);
            LinkRef = tolower(substr(st, RSTART+1, RLENGTH-2));
            st = substr(st, RSTART+RLENGTH+2);
            match(st, /[^[:space:]]+/);
            url = substr(st, RSTART, RLENGTH);
            st = substr(st, RSTART+RLENGTH+1);
            if(match(url, /^<.*>/))
                url = substr(url, RSTART+1, RLENGTH-2);
            if(match(st, /["'(]/)) {
                delim = substr(st, RSTART, 1);
                edelim = (delim == "(") ? ")" : delim;
                if(match(st, delim ".*" edelim))
                    linkdesc = substr(st, RSTART+1, RLENGTH-2);
            }
            LinkUrls[LinkRef] = escape(url);
            if(!linkdesc) LastLink = 1;
            LinkDescs[LinkRef] = escape(linkdesc);
            return;
        } else if(LastLink && match(st, /^[[:space:]]*["'(]/)) {
            match(st, /["'(]/);
            delim = substr(st, RSTART, 1);
            edelim = (delim == "(") ? ")" : delim;
            st = substr(st, RSTART);
            if(match(st, delim ".*" edelim))
                LinkDescs[LinkRef] = escape(substr(st,RSTART+1,RLENGTH-2));
            LastLink = 0;
            return;
        } else if(match(st, /^[[:space:]]*\[\^[-._[:alnum:][:space:]]+\]:[[:space:]]*/)) {
            match(st, /\[\^[[:alnum:]]+\]:/);
            name = substr(st, RSTART+2,RLENGTH-4);
            def = substr(st, RSTART+RLENGTH+1);
            Footnote[tolower(name)] = scrub(def);
            return;
        } else if(match(st, /^[[:space:]]*\*\[[[:alnum:]]+\]:[[:space:]]*/)) {
            match(st, /\[[[:alnum:]]+\]/);
            name = substr(st, RSTART+1,RLENGTH-2);
            def = substr(st, RSTART+RLENGTH+2);
            Abbrs[toupper(name)] = def;
            return;
        } else if(match(st, /^((    )| *\t)/) || match(st, /^[[:space:]]*```+[[:alnum:]]*/)) {
            Preterm = trim(substr(st, RSTART,RLENGTH));
            st = substr(st, RSTART+RLENGTH);
            if(Buf) res = tag("p", scrub(Buf));
            Buf = st;
            push("pre");
        } else if(!trim(Prev) && match(st, /^[[:space:]]*[*-][[:space:]]*[*-][[:space:]]*[*-][-*[:space:]]*$/)) {
            if(Buf) res = tag("p", scrub(Buf));
            Buf = "";
            res = res "<hr>\n";
        } else if(match(st, /^[[:space:]]*===+[[:space:]]*$/)) {
            Buf = trim(substr(Buf, 1, length(Buf) - length(Prev) - 1));
            if(Buf) res= tag("p", scrub(Buf));
            if(Prev) res = res heading(1, scrub(Prev));
            Buf = "";
        } else if(match(st, /^[[:space:]]*---+[[:space:]]*$/)) {
            Buf = trim(substr(Buf, 1, length(Buf) - length(Prev) - 1));
            if(Buf) res = tag("p", scrub(Buf));
            if(Prev) res = res heading(2, scrub(Prev));
            Buf = "";
        } else if(match(st, /^[[:space:]]*#+/)) {
            sub(/#+[[:space:]]*$/, "", st);
            match(st, /#+/);
            ListLevel = RLENGTH;
            tmp = substr(st, RSTART+RLENGTH);
            if(Buf) res = tag("p", scrub(Buf));
            res = res heading(ListLevel, scrub(trim(tmp)));
            Buf = "";
        } else if(match(st, /^[[:space:]]*>/)) {
            if(Buf) res = tag("p", scrub(Buf));
            Buf = scrub(trim(substr(st, RSTART+RLENGTH)));
            push("blockquote");
        } else if(match(st, /^[[:space:]]*([*+-]|[[:digit:]]+\.)[[:space:]]/)) {
            if(Buf) res = tag("p", scrub(Buf));
            Buf="";
            match(st, /^[[:space:]]*/);
            ListLevel = 1;
            indent[ListLevel] = RLENGTH;
            Open[ListLevel]=match(st, /^[[:space:]]*[*+-][[:space:]]*/)?"ul":"ol";
            push(Open[ListLevel]);
            res = res filter(st);
        } else if(match(st, /^[[:space:]]*$/)) {
            if(trim(Buf)) {
                res = tag("p", scrub(trim(Buf)));
                Buf = "";
            }
        } else
            Buf = Buf st "\n";
        LastLink = 0;
    } else if(Mode == "blockquote") {
        if(match(st, /^[[:space:]]*>[[:space:]]*$/))
            Buf = Buf "\n</p><p>";
        else if(match(st, /^[[:space:]]*>/))
            Buf = Buf "\n" scrub(trim(substr(st, RSTART+RLENGTH)));
        else if(match(st, /^[[:space:]]*$/)) {
            res = tag("blockquote", tag("p", trim(Buf)));
            pop();
            res = res filter(st);
        } else
            Buf = Buf st;
    } else if(Mode == "pre") {
        if(!Preterm && match(st, /^((    )| *\t)/) || Preterm && !match(st, /^[[:space:]]*```+/))
            Buf = Buf ((Buf)?"\n":"") substr(st, RSTART+RLENGTH);
        else {
            gsub(/\t/,"    ",Buf);
            if(length(trim(Buf)) > 0) {
                plang = ""; mmaid=0;
                if(match(Preterm, /^[[:space:]]*```+/)) {
                    plang = trim(substr(Preterm, RSTART+RLENGTH));
                    if(plang) {
                        if(plang == "mermaid") {
                            mmaid = 1;
                            HasMermaid = 1;
                        } else {
                            HasPretty = 1;
                            if(plang == "auto")
                                plang = "class=\"prettyprint\"";
                            else
                                plang = "class=\"prettyprint lang-" plang "\"";
                        }
                    }
                }
                if(mmaid && Mermaid)
                    res = tag("div", Buf, "class=\"mermaid\"");
                else
                    res = tag("pre", tag("code", escape(Buf), plang));
            }
            pop();
            if(Preterm) sub(/^[[:space:]]*```+[[:alnum:]]*/,"",st);
            res = res filter(st);
        }
    } else if(Mode == "ul" || Mode == "ol") {
        if(ListLevel == 0 || match(st, /^[[:space:]]*$/) && (RLENGTH <= indent[1])) {
            while(ListLevel > 1)
                Buf = Buf "\n</" Open[ListLevel--] ">";
            res = tag(Mode, "\n" Buf "\n");
            pop();
        } else {
            if(match(st, /^[[:space:]]*([*+-]|[[:digit:]]+\.)/)) {
                tmp = substr(st, RLENGTH+1);
                match(st, /^[[:space:]]*/);
                if(RLENGTH > indent[ListLevel]) {
                    indent[++ListLevel] = RLENGTH;
                    if(match(st, /^[[:space:]]*[*+-]/))
                        Open[ListLevel] = "ul";
                    else
                        Open[ListLevel] = "ol";
                    Buf = Buf "\n<" Open[ListLevel] ">";
                } else while(RLENGTH < indent[ListLevel])
                    Buf = Buf "\n</" Open[ListLevel--] ">";
                if(match(tmp,/^[[:space:]]*\[[xX[:space:]]\]/)) {
                    st = substr(tmp,RLENGTH+1);
                    tmp = tolower(substr(tmp,RSTART,RLENGTH));
                    Buf = Buf "
<input type=\"checkbox\" " (index(tmp,"x")?"checked":"") " disabled>" scrub(st);
                } else
                    Buf = Buf "
" scrub(tmp);
            } else if(match(st, /^[[:space:]]*$/)){
                Buf = Buf "
\n";
            } else {
                sub(/^[[:space:]]+/,"",st);
                Buf = Buf "\n" scrub(st);
            }
        }
    }
    Prev = st;
    return res;
}
function scrub(st,    mp, ms, me, r, p, tg, a) {
    sub(/  $/,"
\n",st);
    gsub(/(  |[[:space:]]+\\)\n/,"
\n",st);
    gsub(/(  |[[:space:]]+\\)$/,"
\n",st);
    while(match(st, /(__?|\*\*?|~~|`+|[&><\\])/)) {
        a = substr(st, 1, RSTART-1);
        mp = substr(st, RSTART, RLENGTH);
        ms = substr(st, RSTART-1,1);
        me = substr(st, RSTART+RLENGTH, 1);
        p = RSTART+RLENGTH;

        if(!classic_underscore && match(mp,/_+/)) {
            if(match(ms,/[[:alnum:]]/) && match(me,/[[:alnum:]]/)) {
                tg = substr(st, 1, index(st, mp));
                r = r tg;
                st = substr(st, index(st, mp) + 1);
                continue;
            }
        }
        st = substr(st, p);
        r = r a;
        ms = "";

        if(mp == "\\") {
            if(match(st, /^!?\[/)) {
                r = r "\\" substr(st, RSTART, RLENGTH);
                st = substr(st, 2);
            } else if(match(st, /^(\*\*|__|~~|`+)/)) {
                r = r substr(st, 1, RLENGTH);
                st = substr(st, RLENGTH+1);
            } else {
                r = r substr(st, 1, 1);
                st = substr(st, 2);
            }
            continue;
        } else if(mp == "_" || mp == "*") {
            if(match(me,/[[:space:]]/)) {
                r = r mp;
                continue;
            }
            p = index(st, mp);
            while(p && match(substr(st, p-1, 1),/[\\[:space:]]/)) {
                ms = ms substr(st, 1, p-1) mp;
                st = substr(st, p + length(mp));
                p = index(st, mp);
            }
            if(!p) {
                r = r mp ms;
                continue;
            }
            ms = ms substr(st,1,p-1);
            r = r itag("em", scrub(ms));
            st = substr(st,p+length(mp));
        } else if(mp == "__" || mp == "**") {
            if(match(me,/[[:space:]]/)) {
                r = r mp;
                continue;
            }
            p = index(st, mp);
            while(p && match(substr(st, p-1, 1),/[\\[:space:]]/)) {
                ms = ms substr(st, 1, p-1) mp;
                st = substr(st, p + length(mp));
                p = index(st, mp);
            }
            if(!p) {
                r = r mp ms;
                continue;
            }
            ms = ms substr(st,1,p-1);
            r = r itag("strong", scrub(ms));
            st = substr(st,p+length(mp));
        } else if(mp == "~~") {
            p = index(st, mp);
            if(!p) {
                r = r mp;
                continue;
            }
            while(p && substr(st, p-1, 1) == "\\") {
                ms = ms substr(st, 1, p-1) mp;
                st = substr(st, p + length(mp));
                p = index(st, mp);
            }
            ms = ms substr(st,1,p-1);
            r = r itag("del", scrub(ms));
            st = substr(st,p+length(mp));
        } else if(match(mp, /`+/)) {
            p = index(st, mp);
            if(!p) {
                r = r mp;
                continue;
            }
            ms = substr(st,1,p-1);
            r = r itag("code", escape(ms));
            st = substr(st,p+length(mp));
        } else if(mp == ">") {
            r = r ">";
        } else if(mp == "<") {

            p = index(st, ">");
            if(!p) {
                r = r "<";
                continue;
            }
            tg = substr(st, 1, p - 1);
            if(match(tg,/^[[:alpha:]]+[[:space:]]/)) {
                a = trim(substr(tg,RSTART+RLENGTH-1));
                tg = substr(tg,1,RLENGTH-1);
            } else
                a = "";

            if(match(tolower(tg), "^/?(a|abbr|div|span|blockquote|pre|img|code|p|em|strong|sup|sub|del|ins|s|u|b|i|br|hr|ul|ol|li|table|thead|tfoot|tbody|tr|th|td|caption|column|col|colgroup|figure|figcaption|dl|dd|dt|mark|cite|q|var|samp|small|details|summary)$")) {
                if(!match(tg, /\//)) {
                    if(match(a, /class="/)) {
                        sub(/class="/, "class=\"dawk-ex ", a);
                    } else {
                        if(a)
                            a = a " class=\"dawk-ex\""
                        else
                            a = "class=\"dawk-ex\""
                    }
                    r = r "<" tg " " a ">";
                } else
                    r = r "<" tg ">";
            } else if(match(tg, "^[[:alpha:]]+://[[:graph:]]+$")) {
                if(!a) a = tg;
                r = r "" a "";
            } else if(match(tg, "^[[:graph:]]+@[[:graph:]]+$")) {
                if(!a) a = tg;
                r = r "" obfuscate(a) "";
            } else {
                r = r "<";
                continue;
            }

            st = substr(st, p + 1);
        } else if(mp == "&") {
            if(match(st, /^[#[:alnum:]]+;/)) {
                r = r "&" substr(st, 1, RLENGTH);
                st = substr(st, RLENGTH+1);
            } else {
                r = r "&";
            }
        }
    }
    return r st;
}

function push(newmode) {Stack[StackTop++] = Mode; Mode = newmode;}
function pop() {Mode = Stack[--StackTop];Buf = ""; return Mode;}
function heading(level, st,       res, href, u, text,svg) {
    if(level > 6) level = 6;
    st = trim(st);
    href = tolower(st);
    href = strip_tags(href);
    gsub(/[^-_ [:alnum:]]+/, "", href);
    gsub(/[[:space:]]/, "-", href);
    if(TitleUrls[href]) {
        for(u = 1; TitleUrls[href "-" u]; u++);
        href = href "-" u;
    }
    TitleUrls[href] = "#" href;

    svg = "<svg width=\"16\" height=\"16\" xmlns=\"http://www.w3.org/2000/svg\"><g transform=\"rotate(-30, 8, 8)\" stroke=\"#000000\" opacity=\"0.25\"><rect fill=\"none\" height=\"6\" width=\"8\" x=\"2\" y=\"6\" rx=\"1.5\"/><rect fill=\"none\" height=\"6\" width=\"8\" x=\"6\" y=\"4\" rx=\"1.5\"/></g></svg>";
    text = "" st " " svg "" (TopLinks?"  ↑ Top":"");

    res = tag("h" level, text, "id=\"" href "\"");
    for(;ToCLevel < level; ToCLevel++) {
        ToC_ID++;
        if(ToCLevel < HideToCLevel) {
            ToC = ToC "▼";
            ToC = ToC "
";
        } else {
            ToC = ToC "►";
            ToC = ToC "
";
        }
    }
    for(;ToCLevel > level; ToCLevel--)
        ToC = ToC "
";
    ToC = ToC "
" st "\n";
    ToCLevel = level;
    return res;
}
function make_toc(st,              r,p,dis,t,n) {
    if(!ToC) return st;
    for(;ToCLevel > 1;ToCLevel--)
        ToC = ToC "
";
    p = match(st, /!\[toc[-+]?\]/);
    while(p) {
        if(substr(st,RSTART-1,1) == "\\") {
            r = r substr(st,1,RSTART-2) substr(st,RSTART,RLENGTH);
            st = substr(st,RSTART+RLENGTH);
            p = match(st, /!\[toc[-+]?\]/);
            continue;
        }

        ++n;
        dis = index(substr(st,RSTART,RLENGTH),"+");
        t = "
\n" (dis?"▼":"►") " Contents\n" \
            "
\n
" ToC "
\n
\n
";
        r = r substr(st,1,RSTART-1);
        r = r t;
        st = substr(st,RSTART+RLENGTH);
        p = match(st, /!\[toc[-+]?\]/);
    }
    return r st;
}
function fix_links(st,          lt,ld,lr,url,img,res,rx,pos,pre) {
    do {
        pre = match(st, /<(pre|code)>/); # Don't substitute in
 or  blocks
        pos = match(st, /\[[^\]]+\]/);
        if(!pos)break;
        if(pre && pre < pos) {
            match(st, /<\/(pre|code)>/);
            res = res substr(st,1,RSTART+RLENGTH);
            st = substr(st, RSTART+RLENGTH+1);
            continue;
        }
        img=substr(st,RSTART-1,1)=="!";
        if(substr(st, RSTART-(img?2:1),1)=="\\") {
            res = res substr(st,1,RSTART-(img?3:2));
            if(img && substr(st,RSTART,RLENGTH)=="[toc]")res=res "\\";
            res = res substr(st,RSTART-(img?1:0),RLENGTH+(img?1:0));
            st = substr(st, RSTART + RLENGTH);
            continue;
        }
        res = res substr(st, 1, RSTART-(img?2:1));
        rx = substr(st, RSTART, RLENGTH);
        st = substr(st, RSTART+RLENGTH);
        if(match(st, /^[[:space:]]*\([^)]+\)/)) {
            lt = substr(rx, 2, length(rx) - 2);
            match(st, /\([^)]+\)/);
            url = substr(st, RSTART+1, RLENGTH-2);
            st = substr(st, RSTART+RLENGTH);
            ld = "";
            if(match(url,/[[:space:]]+["']/)) {
                ld = url;
                url = substr(url, 1, RSTART - 1);
                match(ld,/["']/);
                delim = substr(ld, RSTART, 1);
                if(match(ld,delim ".*" delim))
                    ld = substr(ld, RSTART+1, RLENGTH-2);
            }  else ld = "";
            if(img)
                res = res "";
            else
                res = res "" lt "";
        } else if(match(st, /^[[:space:]]*\[[^\]]*\]/)) {
            lt = substr(rx, 2, length(rx) - 2);
            match(st, /\[[^\]]*\]/);
            lr = trim(tolower(substr(st, RSTART+1, RLENGTH-2)));
            if(!lr) {
                lr = tolower(trim(lt));
                if(LinkDescs[lr]) lt = LinkDescs[lr];
            }
            st = substr(st, RSTART+RLENGTH);
            url = LinkUrls[lr];
            ld = LinkDescs[lr];
            if(img)
                res = res "";
            else if(url)
                res = res "" lt "";
            else
                res = res "[" lt "][" lr "]";
        } else
            res = res (img?"!":"") rx;
    } while(pos > 0);
    return res st;
}
function fix_footnotes(st,         r,p,n,i,d,fn,fc) {
    p = match(st, /\[\^[^\]]+\]/);
    while(p) {
        if(substr(st,RSTART-2,1) == "\\") {
            r = r substr(st,1,RSTART-3) substr(st,RSTART,RLENGTH);
            st = substr(st,RSTART+RLENGTH);
            p = match(st, /\[\^[^\]]+\]/);
            continue;
        }
        r = r substr(st,1,RSTART-1);
        d = substr(st,RSTART+2,RLENGTH-3);
        n = tolower(d);
        st = substr(st,RSTART+RLENGTH);
        if(Footnote[tolower(n)]) {
            if(!fn[n]) fn[n] = ++fc;
            d = Footnote[n];
        } else {
            Footnote[n] = scrub(d);
            if(!fn[n]) fn[n] = ++fc;
        }
        footname[fc] = n;
        d = strip_tags(d);
        if(length(d) > 20) d = substr(d,1,20) "…";
        r = r "[" fn[n] "]";
        p = match(st, /\[\^[^\]]+\]/);
    }
    for(i=1;i<=fc;i++)
        footnotes = footnotes "
" Footnote[footname[i]] \
            "  ↶ Back
\n";
    return r st;
}
function fix_abbrs(str,         st,k,r,p) {
    for(k in Abbrs) {
        r = "";
        st = str;
        t = escape(Abbrs[toupper(k)]);
        gsub(/&/,"\\&", t);
        p = match(st,"[^[:alnum:]]" k "[^[:alnum:]]");
        while(p) {
            r = r substr(st, 1, RSTART);
            r = r "" k "";
            st = substr(st, RSTART+RLENGTH-1);
            p = match(st,"[^[:alnum:]]" k "[^[:alnum:]]");
        }
        str = r st;
    }
    return str;
}
function tag(t, body, attr) {
    if(attr)
        attr = " " trim(attr);
    # https://www.w3.org/TR/html5/grouping-content.html#the-p-element
    if(t == "p" && (match(body, /<\/?(div|table|blockquote|dl|ol|ul|h[[:digit:]]|hr|pre)[>[:space:]]/))|| (match(body,/!\[toc\]/) && substr(body, RSTART-1,1) != "\\"))
        return "<" t attr ">" body "\n";
    else
        return "<" t attr ">" body "</" t ">\n";
}
function itag(t, body) {
    return "<" t ">" body "</" t ">";
}
function obfuscate(e,     r,i,t,o) {
    for(i = 1; i <= length(e); i++) {
        t = substr(e,i,1);
        r = int(rand() * 100);
        if(r > 50)
            o = o sprintf("&#x%02X;", _ord[t]);
        else if(r > 10)
            o = o sprintf("&#%d;", _ord[t]);
        else
            o = o t;
    }
    return o;
}
function init_css(Theme,             css,ss,hr,c1,c2,c3,c4,c5,bg1,bg2,bg3,bg4,ff,fs,i) {
    if(Theme == "0") return "";

    css["body"] = "color:%color1%;font-family:%font-family%;font-size:%font-size%;line-height:1.5em;" \
                "padding:1em 2em;width:80%;max-width:%maxwidth%;margin:0 auto;min-height:100%;float:none;";
    css["h1"] = "border-bottom:1px solid %color1%;padding:0.3em 0.1em;";
    css["h1 a"] = "color:%color1%;";
    css["h2"] = "color:%color2%;border-bottom:1px solid %color2%;padding:0.2em 0.1em;";
    css["h2 a"] = "color:%color2%;";
    css["h3"] = "color:%color3%;border-bottom:1px solid %color3%;padding:0.1em 0.1em;";
    css["h3 a"] = "color:%color3%;";
    css["h4,h5,h6"] = "padding:0.1em 0.1em;";
    css["h4 a,h5 a,h6 a"] = "color:%color4%;";
    css["h1,h2,h3,h4,h5,h6"] = "font-weight:bolder;line-height:1.2em;";
    css["h4"] = "border-bottom:1px solid %color4%";
    css["p"] = "margin:0.5em 0.1em;"
    css["hr"] = "background:%color1%;height:1px;border:0;"
    css["a.normal, a.toc"] = "color:%color2%;";
    #css["a.normal:visited"] = "color:%color2%;";
    #css["a.normal:active"] = "color:%color4%;";
    css["a.normal:hover, a.toc:hover"] = "color:%color4%;";
    css["a.top"] = "font-size:x-small;text-decoration:initial;float:right;";
    css["a.header svg"] = "opacity:0;";
    css["a.header:hover svg"] = "opacity:1;";
    css["a.header"] = "text-decoration: none;";
    css["strong,b"] = "color:%color1%";
    css["code"] = "color:%color2%;font-weight:bold;";
    css["blockquote"] = "margin-left:1em;color:%color2%;border-left:0.2em solid %color3%;padding:0.25em 0.5em;overflow-x:auto;";
    css["pre"] = "color:%color2%;background:%color5%;border:1px solid;border-radius:2px;line-height:1.25em;margin:0.25em 0.5em;padding:0.75em;overflow-x:auto;";
    css["table.dawk-ex"] = "border-collapse:collapse;margin:0.5em;";
    css["th.dawk-ex,td.dawk-ex"] = "padding:0.5em 0.75em;border:1px solid %color4%;";
    css["th.dawk-ex"] = "color:%color2%;border:1px solid %color3%;border-bottom:2px solid %color3%;";
    css["tr.dawk-ex:nth-child(odd)"] = "background-color:%color5%;";
    css["div.dawk-ex"] = "padding:0.5em;";
    css["caption.dawk-ex"] = "padding:0.5em;font-style:italic;";
    css["dl.dawk-ex"] = "margin:0.5em;";
    css["dt.dawk-ex"] = "font-weight:bold;";
    css["dd.dawk-ex"] = "padding:0.3em;";
    css["mark.dawk-ex"] = "color:%color5%;background-color:%color4%;";
    css["del.dawk-ex,s.dawk-ex"] = "color:%color4%;";
    css["a.toc-button"] = "color:%color2%;cursor:pointer;font-size:small;padding: 0.3em 0.5em 0.5em 0.5em;font-family:monospace;border-radius:3px;";
    css["a.toc-button:hover"] = "color:%color4%;background:%color5%;";
    css["div#table-of-contents"] = "padding:0;font-size:smaller;";
    css["abbr"] = "cursor:help;";
    css["ol.footnotes"] = "font-size:small;color:%color4%";
    css["a.footnote"] = "font-size:smaller;text-decoration:initial;";
    css["a.footnote-back"] = "text-decoration:initial;font-size:x-small;";
    css[".fade"] = "color:%color5%;";
    css[".highlight"] = "color:%color2%;background-color:%color5%;";
    css["summary"] = "cursor:pointer;";
    css["ul.toc"] = "list-style-type:none;";

    if(NumberHeadings)  {
        if(NumberH1s) {
            css["body"] = css["body"] "counter-reset: h1 toc1;";
            css["h1"] = css["h1"] "counter-reset: h2 h3 h4;";
            css["h2"] = css["h2"] "counter-reset: h3 h4;";
            css["h3"] = css["h3"] "counter-reset: h4;";
            css["h1::before"] = "content: counter(h1) \" \"; counter-increment: h1; margin-right: 10px;";
            css["h2::before"] = "content: counter(h1) \".\"counter(h2) \" \";counter-increment: h2; margin-right: 10px;";
            css["h3::before"] = "content: counter(h1) \".\"counter(h2) \".\"counter(h3) \" \";counter-increment: h3; margin-right: 10px;";
            css["h4::before"] = "content: counter(h1) \".\"counter(h2) \".\"counter(h3)\".\"counter(h4) \" \";counter-increment: h4; margin-right: 10px;";

            css["li.toc-1"] = "counter-reset: toc2 toc3 toc4;";
            css["li.toc-2"] = "counter-reset: toc3 toc4;";
            css["li.toc-3"] = "counter-reset: toc4;";
            css["a.toc-1::before"] = "content: counter(h1) \"  \";counter-increment: toc1;";
            css["a.toc-2::before"] = "content: counter(h1) \".\" counter(toc2) \"  \";counter-increment: toc2;";
            css["a.toc-3::before"] = "content: counter(h1) \".\" counter(toc2) \".\" counter(toc3) \"  \";counter-increment: toc3;";
            css["a.toc-4::before"] = "content: counter(h1) \".\" counter(toc2) \".\" counter(toc3) \".\" counter(toc4) \"  \";counter-increment: toc4;";

        } else {
            css["h1"] = css["h1"] "counter-reset: h2 h3 h4;";
            css["h2"] = css["h2"] "counter-reset: h3 h4;";
            css["h3"] = css["h3"] "counter-reset: h4;";
            css["h2::before"] = "content: counter(h2) \" \";counter-increment: h2; margin-right: 10px;";
            css["h3::before"] = "content: counter(h2) \".\"counter(h3) \" \";counter-increment: h3; margin-right: 10px;";
            css["h4::before"] = "content: counter(h2) \".\"counter(h3)\".\"counter(h4) \" \";counter-increment: h4; margin-right: 10px;";

            css["li.toc-1"] = "counter-reset: toc2 toc3 toc4;";
            css["li.toc-2"] = "counter-reset: toc3 toc4;";
            css["li.toc-3"] = "counter-reset: toc4;";
            css["a.toc-2::before"] = "content: counter(toc2) \"  \";counter-increment: toc2;";
            css["a.toc-3::before"] = "content: counter(toc2) \".\" counter(toc3) \"  \";counter-increment: toc3;";
            css["a.toc-4::before"] = "content: counter(toc2) \".\" counter(toc3) \".\" counter(toc4) \"  \";counter-increment: toc4;";
        }
    }

    # Colors:
    #c1="#314070";c2="#465DA6";c3="#6676A8";c4="#A88C3F";c5="#E8E4D9";
    c1="#314070";c2="#384877";c3="#6676A8";c4="#738FD0";c5="#FBFCFF";
    # Font Family:
    ff = "sans-serif";
    fs = "11pt";

    # Alternative color scheme suggestions:
    #c1="#303F9F";c2="#0449CC";c3="#2162FA";c4="#4B80FB";c5="#EDF2FF";
    #ff="\"Trebuchet MS\", Helvetica, sans-serif";
    #c1="#430005";c2="#740009";c3="#A6373F";c4="#c55158";c5="#fbf2f2";
    #ff="Verdana, Geneva, sans-serif";
    #c1="#083900";c2="#0D6300";c3="#3C8D2F";c4="#50be3f";c5="#f2faf1";
    #ff="Georgia, serif";
    #c1="#35305D";c2="#646379";c3="#7A74A5";c4="#646392";c5="#fafafa";

    for(i = 0; i<=255; i++)_hex[sprintf("%02X",i)]=i;
    for(k in css)
        ss = ss "\n" k "{" css[k] "}";
    gsub(/%maxwidth%/,MaxWidth,ss);
    gsub(/%color1%/,c1,ss);
    gsub(/%color2%/,c2,ss);
    gsub(/%color3%/,c3,ss);
    gsub(/%color4%/,c4,ss);
    gsub(/%color5%/,c5,ss);
    gsub(/%font-family%/,ff,ss);
    gsub(/%font-size%/,fs,ss);
    gsub(/%hr%/,hr,ss);
    return ss;
}

#! /usr/bin/awk -f

##
# hashd.awk
# =========
#
# Converts Markdown in code comments to HTML of languages that use `#` symbols
# for code comments.
#
# <https://github.com/wernsey/d.awk>
#
#     (c) 2016 Werner Stoop
#     Copying and distribution of this file, with or without modification,
#     are permitted in any medium without royalty provided the copyright
#     notice and this notice are preserved. This file is offered as-is,
#     without any warranty.

BEGIN {

    # Configuration options
    if(Title=="") Title = "Documentation";
    if(Theme=="") Theme = 1;
    if(Pretty=="") Pretty = 0;
    if(HideToCLevel=="") HideToCLevel = 3;
    #TopLinks = 1;
    #classic_underscore = 1;
    if(MaxWidth=="") MaxWidth="1080px";

    Mode = (Clean)?"p":"none";
    ToC = ""; ToCLevel = 1;
    CSS = init_css(Theme);
    for(i = 0; i < 128; i++)
        _ord[sprintf("%c", i)] = i;
    srand();
}

Single && $0 !~ /^#/ {
    if(Mode == "ul" || Mode == "ol") {
        while(ListLevel > 1)
            Buf = Buf "\n</" Open[ListLevel--] ">";
        Out = Out tag(Mode, Buf "\n");
    } else {
        Buf = trim(scrub(Buf));
        if(Buf)
            Out = Out tag(Mode, Buf);
    }
    Mode = "none";
    Single = 0;
    Buf = "";
    Prev = "";
}
Single && /^#+/ {
    sub(/^#+/,"");
    Out = Out filter($0);
}
!Single && /^##+/ {
    sub(/^##+/,"");
    Single = 1;
    Mode = "p";
    Out = Out filter($0);
}

END {

    if(Mode == "ul" || Mode == "ol") {
        while(ListLevel > 1)
            Buf = Buf "\n</" Open[ListLevel--] ">";
        Out = Out tag(Mode, Buf "\n");
    } else if(Mode == "pre") {
        while(ListLevel > 1)
            Buf = Buf "\n</" Open[ListLevel--] ">";
        Out = Out tag(Mode, Buf "\n");
    } else {
        Buf = trim(scrub(Buf));
        if(Buf)
            Out = Out tag(Mode, Buf);
    }

    print "<!DOCTYPE html>\n"
    print "<title>" Title "</title>";
    if(StyleSheet)
        print "<link rel=\"stylesheet\" href=\"" StyleSheet "\">";
    else
        print "";
    print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">";
    if(ToC && match(Out, /!\[toc[-+]?\]/))
        print "";
    if(Pretty && HasCode)
        print "";
    print "";
    if(Out) {
        Out = fix_footnotes(Out);
        Out = fix_links(Out);
        Out = fix_abbrs(Out);
        Out = make_toc(Out);

        print trim(Out);
        if(footnotes) {
            footnotes = fix_links(footnotes);
            print "

\n" footnotes "
";
        }
    }
    print ""
}

function escape(st) {
    gsub(/&/, "\\&", st);
    gsub(/</, "\\<", st);
    gsub(/>/, "\\>", st);
    return st;
}
function strip_tags(st) {
    gsub(/<\/?[^>]+>/,"",st);
    return st;
}
function trim(st) {
    sub(/^[[:space:]]+/, "", st);
    sub(/[[:space:]]+$/, "", st);
    return st;
}
function filter(st,       res,tmp, linkdesc, url, delim, edelim, name, def) {
    if(Mode == "p") {
        if(match(st, /^[[:space:]]*\[[-._[:alnum:][:space:]]+\]:/)) {
            linkdesc = ""; LastLink = 0;
            match(st,/\[.*\]/);
            LinkRef = tolower(substr(st, RSTART+1, RLENGTH-2));
            st = substr(st, RSTART+RLENGTH+2);
            match(st, /[^[:space:]]+/);
            url = substr(st, RSTART, RLENGTH);
            st = substr(st, RSTART+RLENGTH+1);
            if(match(url, /^<.*>/))
                url = substr(url, RSTART+1, RLENGTH-2);
            if(match(st, /["'(]/)) {
                delim = substr(st, RSTART, 1);
                edelim = (delim == "(") ? ")" : delim;
                if(match(st, delim ".*" edelim))
                    linkdesc = substr(st, RSTART+1, RLENGTH-2);
            }
            LinkUrls[LinkRef] = escape(url);
            if(!linkdesc) LastLink = 1;
            LinkDescs[LinkRef] = escape(linkdesc);
            return;
        } else if(LastLink && match(st, /^[[:space:]]*["'(]/)) {
            match(st, /["'(]/);
            delim = substr(st, RSTART, 1);
            edelim = (delim == "(") ? ")" : delim;
            st = substr(st, RSTART);
            if(match(st, delim ".*" edelim))
                LinkDescs[LinkRef] = escape(substr(st,RSTART+1,RLENGTH-2));
            LastLink = 0;
            return;
        } else if(match(st, /^[[:space:]]*\[\^[-._[:alnum:][:space:]]+\]:[[:space:]]*/)) {
            match(st, /\[\^[[:alnum:]]+\]:/);
            name = substr(st, RSTART+2,RLENGTH-4);
            def = substr(st, RSTART+RLENGTH+1);
            Footnote[tolower(name)] = scrub(def);
            return;
        } else if(match(st, /^[[:space:]]*\*\[[[:alnum:]]+\]:[[:space:]]*/)) {
            match(st, /\[[[:alnum:]]+\]/);
            name = substr(st, RSTART+1,RLENGTH-2);
            def = substr(st, RSTART+RLENGTH+2);
            Abbrs[toupper(name)] = def;
            return;
        } else if(match(st, /^((    )| *\t)/) || match(st, /^[[:space:]]*```+[[:alnum:]]*/)) {
            Preterm = trim(substr(st, RSTART,RLENGTH));
            st = substr(st, RSTART+RLENGTH);
            if(Buf) res = tag("p", scrub(Buf));
            Buf = st;
            push("pre");
        } else if(!trim(Prev) && match(st, /^[[:space:]]*[*-][[:space:]]*[*-][[:space:]]*[*-][-*[:space:]]*$/)) {
            if(Buf) res = tag("p", scrub(Buf));
            Buf = "";
            res = res "<hr>\n";
        } else if(match(st, /^[[:space:]]*===+[[:space:]]*$/)) {
            Buf = trim(substr(Buf, 1, length(Buf) - length(Prev) - 1));
            if(Buf) res= tag("p", scrub(Buf));
            if(Prev) res = res heading(1, scrub(Prev));
            Buf = "";
        } else if(match(st, /^[[:space:]]*---+[[:space:]]*$/)) {
            Buf = trim(substr(Buf, 1, length(Buf) - length(Prev) - 1));
            if(Buf) res = tag("p", scrub(Buf));
            if(Prev) res = res heading(2, scrub(Prev));
            Buf = "";
        } else if(match(st, /^[[:space:]]*#+/)) {
            sub(/#+[[:space:]]*$/, "", st);
            match(st, /#+/);
            ListLevel = RLENGTH;
            tmp = substr(st, RSTART+RLENGTH);
            if(Buf) res = tag("p", scrub(Buf));
            res = res heading(ListLevel, scrub(trim(tmp)));
            Buf = "";
        } else if(match(st, /^[[:space:]]*>/)) {
            if(Buf) res = tag("p", scrub(Buf));
            Buf = scrub(trim(substr(st, RSTART+RLENGTH)));
            push("blockquote");
        } else if(match(st, /^[[:space:]]*([*+-]|[[:digit:]]+\.)[[:space:]]/)) {
            if(Buf) res = tag("p", scrub(Buf));
            Buf="";
            match(st, /^[[:space:]]*/);
            ListLevel = 1;
            indent[ListLevel] = RLENGTH;
            Open[ListLevel]=match(st, /^[[:space:]]*[*+-][[:space:]]*/)?"ul":"ol";
            push(Open[ListLevel]);
            res = res filter(st);
        } else if(match(st, /^[[:space:]]*$/)) {
            if(trim(Buf)) {
                res = tag("p", scrub(trim(Buf)));
                Buf = "";
            }
        } else
            Buf = Buf st "\n";
        LastLink = 0;
    } else if(Mode == "blockquote") {
        if(match(st, /^[[:space:]]*>[[:space:]]*$/))
            Buf = Buf "\n</p><p>";
        else if(match(st, /^[[:space:]]*>/))
            Buf = Buf "\n" scrub(trim(substr(st, RSTART+RLENGTH)));
        else if(match(st, /^[[:space:]]*$/)) {
            res = tag("blockquote", tag("p", trim(Buf)));
            pop();
            res = res filter(st);
        } else
            Buf = Buf st;
    } else if(Mode == "pre") {
        if(!Preterm && match(st, /^((    )| *\t)/) || Preterm && !match(st, /^[[:space:]]*```+/))
            Buf = Buf ((Buf)?"\n":"") substr(st, RSTART+RLENGTH);
        else {
            gsub(/\t/,"    ",Buf);
            if(length(trim(Buf)) > 0) {
                Lang = "";
                if(match(Preterm, /^[[:space:]]*```+/)) {
                    Lang = trim(substr(Preterm, RSTART+RLENGTH));
                    if(Lang) {
                        Lang = "class=\"prettyprint lang-" Lang "\"";
                        HasCode=1;
                    }
                }
                res = tag("pre", tag("code", escape(Buf), Lang));
            }
            pop();
            if(Preterm) sub(/^[[:space:]]*```+[[:alnum:]]*/,"",st);
            res = res filter(st);
        }
    } else if(Mode == "ul" || Mode == "ol") {
        if(ListLevel == 0 || match(st, /^[[:space:]]*$/) && (RLENGTH <= indent[1])) {
            while(ListLevel > 1)
                Buf = Buf "\n</" Open[ListLevel--] ">";
            res = tag(Mode, "\n" Buf "\n");
            pop();
        } else {
            if(match(st, /^[[:space:]]*([*+-]|[[:digit:]]+\.)/)) {
                tmp = substr(st, RLENGTH+1);
                match(st, /^[[:space:]]*/);
                if(RLENGTH > indent[ListLevel]) {
                    indent[++ListLevel] = RLENGTH;
                    if(match(st, /^[[:space:]]*[*+-]/))
                        Open[ListLevel] = "ul";
                    else
                        Open[ListLevel] = "ol";
                    Buf = Buf "\n<" Open[ListLevel] ">";
                } else while(RLENGTH < indent[ListLevel])
                    Buf = Buf "\n</" Open[ListLevel--] ">";
                if(match(tmp,/^[[:space:]]*\[[xX[:space:]]\]/)) {
                    st = substr(tmp,RLENGTH+1);
                    tmp = tolower(substr(tmp,RSTART,RLENGTH));
                    Buf = Buf "
<input type=\"checkbox\" " (index(tmp,"x")?"checked":"") " disabled>" scrub(st);
                } else
                    Buf = Buf "
" scrub(tmp);
            } else if(match(st, /^[[:space:]]*$/)){
                Buf = Buf "
\n";
            } else {
                sub(/^[[:space:]]+/,"",st);
                Buf = Buf "\n" scrub(st);
            }
        }
    }
    Prev = st;
    return res;
}
function scrub(st,    mp, ms, me, r, p, tg, a) {
    sub(/  $/,"
\n",st);
    gsub(/(  |[[:space:]]+\\)\n/,"
\n",st);
    gsub(/(  |[[:space:]]+\\)$/,"
\n",st);
    while(match(st, /(__?|\*\*?|~~|`+|[&><\\])/)) {
        a = substr(st, 1, RSTART-1);
        mp = substr(st, RSTART, RLENGTH);
        ms = substr(st, RSTART-1,1);
        me = substr(st, RSTART+RLENGTH, 1);
        p = RSTART+RLENGTH;

        if(!classic_underscore && match(mp,/_+/)) {
            if(match(ms,/[[:alnum:]]/) && match(me,/[[:alnum:]]/)) {
                tg = substr(st, 1, index(st, mp));
                r = r tg;
                st = substr(st, index(st, mp) + 1);
                continue;
            }
        }
        st = substr(st, p);
        r = r a;
        ms = "";

        if(mp == "\\") {
            if(match(st, /^!?\[/)) {
                r = r "\\" substr(st, RSTART, RLENGTH);
                st = substr(st, 2);
            } else if(match(st, /^(\*\*|__|~~|`+)/)) {
                r = r substr(st, 1, RLENGTH);
                st = substr(st, RLENGTH+1);
            } else {
                r = r substr(st, 1, 1);
                st = substr(st, 2);
            }
            continue;
        } else if(mp == "_" || mp == "*") {
            if(match(me,/[[:space:]]/)) {
                r = r mp;
                continue;
            }
            p = index(st, mp);
            while(p && match(substr(st, p-1, 1),/[\\[:space:]]/)) {
                ms = ms substr(st, 1, p-1) mp;
                st = substr(st, p + length(mp));
                p = index(st, mp);
            }
            if(!p) {
                r = r mp ms;
                continue;
            }
            ms = ms substr(st,1,p-1);
            r = r itag("em", scrub(ms));
            st = substr(st,p+length(mp));
        } else if(mp == "__" || mp == "**") {
            if(match(me,/[[:space:]]/)) {
                r = r mp;
                continue;
            }
            p = index(st, mp);
            while(p && match(substr(st, p-1, 1),/[\\[:space:]]/)) {
                ms = ms substr(st, 1, p-1) mp;
                st = substr(st, p + length(mp));
                p = index(st, mp);
            }
            if(!p) {
                r = r mp ms;
                continue;
            }
            ms = ms substr(st,1,p-1);
            r = r itag("strong", scrub(ms));
            st = substr(st,p+length(mp));
        } else if(mp == "~~") {
            p = index(st, mp);
            if(!p) {
                r = r mp;
                continue;
            }
            while(p && substr(st, p-1, 1) == "\\") {
                ms = ms substr(st, 1, p-1) mp;
                st = substr(st, p + length(mp));
                p = index(st, mp);
            }
            ms = ms substr(st,1,p-1);
            r = r itag("del", scrub(ms));
            st = substr(st,p+length(mp));
        } else if(match(mp, /`+/)) {
            p = index(st, mp);
            if(!p) {
                r = r mp;
                continue;
            }
            ms = substr(st,1,p-1);
            r = r itag("code", escape(ms));
            st = substr(st,p+length(mp));
        } else if(mp == ">") {
            r = r ">";
        } else if(mp == "<") {

            p = index(st, ">");
            if(!p) {
                r = r "<";
                continue;
            }
            tg = substr(st, 1, p - 1);
            if(match(tg,/^[[:alpha:]]+[[:space:]]/)) {
                a = substr(tg,RSTART+RLENGTH-1);
                tg = substr(tg,1,RLENGTH-1);
            } else
                a = "";

            if(match(tolower(tg), "^/?(a|abbr|div|span|blockquote|pre|img|code|p|em|strong|sup|sub|del|ins|s|u|b|i|br|hr|ul|ol|li|table|thead|tfoot|tbody|tr|th|td|caption|column|col|colgroup|figure|figcaption|dl|dd|dt|mark|cite|q|var|samp|small|details|summary)$")) {
                r = r "<" tg a ">";
            } else if(match(tg, "^[[:alpha:]]+://[[:graph:]]+$")) {
                if(!a) a = tg;
                r = r "" a "";
            } else if(match(tg, "^[[:graph:]]+@[[:graph:]]+$")) {
                if(!a) a = tg;
                r = r "" obfuscate(a) "";
            } else {
                r = r "<";
                continue;
            }

            st = substr(st, p + 1);
        } else if(mp == "&") {
            if(match(st, /^[#[:alnum:]]+;/)) {
                r = r "&" substr(st, 1, RLENGTH);
                st = substr(st, RLENGTH+1);
            } else {
                r = r "&";
            }
        }
    }
    return r st;
}

function push(newmode) {Stack[StackTop++] = Mode; Mode = newmode;}
function pop() {Mode = Stack[--StackTop];Buf = ""; return Mode;}
function heading(level, st,       res, href) {
    st = trim(st);
    if(level > 6) level = 6;
    href = tolower(st);
    href = strip_tags(href);
    gsub(/[^ [:alnum:]]+/, "", href);
    gsub(/ +/, "-", href);
    if(!LinkUrls[href]) LinkUrls[href] = "#" href;
    if(!LinkUrls[tolower(st)]) LinkUrls[tolower(st)] = "#" href;
    res = tag("h" level, st (TopLinks?"  ↑ Top":""), "id=\"" href "\"");
    for(;ToCLevel < level; ToCLevel++) {
        ToC_ID++;
        if(ToCLevel < HideToCLevel) {
            ToC = ToC "▲";
            ToC = ToC "
";
        } else {
            ToC = ToC "▼";
            ToC = ToC "
";
        }
    }
    for(;ToCLevel > level; ToCLevel--)
        ToC = ToC "
";
    ToC = ToC "
" st "\n";
    ToCLevel = level;
    return res;
}
function make_toc(st,              r,p,dis,t,n) {
    if(!ToC) return st;
    for(;ToCLevel > 1;ToCLevel--)
        ToC = ToC "
";
    p = match(st, /!\[toc[-+]?\]/);
    while(p) {
        if(substr(st,RSTART-1,1) == "\\") {
            r = r substr(st,1,RSTART-2) substr(st,RSTART,RLENGTH);
            st = substr(st,RSTART+RLENGTH);
            p = match(st, /!\[toc[-+]?\]/);
            continue;
        }

        ++n;
        dis = index(substr(st,RSTART,RLENGTH),"+");
        t = "
\n" (dis?"▲":"▼") " Contents\n" \
            "
\n
" ToC "
\n
\n
";
        r = r substr(st,1,RSTART-1);
        r = r t;
        st = substr(st,RSTART+RLENGTH);
        p = match(st, /!\[toc[-+]?\]/);
    }
    return r st;
}
function fix_links(st,          lt,ld,lr,url,img,res,rx,pos,pre) {
    do {
        pre = match(st, /
/); # Don't substitute in
 blocks
        pos = match(st, /\[[^\]]+\]/);
        if(!pos)break;
        if(pre && pre < pos) {
            pre = match(st, /<\/pre>/);
            res = res substr(st,1,RSTART+RLENGTH);
            st = substr(st, RSTART+RLENGTH);
            continue;
        }
        img=substr(st,RSTART-1,1)=="!";
        if(substr(st, RSTART-(img?2:1),1)=="\\") {
            res = res substr(st,1,RSTART-(img?3:2));
            if(img && substr(st,RSTART,RLENGTH)=="[toc]")res=res "\\";
            res = res substr(st,RSTART-(img?1:0),RLENGTH+(img?1:0));
            st = substr(st, RSTART + RLENGTH);
            continue;
        }
        res = res substr(st, 1, RSTART-(img?2:1));
        rx = substr(st, RSTART, RLENGTH);
        st = substr(st, RSTART+RLENGTH);
        if(match(st, /^[[:space:]]*\([^)]+\)/)) {
            lt = substr(rx, 2, length(rx) - 2);
            match(st, /\([^)]+\)/);
            url = substr(st, RSTART+1, RLENGTH-2);
            st = substr(st, RSTART+RLENGTH);
            ld = "";
            if(match(url,/[[:space:]]+["']/)) {
                ld = url;
                url = substr(url, 1, RSTART - 1);
                match(ld,/["']/);
                delim = substr(ld, RSTART, 1);
                if(match(ld,delim ".*" delim))
                    ld = substr(ld, RSTART+1, RLENGTH-2);
            }  else ld = "";
            if(img)
                res = res "";
            else
                res = res "" lt "";
        } else if(match(st, /^[[:space:]]*\[[^\]]*\]/)) {
            lt = substr(rx, 2, length(rx) - 2);
            match(st, /\[[^\]]*\]/);
            lr = trim(tolower(substr(st, RSTART+1, RLENGTH-2)));
            if(!lr) {
                lr = tolower(trim(lt));
                if(LinkDescs[lr]) lt = LinkDescs[lr];
            }
            st = substr(st, RSTART+RLENGTH);
            url = LinkUrls[lr];
            ld = LinkDescs[lr];
            if(img)
                res = res "";
            else
                res = res "" lt "";
        } else
            res = res (img?"!":"") rx;
    } while(pos > 0);
    return res st;
}
function fix_footnotes(st,         r,p,n,i,d,fn,fc) {
    p = match(st, /\[\^[^\]]+\]/);
    while(p) {
        if(substr(st,RSTART-2,1) == "\\") {
            r = r substr(st,1,RSTART-3) substr(st,RSTART,RLENGTH);
            st = substr(st,RSTART+RLENGTH);
            p = match(st, /\[\^[^\]]+\]/);
            continue;
        }
        r = r substr(st,1,RSTART-1);
        d = substr(st,RSTART+2,RLENGTH-3);
        n = tolower(d);
        st = substr(st,RSTART+RLENGTH);
        if(Footnote[tolower(n)]) {
            if(!fn[n]) fn[n] = ++fc;
            d = Footnote[n];
        } else {
            Footnote[n] = scrub(d);
            if(!fn[n]) fn[n] = ++fc;
        }
        footname[fc] = n;
        d = strip_tags(d);
        if(length(d) > 20) d = substr(d,1,20) "…";
        r = r "[" fn[n] "]";
        p = match(st, /\[\^[^\]]+\]/);
    }
    for(i=1;i<=fc;i++)
        footnotes = footnotes "
" Footnote[footname[i]] \
            "  ↶ Back
\n";
    return r st;
}
function fix_abbrs(str,         st,k,r,p) {
    for(k in Abbrs) {
        r = "";
        st = str;
        t = escape(Abbrs[toupper(k)]);
        gsub(/&/,"\\&", t);
        p = match(st,"[^[:alnum:]]" k "[^[:alnum:]]");
        while(p) {
            r = r substr(st, 1, RSTART);
            r = r "" k "";
            st = substr(st, RSTART+RLENGTH-1);
            p = match(st,"[^[:alnum:]]" k "[^[:alnum:]]");
        }
        str = r st;
    }
    return str;
}
function tag(t, body, attr) {
    if(attr)
        attr = " " trim(attr);
    # https://www.w3.org/TR/html5/grouping-content.html#the-p-element
    if(t == "p" && (match(body, /<\/?(div|table|blockquote|dl|ol|ul|h[[:digit:]]|hr|pre)[>[:space:]]/))|| (match(body,/!\[toc\]/) && substr(body, RSTART-1,1) != "\\"))
        return "<" t attr ">" body "\n";
    else
        return "<" t attr ">" body "</" t ">\n";
}
function itag(t, body) {
    return "<" t ">" body "</" t ">";
}
function obfuscate(e,     r,i,t,o) {
    for(i = 1; i <= length(e); i++) {
        t = substr(e,i,1);
        r = int(rand() * 100);
        if(r > 50)
            o = o sprintf("&#x%02X;", _ord[t]);
        else if(r > 10)
            o = o sprintf("&#%d;", _ord[t]);
        else
            o = o t;
    }
    return o;
}
function init_css(Theme,             css,ss,hr,c1,c2,c3,c4,c5,bg1,bg2,bg3,bg4,ff,fs,i) {
    if(Theme == "0") return "";

    css["body"] = "color:%color1%;font-family:%font-family%;font-size:%font-size%;line-height:1.5em;" \
                "padding:1em 2em;width:80%;max-width:%maxwidth%;margin:0 auto;min-height:100%;float:none;";
    css["h1"] = "color:%color1%;border-bottom:1px solid %color1%;padding:0.3em 0.1em;";
    css["h2"] = "color:%color2%;border-bottom:1px solid %color2%;padding:0.2em 0.1em;";
    css["h3"] = "color:%color3%;border-bottom:1px solid %color3%;padding:0.1em 0.1em;";
    css["h4,h5,h6"] = "color:%color4%;padding:0.1em 0.1em;";
    css["h1,h2,h3,h4,h5,h6"] = "font-weight:normal;line-height:1.2em;";
    css["h4"] = "border-bottom:1px solid %color4%";
    css["p"] = "margin:0.5em 0.1em;"
    css["hr"] = "background:%color1%;height:1px;border:0;"
    css["a"] = "color:%color2%;";
    css["a:visited"] = "color:%color2%;";
    css["a:active"] = "color:%color4%;";
    css["a:hover"] = "color:%color4%;";
    css["a.top"] = "font-size:x-small;text-decoration:initial;float:right;";
    css["strong,b"] = "color:%color1%";
    css["code"] = "color:%color2%;";
    css["blockquote"] = "margin-left:1em;color:%color2%;border-left:0.2em solid %color3%;padding:0.25em 0.5em;overflow-x:auto;";
    css["pre"] = "color:%color2%;background:%color5%;border:1px solid;border-radius:2px;line-height:1.25em;margin:0.25em 0.5em;padding:0.75em;overflow-x:auto;";
    css["table"] = "border-collapse:collapse;margin:0.5em;";
    css["th,td"] = "padding:0.5em 0.75em;border:1px solid %color4%;";
    css["th"] = "color:%color2%;border:1px solid %color3%;border-bottom:2px solid %color3%;";
    css["tr:nth-child(odd)"] = "background-color:%color5%;";
    css["div"] = "padding:0.5em;";
    css["caption"] = "padding:0.5em;font-style:italic;";
    css["dl"] = "margin:0.5em;";
    css["dt"] = "font-weight:bold;";
    css["dd"] = "padding:0.3em;";
    css["mark"] = "color:%color2%;background-color:%color5%;";
    css["del,s"] = "color:%color4%;";
    css["a.toc-button"] = "color:%color2%;cursor:pointer;font-size:small;padding: 0.3em 0.5em 0.5em 0.5em;font-family:monospace;border-radius:3px;";
    css["a.toc-button:hover"] = "color:%color4%;background:%color5%;";
    css["div#table-of-contents"] = "padding:0;font-size:smaller;";
    css["abbr"] = "cursor:help;";
    css["ol.footnotes"] = "font-size:small;color:%color4%";
    css["a.footnote"] = "font-size:smaller;text-decoration:initial;";
    css["a.footnote-back"] = "text-decoration:initial;font-size:x-small;";
    css[".fade"] = "color:%color5%;";
    css[".highlight"] = "color:%color2%;background-color:%color5%;";
	css["summary"] = "cursor:pointer;";

    # Colors:
    c1="#314070";c2="#465DA6";c3="#6676A8";c4="#A88C3F";c5="#E8E4D9";
    # Font Family:
    ff = "sans-serif";
    fs = "11pt";

    # Alternative color scheme suggestions:
    #c1="#303F9F";c2="#0449CC";c3="#2162FA";c4="#4B80FB";c5="#EDF2FF";
    #ff="\"Trebuchet MS\", Helvetica, sans-serif";
    #c1="#430005";c2="#740009";c3="#A6373F";c4="#c55158";c5="#fbf2f2";
    #ff="Verdana, Geneva, sans-serif";
    #c1="#083900";c2="#0D6300";c3="#3C8D2F";c4="#50be3f";c5="#f2faf1";
    #ff="Georgia, serif";
    #c1="#35305D";c2="#646379";c3="#7A74A5";c4="#646392";c5="#fafafa";

    for(i = 0; i<=255; i++)_hex[sprintf("%02X",i)]=i;
    for(k in css)
        ss = ss "\n" k "{" css[k] "}";
    gsub(/%maxwidth%/,MaxWidth,ss);
    gsub(/%color1%/,c1,ss);
    gsub(/%color2%/,c2,ss);
    gsub(/%color3%/,c3,ss);
    gsub(/%color4%/,c4,ss);
    gsub(/%color5%/,c5,ss);
    gsub(/%font-family%/,ff,ss);
    gsub(/%font-size%/,fs,ss);
    gsub(/%hr%/,hr,ss);
    return ss;
}


gcj's javadoc wants lowercase hexadecimal constants. (dm)

git-svn-id: 30a5f035a20f1bc647618dbad7eea2a951b61b7c@2659 91a5dbb7-01b9-0310-9b5f-b28072856b6e

###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
#          text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2006 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation.  Please see the file COPYING for details.
#
# Web Page: http://mielke.cc/brltty/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

BEGIN {
  print "public interface BrlapiConstants {"
}

END {
  print "}"
}

function brlCommand(name, symbol, value, help) {
  writeCommandDefinition(name, value, help)
}

function brlBlock(name, symbol, value, help) {
  if (name == "PASSCHAR") return
  if (name == "PASSKEY") return

  if (value ~ /^0[xX][0-9a-fA-F]+00$/) {
    writeCommandDefinition(name, hexadecimalValue(value) "00", help)
  }
}

function brlKey(name, symbol, value, help) {
}

function brlFlag(name, symbol, value, help) {
  if (value ~ /^0[xX][0-9a-fA-F]+0000$/) {
    value = hexadecimalValue(substr(value, 1, length(value)-4))
    if (name ~ /^CHAR_/) {
      name = substr(name, 6)
    } else {
      value = value "00"
    }
  } else if (value ~ /^\(/) {
    gsub("BRL_FLG_", "KEY_FLG_", value)
  } else {
    return
  }
  writeJavaConstant("int", "KEY_FLG_" name, value, help)
}

function brlDot(number, symbol, value, help) {
  writeJavaConstant("int", "BRL_DOT" number, value, help)
}

function apiType(name, symbol, value, help) {
  writeJavaConstant("int", "KEY_TYPE_" name, hexadecimalValue(value));
}

function apiKey(name, symbol, value, help) {
  value = hexadecimalValue(value)

  if (name == "FUNCTION") {
    for (i=0; i<35; ++i) {
      writeKeyDefinition("F" (i+1), "(" value " + " i ")")
    }
  } else {
    writeKeyDefinition(name, value)
  }
}

function writeCommandDefinition(name, value, help) {
  writeJavaConstant("int", "KEY_CMD_" name, "(KEY_TYPE_CMD | " value ")", help)
}

function writeKeyDefinition(name, value) {
  writeJavaConstant("int", "KEY_SYM_" name, "(KEY_TYPE_SYM | " value ")")
}

function writeJavaConstant(type, name, value, help) {
  writeJavadocComment(help)
  print "  public static final " type " " name " = " value ";"
}

function writeJavadocComment(text) {
  if (length(text) > 0) print "  /** " text " */"
}

function hexadecimalValue(value) {
  value = tolower(value)
  gsub("u?l*$", "", value)
  gsub("x0+", "x0", value)
  return value
}

###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
#          text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2006 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation.  Please see the file COPYING for details.
#
# Web Page: http://mielke.cc/brltty/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

BEGIN {
  print "public interface BrlapiConstants {"
}

END {
  print "}"
}

function brlCommand(name, symbol, value, help) {
  writeCommandDefinition(name, value, help)
}

function brlBlock(name, symbol, value, help) {
  if (name == "PASSCHAR") return
  if (name == "PASSKEY") return

  if (value ~ /^0[xX][0-9a-fA-F]+00$/) {
    writeCommandDefinition(name, toupper(value) "00", help)
  }
}

function brlKey(name, symbol, value, help) {
}

function brlFlag(name, symbol, value, help) {
  if (value ~ /^0[xX][0-9a-fA-F]+0000$/) {
    value = toupper(substr(value, 1, length(value)-4))
    if (name ~ /^CHAR_/) {
      name = substr(name, 6)
    } else {
      value = value "00"
    }
  } else if (value ~ /^\(/) {
    gsub("BRL_FLG_", "KEY_FLG_", value)
  } else {
    return
  }
  writeJavaConstant("KEY_FLG_" name, value, help)
}

function brlDot(number, symbol, value, help) {
  writeJavaConstant("BRL_DOT" number, value, help)
}

function apiType(name, symbol, value, help) {
  writeJavaConstant("KEY_TYPE_" name, hexadecimalValue(value));
}

function apiKey(name, symbol, value, help) {
  value = hexadecimalValue(value)

  if (name == "FUNCTION") {
    for (i=0; i<35; ++i) {
      writeKeyDefinition("F" (i+1), "(" value " + " i ")")
    }
  } else {
    writeKeyDefinition(name, value)
  }
}

function writeCommandDefinition(name, value, help) {
  writeJavaConstant("KEY_CMD_" name, "(KEY_TYPE_CMD | " value ")", help)
}

function writeKeyDefinition(name, value) {
  writeJavaConstant("KEY_SYM_" name, "(KEY_TYPE_SYM | " value ")")
}

function writeJavaConstant(name, value, help) {
  writeJavadocComment(help)
  print "  public static final int " name " = " value ";"
}

function writeJavadocComment(text) {
  print "  /** " text " */"
}

function hexadecimalValue(value) {
  gsub("[uU]?[lL]*$", "", value)
  return value
}


Const has static linkage

Const has static linkage

bin/obj/Linux.x64.Debug/src/dlls/mscorrc/full/mscorrc_debug.cpp:1002:110: error: ‘visibility’ attribute ignored [-Werror=attributes]
 const NativeStringResourceTable nativeStringResourceTable_mscorrc_debug __attribute__((visibility("default"))) = {

# Convert string resources from Windows native resource file to a C++
# source file with an array of structs representing the resources.

BEGIN {
    numEntries = 0;
}

# Takes a number and returns a string corresponding to its hex
# representation. A string representation that has fewer than 8
# characters (not including the '0x' prefix) is padded with 0's
# to make it 8 characters.
# Example: an input of 49 yields "0x00000031".
function numberToHexString(number)
{
    quotient = number;

    hexString = "";
    for (digitCount = 0; digitCount < 8; digitCount++)
    {
        remainder = quotient % 16;
        quotient = int(quotient / 16);
        hexString = sprintf("%x"hexString, remainder);
    }

    hexString = "0x" hexString;
    return hexString;
}

# Add each entry that is in our associative array of entries to the
# C++ array we are building. The C++ array will be ordered by the
# resourceId (lowest to highest) to facilitate quick lookups.
function writesortedentries()
{
    for (entry in resourceArray)
    {
        # Write the entries to the C++ array ordered by the ID.
        printf "    {%s,%s},\n", entry, resourceArray[entry] | "sort";
    }

    # Close the pipe to ensure that the data is written now.
    close("sort");
}

# Write entry for a string resource
# This is called for each entry. Because we want to write them in
# sorted order once all the entries have come in, for now we just
# store each entry in an associative array.
function writestringentry(id, str)
{
    numEntries++;

    # Use the string representation of the ID as the array index
    # because the precision of numeric indices can be lost during
    # the number -> string -> number conversions that would occur
    # if numeric indices are used.
    resourceArray[numberToHexString(id)] = str;
}

# Write file header and begin the array we will populate with the resources.
function writeheader(arrayName, tableName)
{
    print "// This code was generated by rctocpp.awk and is not meant to be modified manually."
    print "#include <resourcestring.h>";
    print "";
    print "extern NativeStringResourceTable " tableName ";";
    print "const NativeStringResource " arrayName "[] = {";
}

# Write file footer
# This function is called after all of the entries have been given to
# writestringentry. Because we know there are no more entries, we can
# now write all the entries we received so far when this is called.
# After we have written all the entries, we close the array and add a
# constant for the size of the array for convenience.
function writefooter(arrayName, tableName)
{
    writesortedentries();
    print "};";
    print "";

    print "NativeStringResourceTable " tableName " __attribute__((visibility(\"default\"))) = {";
    print numEntries ",";
    print arrayName "};";
}

# Convert string resources from Windows native resource file to a C++
# source file with an array of structs representing the resources.

BEGIN {
    numEntries = 0;
}

# Takes a number and returns a string corresponding to its hex
# representation. A string representation that has fewer than 8
# characters (not including the '0x' prefix) is padded with 0's
# to make it 8 characters.
# Example: an input of 49 yields "0x00000031".
function numberToHexString(number)
{
    quotient = number;

    hexString = "";
    for (digitCount = 0; digitCount < 8; digitCount++)
    {
        remainder = quotient % 16;
        quotient = int(quotient / 16);
        hexString = sprintf("%x"hexString, remainder);
    }

    hexString = "0x" hexString;
    return hexString;
}

# Add each entry that is in our associative array of entries to the
# C++ array we are building. The C++ array will be ordered by the
# resourceId (lowest to highest) to facilitate quick lookups.
function writesortedentries()
{
    for (entry in resourceArray)
    {
        # Write the entries to the C++ array ordered by the ID.
        printf "    {%s,%s},\n", entry, resourceArray[entry] | "sort";
    }

    # Close the pipe to ensure that the data is written now.
    close("sort");
}

# Write entry for a string resource
# This is called for each entry. Because we want to write them in
# sorted order once all the entries have come in, for now we just
# store each entry in an associative array.
function writestringentry(id, str)
{
    numEntries++;

    # Use the string representation of the ID as the array index
    # because the precision of numeric indices can be lost during
    # the number -> string -> number conversions that would occur
    # if numeric indices are used.
    resourceArray[numberToHexString(id)] = str;
}

# Write file header and begin the array we will populate with the resources.
function writeheader(arrayName, tableName)
{
    print "// This code was generated by rctocpp.awk and is not meant to be modified manually."
    print "#include <resourcestring.h>";
    print "";
    print "extern const NativeStringResourceTable " tableName ";";
    print "const NativeStringResource " arrayName "[] = {";
}

# Write file footer
# This function is called after all of the entries have been given to
# writestringentry. Because we know there are no more entries, we can
# now write all the entries we received so far when this is called.
# After we have written all the entries, we close the array and add a
# constant for the size of the array for convenience.
function writefooter(arrayName, tableName)
{
    writesortedentries();
    print "};";
    print "";

    print "const NativeStringResourceTable " tableName " __attribute__((visibility(\"default\"))) = {";
    print numEntries ",";
    print arrayName "};";
}


Fix unterminated source lines

Fix unterminated source lines

# Print lines from a WebScraper csv file after joining extra newlines
# Make sure lines have a terminating double quote (except header line)

# INVOCATION:
#   awk -f fixExtraLinesFrom-webscraper.awk BritBoxPrograms.csv

{
    if (/^"/) {
        if (line !~ "\"$" && NR != 2)
            line = line "\""
        print line
        line = $0
    } else {
        line = line $0
    }
}

END {
    if (line !~ "\"$")
        line = line "\""
    print line
}

# Print lines from a WebScraper csv file after joining extra newlines

# INVOCATION:
#   awk -f fixExtraLinesFrom-webscraper.awk BritBoxPrograms.csv

{
    if (/^"/)
        printf ("\n" $0)
    else
        printf
}

END {
    printf ("\n")
}


2.13.awk

#!/usr/bin/awk -f
BEGIN	{
	printf("#include \"apue.h\"\n")
	printf("#include <erron.h>\n")
	printf("#include <limits.h>\n")
	printf("\n")
	printf("static void pr_sysconf(char *, int);\n")
	printf("static void pr_pathconf(char *, char *, int);\n")
	printf("\n")
	printf("int\n")
	printf("main(int argc, char *argv[])\n")
	printf("{\n")
	printf("\tif (argc != 2)\n")
	printf("\t\terr_quit{\"usage: a.out <dirname>\";\n\n")
	FS="\t+"
	while (getline <"sysconf.sym" > 0) {
		printf("#ifdef %s\n", $1)
		printf("\tprintf(\"%s defined to be %%ld\\n\", (long)%s+0);\n", $1, $1)
		printf("#else\n")
		printf("\tprintf(\"no symbol for %s\\n");\n", $1)
		printf("#endif\n")
		printf("#ifdef %s\n", $2)
		printf("\tpr_sysconf(\"%s = \", %s);\n", $1, $2)
		printf("#else\n")
		printf("\tprintf(\"no symbol for %s\\n");\n", $2)
		printf("#endif\n")
	}
	close("sysconf.sym")
	while (getline <"pathconf.sym" > 0) {
		printf("#ifdef %s\n", $1)
        printf(" printf(\"%s defined to be %%d\\n\", %s+0);\n", $1, $1)
        printf("#else\n")
        printf(" printf(\"no symbol for %s\\n\");\n", $1)
        printf("#endif\n")
        printf("#ifdef %s\n", $2)
        printf(" pr_pathconf(\"%s =\", argv[1], %s);\n", $1, $2)
        printf("#else\n")
        printf(" printf(\"no symbol for %s\\n\");\n", $2)
        printf("#endif\n")
    }
    close("pathconf.sym")
    exit
	}
END {
    printf(" exit(0);\n")
    printf("}\n\n")
    printf("static void\n")
    printf("pr_sysconf(char *mesg, int name)\n")
    printf("{\n")
    printf(" long val;\n\n")
    printf(" fputs(mesg, stdout);\n")
    printf(" errno = 0;\n")
    printf(" if ((val = sysconf(name)) < 0) {\n")
    printf("  if (errno != 0) {\n")
    printf("   if (errno == EINVAL)\n")
    printf("    fputs(\" (not supported)\\n\", stdout);\n")
    printf("   else\n")
    printf("    err_sys(\"sysconf error\");\n")
    printf("  } else {\n")
    printf("   fputs(\" (no limit)\\n\", stdout);\n")
    printf("  }\n")
    printf(" } else {\n")
    printf("  printf(\" %%ld\\n\", val);\n")
    printf(" }\n")
    printf("}\n\n")
    printf("static void\n")
    printf("pr_pathconf(char *mesg, char *path, int name)\n")
    printf("{\n")
    printf(" long val;\n")
    printf("\n")
    printf(" fputs(mesg, stdout);\n")
    printf(" errno = 0;\n")
    printf(" if ((val = pathconf(path, name)) < 0) {\n")
    printf("  if (errno != 0) {\n")
    printf("   if (errno == EINVAL)\n")
    printf("    fputs(\" (not supported)\\n\", stdout);\n")
    printf("   else\n")
    printf("    err_sys(\"pathconf error, path = %%s\", path);\n")
    printf("  } else {\n")
    printf("   fputs(\" (no limit)\\n\", stdout);\n")
    printf("  }\n")
    printf(" } else {\n")
    printf("  printf(\" %%ld\\n\", val);\n")
    printf(" }\n")
    printf("}\n")
}
}

#!/usr/bin/awk -f
BEGIN	{
	printf("#include \"apue.h\"\n")
	printf("#include <erron.h>\n")
	printf("#include <limits.h>\n")
	printf("\n")
	printf("static void pr_sysconf(char *, int);\n")
	printf("static void pr_pathconf(char *, char *, int);\n")
	printf("\n")
	printf("int\n")
	printf("main(int argc, char *argv[])\n")
	printf("{\n")
	printf("\tif (argc != 2)\n")
	printf("\t\terr_quit{\"usage: a.out <dirname>\";\n\n")
	FS="\t+"
	while (getline <"sysconf.sym" > 0) {
		printf("#ifdef %s\n", $1)
		printf("\tprintf(\"%s defined to be %%ld\\n", (long)%s+0);\n", $1, $1)
		printf("#else\n")
		printf("\tprintf(\"no symbol for %s\\n");\n", $1)
		printf("#endif\n")
		printf("#ifdef %s\n", $2)
		printf("\tpr_sysconf(\"%s = \", %s);\n", $1, $2)
		printf("#else\n")
		printf("\tprintf(\"no symbol for %s\\n");\n", $2)
		printf("#endif\n")
	}
	close("sysconf.sym")
	while (getline <"pathconf.sym" > 0) {
		printf("#ifdef %s\n", $1)
        printf(" printf(\"%s defined to be %%d\\n\", %s+0);\n", $1, $1)
        printf("#else\n")
        printf(" printf(\"no symbol for %s\\n\");\n", $1)
        printf("#endif\n")
        printf("#ifdef %s\n", $2)
        printf(" pr_pathconf(\"%s =\", argv[1], %s);\n", $1, $2)
        printf("#else\n")
        printf(" printf(\"no symbol for %s\\n\");\n", $2)
        printf("#endif\n")
    }
    close("pathconf.sym")
    exit
	}
END {
    printf(" exit(0);\n")
    printf("}\n\n")
    printf("static void\n")
    printf("pr_sysconf(char *mesg, int name)\n")
    printf("{\n")
    printf(" long val;\n\n")
    printf(" fputs(mesg, stdout);\n")
    printf(" errno = 0;\n")
    printf(" if ((val = sysconf(name)) < 0) {\n")
    printf("  if (errno != 0) {\n")
    printf("   if (errno == EINVAL)\n")
    printf("    fputs(\" (not supported)\\n\", stdout);\n")
    printf("   else\n")
    printf("    err_sys(\"sysconf error\");\n")
    printf("  } else {\n")
    printf("   fputs(\" (no limit)\\n\", stdout);\n")
    printf("  }\n")
    printf(" } else {\n")
    printf("  printf(\" %%ld\\n\", val);\n")
    printf(" }\n")
    printf("}\n\n")
    printf("static void\n")
    printf("pr_pathconf(char *mesg, char *path, int name)\n")
    printf("{\n")
    printf(" long val;\n")
    printf("\n")
    printf(" fputs(mesg, stdout);\n")
    printf(" errno = 0;\n")
    printf(" if ((val = pathconf(path, name)) < 0) {\n")
    printf("  if (errno != 0) {\n")
    printf("   if (errno == EINVAL)\n")
    printf("    fputs(\" (not supported)\\n\", stdout);\n")
    printf("   else\n")
    printf("    err_sys(\"pathconf error, path = %%s\", path);\n")
    printf("  } else {\n")
    printf("   fputs(\" (no limit)\\n\", stdout);\n")
    printf("  }\n")
    printf(" } else {\n")
    printf("  printf(\" %%ld\\n\", val);\n")
    printf(" }\n")
    printf("}\n")
}
}


[as] Print proper error messages in gen.awk

BEGIN		{
		FS = "\t"
		printf "#include \"../../../inc/scc.h\"\n"\
		       "#include \"../../as.h\"\n"\
		       "#include \"../" family "/proc.h\"\n"
		nop = 0; nvar = 0
}
		{sub(/#.*/,"")}

$6 !~ cpu	{next}

/^$/		{next}

		{
		if (opstart[$1] == 0) {
			opstart[$1] = nvar
			opnames[nop++] = $1
		}
		opcount[$1]++
		opargs[nvar] = $2
		opsize[nvar] = $3
		opbytes[nvar] = ($4 == "none") ? "" : $4
		opformat[nvar++] = $5
		formats[$5] = 1
}
END		{
		for (i in formats)
			printf "Format %s;\n", i

		printf "int nr_ins = %d;\n\n", nop
		print "struct ins instab[] = {"
		for (i = 0; i < nop; i++) {
			n = opnames[i]
			start = opstart[n]
			end = start + opcount[n]
			printf "\t{.str = \"%s\", .begin = %d, .end = %d},\n",
			       n, start, end | "sort"
		}
		close("sort")
		printf "};\n\n"

		print "struct op optab[] = {"
		for (i = 0; i < nvar; i++) {
			printf "\t{\n" \
			       "\t\t.size = %d,\n"\
			       "\t\t.format = %s,\n",
			       opsize[i], opformat[i]

			if (opbytes[i] != "")
				printf "\t\t.bytes = (unsigned char []) {%s},\n",
				        opbytes[i]

			a = str2args(opargs[i])
			if (a != "")
				printf "\t\t.args = (unsigned char []) {%s}\n", a

			print "\t},"
		}
		print "};"
}

function str2args(s, args, i, out, n)
{
	n = split(s, args, /,/)
	if (n == 0 || args[1] == "none")
		return ""
	for (i = 1; i <= n; i++) {
		a = args[i]
		if (match(a, /^imm8/)) {
			out = out "AIMM8"
		} else if (match(a, /^imm16/)) {
			out = out "AIMM16"
		} else if (match(a, /^imm32/)) {
			out = out "AIMM32"
		} else if (match(a, /^imm64/)) {
			out = out "AIMM64"
		} else if (match(a, /^imm3/)) {
			out = out "AIMM3"
		} else if (match(a, /^rst/)) {
			out = out "ARST"
		} else if (match(a, /^\(IY\+n\)/)) {
			out = out "AINDEX_IY"
		} else if (match(a, /^\(IX\+n\)/)) {
			out = out "AINDEX_IX"
		} else if (match(a, /^ss/)) {
			out = out "AREG_SSCLASS"
		} else if (match(a, /^cc/)) {
			out = out "AREG_CCCLASS"
		} else if (match(a, /^dd/)) {
			out = out "AREG_DDCLASS"
		} else if (match(a, /^qq/)) {
			out = out "AREG_QQCLASS"
		} else if (match(a, /^rr/)) {
			out = out "AREG_RRCLASS"
		} else if (match(a, /^pp/)) {
			out = out "AREG_PPCLASS"
		} else if (match(a, /^p/)) {
			out = out "AREG_PCLASS"
		} else if (match(a, /^q/)) {
			out = out "AREG_QCLASS"
		} else if (match(a, /^r/)) {
			out = out "AREG_RCLASS"
		} else if (match(a, /^R/)) {
			out = out "AREG_R"
		} else if (match(a, /^\(DE\)/)) {
			out = out "AINDER_DE"
		} else if (match(a, /^\(BC\)/)) {
			out = out "AINDER_BC"
		} else if (match(a, /^\(HL\)/)) {
			out = out "AINDER_HL"
		} else if (match(a, /^\(SP\)/)) {
			out = out "AINDER_SP"
		} else if (match(a, /^\(C\)/)) {
			out = out "AINDER_C"
		} else if (match(a, /^SP/)) {
			out = out "AREG_SP"
		} else if (match(a, /^HL/)) {
			out = out "AREG_HL"
		} else if (match(a, /^DE/)) {
			out = out "AREG_DE"
		} else if (match(a, /^IX/)) {
			out = out "AREG_IX"
		} else if (match(a, /^IY/)) {
			out = out "AREG_IY"
		} else if (match(a, /^AF'/)) {
			out = out "AREG_AF_"
		} else if (match(a, /^AF/)) {
			out = out "AREG_AF"
		} else if (match(a, /^A/)) {
			out = out "AREG_A"
		} else if (match(a, /^F/)) {
			out = out "AREG_F"
		} else if (match(a, /^\(n\)/)) {
			out = out "ADIRECT"
		} else if (match(a, /^I/)) {
			out = out "AREG_I"
		} else if (match(a, /^0/)) {
			out = out "AZERO"
		} else if (match(a, /^sym/)) {
			out = out "ASYM"
		} else if (match(a, /^string/)) {
			out = out "ASTR"
		} else {
			print FILENAME ":" NR ":" $0 ":wrong arg", a > "/dev/stderr"
			exit 1
		}
		a = substr(a, RLENGTH+1)
		if (a ~ /^\+$/) {
			return out "|AREP"
		} else if (a ~ /^\?$/) {
			return out "|AOPT"
		} else if (a != "") {
			print FILENAME ":" NR ":" $0 ":wrong arg", a > "/dev/stderr"
			exit 1
		}
		out = out ","
	}
	out = out "0"

	return out
}

BEGIN		{
		FS = "\t"
		printf "#include \"../../../inc/scc.h\"\n"\
		       "#include \"../../as.h\"\n"\
		       "#include \"../" family "/proc.h\"\n"
		nop = 0; nvar = 0
}
		{sub(/#.*/,"")}

$6 !~ cpu	{next}

/^$/		{next}

		{
		if (opstart[$1] == 0) {
			opstart[$1] = nvar
			opnames[nop++] = $1
		}
		opcount[$1]++
		opargs[nvar] = $2
		opsize[nvar] = $3
		opbytes[nvar] = ($4 == "none") ? "" : $4
		opformat[nvar++] = $5
		formats[$5] = 1
}
END		{
		for (i in formats)
			printf "Format %s;\n", i

		printf "int nr_ins = %d;\n\n", nop
		print "struct ins instab[] = {"
		for (i = 0; i < nop; i++) {
			n = opnames[i]
			start = opstart[n]
			end = start + opcount[n]
			printf "\t{.str = \"%s\", .begin = %d, .end = %d},\n",
			       n, start, end | "sort"
		}
		close("sort")
		printf "};\n\n"

		print "struct op optab[] = {"
		for (i = 0; i < nvar; i++) {
			printf "\t{\n" \
			       "\t\t.size = %d,\n"\
			       "\t\t.format = %s,\n",
			       opsize[i], opformat[i]

			if (opbytes[i] != "")
				printf "\t\t.bytes = (unsigned char []) {%s},\n",
				        opbytes[i]

			a = str2args(opargs[i])
			if (a != "")
				printf "\t\t.args = (unsigned char []) {%s}\n", a

			print "\t},"
		}
		print "};"
}

function str2args(s, args, i, out, n)
{
	n = split(s, args, /,/)
	if (n == 0 || args[1] == "none")
		return ""
	for (i = 1; i <= n; i++) {
		a = args[i]
		if (match(a, /^imm8/)) {
			out = out "AIMM8"
		} else if (match(a, /^imm16/)) {
			out = out "AIMM16"
		} else if (match(a, /^imm32/)) {
			out = out "AIMM32"
		} else if (match(a, /^imm64/)) {
			out = out "AIMM64"
		} else if (match(a, /^imm3/)) {
			out = out "AIMM3"
		} else if (match(a, /^rst/)) {
			out = out "ARST"
		} else if (match(a, /^\(IY\+n\)/)) {
			out = out "AINDEX_IY"
		} else if (match(a, /^\(IX\+n\)/)) {
			out = out "AINDEX_IX"
		} else if (match(a, /^ss/)) {
			out = out "AREG_SSCLASS"
		} else if (match(a, /^cc/)) {
			out = out "AREG_CCCLASS"
		} else if (match(a, /^dd/)) {
			out = out "AREG_DDCLASS"
		} else if (match(a, /^qq/)) {
			out = out "AREG_QQCLASS"
		} else if (match(a, /^rr/)) {
			out = out "AREG_RRCLASS"
		} else if (match(a, /^pp/)) {
			out = out "AREG_PPCLASS"
		} else if (match(a, /^p/)) {
			out = out "AREG_PCLASS"
		} else if (match(a, /^q/)) {
			out = out "AREG_QCLASS"
		} else if (match(a, /^r/)) {
			out = out "AREG_RCLASS"
		} else if (match(a, /^R/)) {
			out = out "AREG_R"
		} else if (match(a, /^\(DE\)/)) {
			out = out "AINDER_DE"
		} else if (match(a, /^\(BC\)/)) {
			out = out "AINDER_BC"
		} else if (match(a, /^\(HL\)/)) {
			out = out "AINDER_HL"
		} else if (match(a, /^\(SP\)/)) {
			out = out "AINDER_SP"
		} else if (match(a, /^\(C\)/)) {
			out = out "AINDER_C"
		} else if (match(a, /^SP/)) {
			out = out "AREG_SP"
		} else if (match(a, /^HL/)) {
			out = out "AREG_HL"
		} else if (match(a, /^DE/)) {
			out = out "AREG_DE"
		} else if (match(a, /^IX/)) {
			out = out "AREG_IX"
		} else if (match(a, /^IY/)) {
			out = out "AREG_IY"
		} else if (match(a, /^AF'/)) {
			out = out "AREG_AF_"
		} else if (match(a, /^AF/)) {
			out = out "AREG_AF"
		} else if (match(a, /^A/)) {
			out = out "AREG_A"
		} else if (match(a, /^F/)) {
			out = out "AREG_F"
		} else if (match(a, /^\(n\)/)) {
			out = out "ADIRECT"
		} else if (match(a, /^I/)) {
			out = out "AREG_I"
		} else if (match(a, /^0/)) {
			out = out "AZERO"
		} else if (match(a, /^sym/)) {
			out = out "ASYM"
		} else if (match(a, /^string/)) {
			out = out "ASTR"
		} else {
			print FILENAME ":" NR ":" $0 ":wrong arg", a > "/dev/stderr"
			exit 1
		}
		a = substr(a, RLENGTH+1)
		if (a ~ /^\+$/) {
			return out "|AREP"
		} else if (a ~ /^\?$/) {
			return out "|AOPT"
		} else if (a != "") {
			print "wrong arg", a > "/dev/stderr"
			exit 1
		}
		out = out ","
	}
	out = out "0"

	return out
}


SHADOW_LIST was getting converted to SHADOWLIST by the awk script that converts configs to win32.

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
##
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
##
##    http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************

##
## convert_config_to_win32.awk
##
## Todd Tannenbaum <tannenba@cs.wisc.edu>, 10/06
## John Knoeller <johnkn@cs.wisc.edu>, 12/10
##

# This is an awk script to modify condor_config.generic into a form that
# works with Windows.
# Pipe condor_config.generic through this awk script and save it as
# condor_config.win, which is what the Installer expects to modify after unbundling.

BEGIN {
	FS = "="
}

# Make it so we can fill in the VM_GAHP_SERVER option if we choose to in the
# installer. This is done before the .exe append bellow, because that match
# seems to block any other matches for that line.
/^#VM_GAHP_SERVER/ {
	print "#VM_GAHP_SERVER = $(BIN)/condor_vm-gahp.exe"
	print "VM_GAHP_SERVER = "
	next
}

# Add a .exe to the end of all condor daemon names in $(BIN) and $(SBIN)
/BIN)\/condor_/ {
	printf "%s.exe\n",$0
	next
}

# Add a .exe to the end of all condor daemon names in $(LIBEXEC)
/LIBEXEC)\/condor_/ {
	printf "%s.exe\n",$0
	next
}

# Email Settings
# Use condor_mail.exe for MAIL, and put in a stub for SMTP_SERVER
/^MAIL/ {
	printf "MAIL = $(BIN)/condor_mail.exe\n\n"
	printf "## For Condor on Win32 we need to specify an SMTP server so\n"
	printf "## that Condor is able to send email.\n"
	printf "SMTP_SERVER =\n\n"
	printf "## For Condor on Win32 we may need to specify a \"from\"\n"
	printf "## address so that a valid address is used in the from\n"
	printf "## field.\n"
	printf "MAIL_FROM =\n\n"
	next
}
/^SMTP_SERVER/ {
	next
}

# Remove SHADOW_STANDARD (the standard universe shadow)
#
/^SHADOW_STANDARD/ {
	next
}
/^SHADOW_LIST/ {
    printf "SHADOW_LIST = SHADOW\n"
    next
}

# Choose a Windows-reasonable value for RELEASE_DIR and LOCAL_DIR
#
/^RELEASE_DIR[ \t]*=/ {
	printf "RELEASE_DIR = C:\\Condor\n"
	next
}
/^LOCAL_DIR[ \t]*=/ {
    printf "LOCAL_DIR = $(RELEASE_DIR)\n"
    next
}

# Don't require a local config file.
#
/^\#REQUIRE_LOCAL_CONFIG_FILE \=/ {
   printf "REQUIRE_LOCAL_CONFIG_FILE = FALSE\n"
   next
}

# Specify $(FULL_HOSTNAME) as the sample commented-out entry for
# FILESYSTEM_DOMAIN and UID_DOMAIN, as this is what the installer expects.
/^UID_DOMAIN/ || /^FILESYSTEM_DOMAIN/ {
	printf "#%s= $(FULL_HOSTNAME)\n", $1
	next
}

# Have $(SBIN) point to $(BIN)
/^SBIN/ {
	printf "%s= $(BIN)\n", $1
	next
}

# Have $(LIBEXEC) point to $(BIN)
/^LIBEXEC/ {
	printf "%s= $(BIN)\n", $1
	next
}

# QUEUE_SUPER_USERS should be condor and SYSTEM, not root! :)
/^QUEUE_SUPER_USERS/ {
	printf "%s= condor, SYSTEM\n", $1
	next
}

# JOB_RENICE_INCREMENT must be 10 or load average will be messed up
# Be careful, it may be commented out in condor_config.generic.
/^.*JOB_RENICE_INCREMENT/ {
	printf "JOB_RENICE_INCREMENT = 10\n"
	next
}

# Clean out the initial guess of /usr/bin/java for JAVA... ;)
# Note the space after JAVA below, so we do not change other JAVA settings.
/^JAVA / {
	printf "JAVA =\n"
	next
}

# Win32 has a path separator of ';', while on Unix it is ':'
/^JAVA_CLASSPATH_SEPARATOR/ {
	printf "%s= ;\n", $1
	next
}

# There's no reasonable default place to put log files for
# daemons that run as a user (on Unix we use /tmp). Use NUL.
/(^C_GAHP_LOG)|(^C_GAHP_LOCK)|(^C_GAHP_WORKER_THREAD_LOG)|(^C_GAHP_WORKER_THREAD_LOCK)|(^VM_GAHP_LOG)/ {
	printf "%s = NUL\n", $1
	next
}

# PROCD_ADDRESS needs to refer to a valid name for a Windows named
# pipe
/^PROCD_ADDRESS/ {
	print "PROCD_ADDRESS = \\\\.\\pipe\\condor_procd_pipe"
	next
}

# Make it so we can fill in the VM GAHP options if we choose
# to in the installer.
/^#VM_TYPE/ {
	print "VM_TYPE ="
	next
}
/^#VM_MAX_NUMBER/ {
	print "VM_MAX_NUMBER = $(NUM_CPUS)"
	next
}
/^#VM_MEMORY/ {
	print "VM_MEMORY = 128"
	next
}
/^#VMWARE_LOCAL_SETTINGS_FILE/ {
	print "VMWARE_LOCAL_SETTINGS_FILE = $(RELEASE_DIR)/condor_vmware_local_settings"
	next
}

# Set it up so we can change the VMWARE_SCRIPT option if we choose to
# do so in the installer
#/^VMWARE_SCRIPT/ {
#	printf "VMWARE_SCRIPT = $(BIN)/condor_vm_vmware.pl\n"
#	next
#}

# Change the configuration such that we can modify the VMware
# networking types
/^#VM_NETWORKING_TYPE/ {
	print "VM_NETWORKING_TYPE = nat"
	next
}
/^#VM_NETWORKING_DEFAULT_TYPE/ {
	print "VM_NETWORKING_DEFAULT_TYPE = nat"
	next
}

# We use the equals sign so that it will not match the names above
# and trash the resulting configuration file
/^#VM_NETWORKING =/ {
	print "VM_NETWORKING = FALSE"
	next
}
/^#VMWARE_NAT_NETWORKING_TYPE/ {
	printf "VMWARE_NAT_NETWORKING_TYPE = nat\n"
	next
}
/^#VMWARE_BRIDGE_NETWORKING_TYPE/ {
	printf "VMWARE_BRIDGE_NETWORKING_TYPE = bridged\n"
	next
}

# If we made it here, print out the line unchanged
{print $0}

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
##
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
##
##    http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************

##
## convert_config_to_win32.awk
##
## Todd Tannenbaum <tannenba@cs.wisc.edu>, 10/06
## John Knoeller <johnkn@cs.wisc.edu>, 12/10
##

# This is an awk script to modify condor_config.generic into a form that
# works with Windows.
# Pipe condor_config.generic through this awk script and save it as
# condor_config.win, which is what the Installer expects to modify after unbundling.

BEGIN {
	FS = "="
}

# Make it so we can fill in the VM_GAHP_SERVER option if we choose to in the
# installer. This is done before the .exe append bellow, because that match
# seems to block any other matches for that line.
/^#VM_GAHP_SERVER/ {
	print "#VM_GAHP_SERVER = $(BIN)/condor_vm-gahp.exe"
	print "VM_GAHP_SERVER = "
	next
}

# Add a .exe to the end of all condor daemon names in $(BIN) and $(SBIN)
/BIN)\/condor_/ {
	printf "%s.exe\n",$0
	next
}

# Add a .exe to the end of all condor daemon names in $(LIBEXEC)
/LIBEXEC)\/condor_/ {
	printf "%s.exe\n",$0
	next
}

# Email Settings
# Use condor_mail.exe for MAIL, and put in a stub for SMTP_SERVER
/^MAIL/ {
	printf "MAIL = $(BIN)/condor_mail.exe\n\n"
	printf "## For Condor on Win32 we need to specify an SMTP server so\n"
	printf "## that Condor is able to send email.\n"
	printf "SMTP_SERVER =\n\n"
	printf "## For Condor on Win32 we may need to specify a \"from\"\n"
	printf "## address so that a valid address is used in the from\n"
	printf "## field.\n"
	printf "MAIL_FROM =\n\n"
	next
}
/^SMTP_SERVER/ {
	next
}

# Remove SHADOW_STANDARD (the standard universe shadow)
#
/^SHADOW_STANDARD/ {
	next
}
/^SHADOW_LIST/ {
    printf "SHADOWLIST = SHADOW\n"
    next
}

# Choose a Windows-reasonable value for RELEASE_DIR and LOCAL_DIR
#
/^RELEASE_DIR[ \t]*=/ {
	printf "RELEASE_DIR = C:\\Condor\n"
	next
}
/^LOCAL_DIR[ \t]*=/ {
    printf "LOCAL_DIR = $(RELEASE_DIR)\n"
    next
}

# Don't require a local config file.
#
/^\#REQUIRE_LOCAL_CONFIG_FILE \=/ {
   printf "REQUIRE_LOCAL_CONFIG_FILE = FALSE\n"
   next
}

# Specify $(FULL_HOSTNAME) as the sample commented-out entry for
# FILESYSTEM_DOMAIN and UID_DOMAIN, as this is what the installer expects.
/^UID_DOMAIN/ || /^FILESYSTEM_DOMAIN/ {
	printf "#%s= $(FULL_HOSTNAME)\n", $1
	next
}

# Have $(SBIN) point to $(BIN)
/^SBIN/ {
	printf "%s= $(BIN)\n", $1
	next
}

# Have $(LIBEXEC) point to $(BIN)
/^LIBEXEC/ {
	printf "%s= $(BIN)\n", $1
	next
}

# QUEUE_SUPER_USERS should be condor and SYSTEM, not root! :)
/^QUEUE_SUPER_USERS/ {
	printf "%s= condor, SYSTEM\n", $1
	next
}

# JOB_RENICE_INCREMENT must be 10 or load average will be messed up
# Be careful, it may be commented out in condor_config.generic.
/^.*JOB_RENICE_INCREMENT/ {
	printf "JOB_RENICE_INCREMENT = 10\n"
	next
}

# Clean out the initial guess of /usr/bin/java for JAVA... ;)
# Note the space after JAVA below, so we do not change other JAVA settings.
/^JAVA / {
	printf "JAVA =\n"
	next
}

# Win32 has a path separator of ';', while on Unix it is ':'
/^JAVA_CLASSPATH_SEPARATOR/ {
	printf "%s= ;\n", $1
	next
}

# There's no reasonable default place to put log files for
# daemons that run as a user (on Unix we use /tmp). Use NUL.
/(^C_GAHP_LOG)|(^C_GAHP_LOCK)|(^C_GAHP_WORKER_THREAD_LOG)|(^C_GAHP_WORKER_THREAD_LOCK)|(^VM_GAHP_LOG)/ {
	printf "%s = NUL\n", $1
	next
}

# PROCD_ADDRESS needs to refer to a valid name for a Windows named
# pipe
/^PROCD_ADDRESS/ {
	print "PROCD_ADDRESS = \\\\.\\pipe\\condor_procd_pipe"
	next
}

# Make it so we can fill in the VM GAHP options if we choose
# to in the installer.
/^#VM_TYPE/ {
	print "VM_TYPE ="
	next
}
/^#VM_MAX_NUMBER/ {
	print "VM_MAX_NUMBER = $(NUM_CPUS)"
	next
}
/^#VM_MEMORY/ {
	print "VM_MEMORY = 128"
	next
}
/^#VMWARE_LOCAL_SETTINGS_FILE/ {
	print "VMWARE_LOCAL_SETTINGS_FILE = $(RELEASE_DIR)/condor_vmware_local_settings"
	next
}

# Set it up so we can change the VMWARE_SCRIPT option if we choose to
# do so in the installer
#/^VMWARE_SCRIPT/ {
#	printf "VMWARE_SCRIPT = $(BIN)/condor_vm_vmware.pl\n"
#	next
#}

# Change the configuration such that we can modify the VMware
# networking types
/^#VM_NETWORKING_TYPE/ {
	print "VM_NETWORKING_TYPE = nat"
	next
}
/^#VM_NETWORKING_DEFAULT_TYPE/ {
	print "VM_NETWORKING_DEFAULT_TYPE = nat"
	next
}

# We use the equals sign so that it will not match the names above
# and trash the resulting configuration file
/^#VM_NETWORKING =/ {
	print "VM_NETWORKING = FALSE"
	next
}
/^#VMWARE_NAT_NETWORKING_TYPE/ {
	printf "VMWARE_NAT_NETWORKING_TYPE = nat\n"
	next
}
/^#VMWARE_BRIDGE_NETWORKING_TYPE/ {
	printf "VMWARE_BRIDGE_NETWORKING_TYPE = bridged\n"
	next
}

# If we made it here, print out the line unchanged
{print $0}


MTEXT entities added

MTEXT entities added

BEGIN {
	print "EAST;NORTH;LAYER;DIRECTION;SIZE;TEXT";	# print header
	rad2deg = 180.0 / atan2(1.0, 1.0) / 4;
}
/^ENTITIES/,/^EOF/ {
	if ($0 == "  0") {					# next entity reached
		if (entity == "MTEXT") {		# calculate angle from dx, dy
			angle = atan2(dy, dx) * rad2deg;	# angle in deg
		}
		if (entity == "TEXT" || entity == "MTEXT") {	# output text data
			printf("%.2f;%.2f;%s;%.5f;%.2f;%s\n", x, y, layer, angle, size, txt);
		}
		entity = ""; txt = ""; angle = 0; size = 1; layer = "";
		dx = dy = 0.0;
		last = "";						# initialize variables
	}
	if (last == "  0") { entity = $0; }	# actual entity type
	if (last == "  8") { layer = $0; }	# layer
	if (last == " 10") { x = $0; }		# east
	if (last == " 20") { y = $0; }		# north
	if (last == " 11") { dx = $0; }		# direction for MTEXT
	if (last == " 21") { dy = $0; }		# direction for MTEXT
	if (last == " 40") { size = $0; }	# text size
	if (last == " 50") { angle = $0; }	# text direction
	if (last == "  1") { txt = $0; }	# text
	last = $0;							# last input line
}

BEGIN {
	print "EAST;NORTH;LAYER;DIRECTION;SIZE;TEXT";	# print header
}
/^ENTITIES/,/^EOF/ {
	if ($0 == "  0") {					# next entity reached
		if (entity == "TEXT") {			# output text data
			printf("%.2f;%.2f;%s;%.5f;%.2f;%s\n", x, y, layer, angle, size, txt);
		}
		entity = ""; txt = ""; angle = 0; size = 1; layer = "";
		last = "";						# initialize variables
	}
	if (last == "  0") { entity = $0; }	# actual entity type
	if (last == "  8") { layer = $0; }	# layer
	if (last == " 10") { x = $0; }		# east
	if (last == " 20") { y = $0; }		# north
	if (last == " 40") { size = $0; }	# text size
	if (last == " 50") { angle = $0; }	# text direction
	if (last == "  1") { txt = $0; }	# text
	last = $0;							# last input line
}