make option -version and -interactive a little more comprehensive

####################################################################
# Main.awk                                                         #
####################################################################

# Detect gawk version.
function initGawk(    group) {
    Gawk = "gawk"
    GawkVersion = PROCINFO["version"]

    split(PROCINFO["version"], group, ".")
    if (group[1] < 4) {
        e("[ERROR] Oops! Your gawk (version " GawkVersion ") appears to be too old.\nYou need at least gawk 4.0.0 to run this program.")
        exit 1
    }
}

# Pre-initialization (before option parsing).
function preInit() {
    initGawk()          #<< AnsiCode

    # Languages
    initBiDi()
    initLocale()
    initLocaleDisplay() #<< Locale, BiDi
    initUserLang()      #<< Locale

    RS = "\n"

    ExitCode = 0

    Option["debug"] = 0

    Option["verbose"] = 1
    if (ENVIRON["COLUMNS"])
        Option["width"] = ENVIRON["COLUMNS"]
    else {
        "tput cols 2>/dev/null" |& getline Option["width"]
        if (!Option["width"]) Option["width"] = 64
    }

    Option["browser"] = ENVIRON["BROWSER"]

    Option["play"] = 0
    Option["player"] = ENVIRON["PLAYER"]

    Option["proxy"] = ENVIRON["HTTP_PROXY"] ? ENVIRON["HTTP_PROXY"] : ENVIRON["http_proxy"]

    Option["interactive"] = 0
    Option["no-rlwrap"] = 0
    Option["emacs"] = 0
    Option["prompt"] = ENVIRON["TRANS_PS"] ? ENVIRON["TRANS_PS"] : "%s>"
    Option["prompt-color"] = ENVIRON["TRANS_PS_COLOR"] ? ENVIRON["TRANS_PS_COLOR"] : "blue"

    Option["input"] = ""
    Option["output"] = "/dev/stdout"

    Option["hl"] = ENVIRON["HOME_LANG"] ? ENVIRON["HOME_LANG"] : UserLang
    Option["sl"] = ENVIRON["SOURCE_LANG"] ? ENVIRON["SOURCE_LANG"] : "auto"
    Option["tl"][1] = ENVIRON["TARGET_LANG"] ? ENVIRON["TARGET_LANG"] : UserLang
}

# Post-initialization (after option parsing).
function postInit() {
    # Translate
    initHttpService()
}

# Main entry point.
BEGIN {
    preInit()

    pos = 0
    while (ARGV[++pos]) {
        # -, -no-op
        match(ARGV[pos], /^-(-?no-op)?$/)
        if (RSTART) continue

        # -V, -version
        match(ARGV[pos], /^--?(vers(i(on?)?)?|V)$/)
        if (RSTART) {
            print getVersion()
            print
            printf("%-22s%s\n", "gawk (GNU Awk)", PROCINFO["version"])
            printf("%s\n", FriBidi ? FriBidi : "fribidi (GNU FriBidi) [NOT INSTALLED]")
            printf("%-22s%s\n", "User Language", Locale[getCode(UserLang)]["name"] " (" show(Locale[getCode(UserLang)]["endonym"]) ")")
            exit
        }

        # -H, -h, -help
        match(ARGV[pos], /^--?(h(e(lp?)?)?|H)$/)
        if (RSTART) {
            if (ENVIRON["TRANS_MANPAGE"])
                system("echo -E \"${TRANS_MANPAGE}\" | " \
                       "groff -Wall -mtty-char -mandoc -Tutf8 -Dutf8 -rLL=${COLUMNS}n -rLT=${COLUMNS}n | " \
                       (system("most 2>/dev/null") ?
                        "less -s -P\"\\ \\Manual page " Command "(1) line %lt (press h for help or q to quit)\"" :
                        "most -Cs"))
            else
                print getHelp()
            exit
        }

        # -r, -reference
        match(ARGV[pos], /^--?r(e(f(e(r(e(n(ce?)?)?)?)?)?)?)?$/)
        if (RSTART) {
            print getReference("endonym")
            exit
        }

        # -R, -reference-english
        match(ARGV[pos], /^--?(reference-(e(n(g(l(i(sh?)?)?)?)?)?)?|R)$/)
        if (RSTART) {
            print getReference("name")
            exit
        }

        # -d, -debug
        match(ARGV[pos], /^--?d(e(b(ug?)?)?)?$/)
        if (RSTART) {
            Option["debug"] = 1
            continue
        }

        # -v, -verbose
        match(ARGV[pos], /^--?v(e(r(b(o(se?)?)?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = 1 # default value
            continue
        }

        # -b, -brief
        match(ARGV[pos], /^--?b(r(i(ef?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = 0
            continue
        }

        # -w [num], -width [num]
        match(ARGV[pos], /^--?w(i(d(th?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["width"] = group[4] ?
                (group[5] ? group[5] : Option["width"]) :
                ARGV[++pos]
            continue
        }

        # -browser [program]
        match(ARGV[pos], /^--?browser(=(.*)?)?$/, group)
        if (RSTART) {
            Option["browser"] = group[1] ?
                (group[2] ? group[2] : Option["browser"]) :
                ARGV[++pos]
            continue
        }

        # -p, -play
        match(ARGV[pos], /^--?p(l(ay?)?)?$/)
        if (RSTART) {
            Option["play"] = 1
            continue
        }

        # -player [program]
        match(ARGV[pos], /^--?player(=(.*)?)?$/, group)
        if (RSTART) {
            Option["play"] = 1
            Option["player"] = group[1] ?
                (group[2] ? group[2] : Option["player"]) :
                ARGV[++pos]
            continue
        }

        # -x [proxy], -proxy [proxy]
        match(ARGV[pos], /^--?(proxy|x)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["proxy"] = group[2] ?
                (group[3] ? group[3] : Option["proxy"]) :
                ARGV[++pos]
            continue
        }

        # -I, -interactive
        match(ARGV[pos], /^--?(int(e(r(a(c(t(i(ve?)?)?)?)?)?)?)?|I)$/)
        if (RSTART) {
            Option["interactive"] = 1
            continue
        }

        # -no-rlwrap
        match(ARGV[pos], /^--?no-rlwrap/)
        if (RSTART) {
            Option["no-rlwrap"] = 1
            continue
        }

        # -E, -emacs
        match(ARGV[pos], /^--?(emacs|E)$/)
        if (RSTART) {
            Option["emacs"] = 1
            continue
        }

        # -prompt [prompt_string]
        match(ARGV[pos], /^--?prompt(=(.*)?)?$/, group)
        if (RSTART) {
            Option["prompt"] = group[1] ?
                (group[2] ? group[2] : Option["prompt"]) :
                ARGV[++pos]
            continue
        }

        # -prompt-color [color_code]
        match(ARGV[pos], /^--?prompt-color(=(.*)?)?$/, group)
        if (RSTART) {
            Option["prompt-color"] = group[1] ?
                (group[2] ? group[2] : Option["prompt-color"]) :
                ARGV[++pos]
            continue
        }

        # -i [file], -input [file]
        match(ARGV[pos], /^--?i(n(p(ut?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["input"] = group[4] ?
                (group[5] ? group[5] : Option["input"]) :
                ARGV[++pos]
            continue
        }

        # -o [file], -output [file]
        match(ARGV[pos], /^--?o(u(t(p(ut?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["output"] = group[5] ?
                (group[6] ? group[6] : Option["output"]) :
                ARGV[++pos]
            continue
        }

        # -l [code], -lang [code]
        match(ARGV[pos], /^--?l(a(ng?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["hl"] = group[3] ?
                (group[4] ? group[4] : Option["hl"]) :
                ARGV[++pos]
            continue
        }

        # -s [code], -source [code]
        match(ARGV[pos], /^--?s(o(u(r(ce?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["sl"] = group[5] ?
                (group[6] ? group[6] : Option["sl"]) :
                ARGV[++pos]
            continue
        }

        # -t [codes], -target [codes]
        match(ARGV[pos], /^--?t(a(r(g(et?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            if (group[5]) {
                if (group[6]) split(group[6], Option["tl"], "+")
            } else
                split(ARGV[++pos], Option["tl"], "+")
            continue
        }

        # Shortcut format
        # '[code]:[code]+...' or '[code]=[code]+...'
        match(ARGV[pos], /^[{([]?([[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?(:|=)((@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?\+)*(@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?)[})\]]?$/, group)
        if (RSTART) {
            if (group[1]) Option["sl"] = group[1]
            if (group[4]) split(group[4], Option["tl"], "+")
            continue
        }

        # --
        match(ARGV[pos], /^--$/)
        if (RSTART) {
            ++pos # skip the end-of-options option
            break # no more option from here
        }

        break # no more option from here
    }

    # Option parsing finished
    postInit()

    if (Option["interactive"] && !Option["no-rlwrap"]) {
        # Interactive mode
        initRlwrap() # initialize Rlwrap

        if (Rlwrap && (ENVIRON["TRANS_PROGRAM"] || fileExists(EntryPoint))) {
            command = Rlwrap " " Gawk " " (ENVIRON["TRANS_PROGRAM"] ?
                                           "\"${TRANS_PROGRAM}\"" :
                                           "-f " EntryPoint) " -" \
                " -no-rlwrap" # be careful - never fork Rlwrap recursively!
            for (i = 1; i < length(ARGV); i++)
                if (ARGV[i])
                    command = command " " parameterize(ARGV[i])

            if (!system(command))
                exit # child process finished, exit
            else
                ; # skip
        } else
            ; # skip

    } else if (!Option["interactive"] && !Option["no-rlwrap"] && Option["emacs"]) {
        # Emacs interface
        Emacs = "emacs"

        if (ENVIRON["TRANS_PROGRAM"] || fileExists(EntryPoint)) {
            params = ""
            for (i = 1; i < length(ARGV); i++)
                if (ARGV[i])
                    params = params " " (parameterize(ARGV[i], "\""))
            if (ENVIRON["TRANS_PROGRAM"]) {
                el = "(progn (setq trans-program (getenv \"TRANS_PROGRAM\")) " \
                    "(setq explicit-shell-file-name \"" Gawk "\") " \
                    "(setq explicit-" Gawk "-args (cons trans-program '(\"-\" \"-I\" \"-no-rlwrap\"" params "))) " \
                    "(command-execute 'shell) (rename-buffer \"" Name "\"))"
            } else {
                el = "(progn (setq explicit-shell-file-name \"" Gawk "\") " \
                    "(setq explicit-" Gawk "-args '(\"-f\" \"" EntryPoint "\" \"--\" \"-I\" \"-no-rlwrap\"" params ")) " \
                    "(command-execute 'shell) (rename-buffer \"" Name "\"))"
            }
            command = Emacs " --eval " parameterize(el)

            if (!system(command))
                exit # child process finished, exit
            else
                Option["interactive"] = 1 # skip
        } else
            Option["interactive"] = 1 # skip
    }

    if (Option["play"]) {
        # Initialize audio player or speech synthesizer
        if (!Option["player"]) {
            initAudioPlayer()
            Option["player"] = AudioPlayer ? AudioPlayer : Option["player"]
            if (!Option["player"])
                initSpeechSynthesizer()
        }

        if (!Option["player"] && !SpeechSynthesizer) {
            w("[WARNING] No available audio player or speech synthesizer is found.")
            Option["play"] = 0
        }
    }

    if (Option["interactive"])
        print AnsiCode["bold"] AnsiCode[tolower(Option["prompt-color"])] getVersion() AnsiCode[0] > "/dev/stderr"

    # Initialize browser
    if (!Option["browser"]) {
        "xdg-mime query default text/html 2>/dev/null" |& getline Option["browser"]
        match(Option["browser"], "(.*).desktop$", group)
        Option["browser"] = group[1]
    }

    if (pos < ARGC) {
        # More parameters

        # Translate the remaining parameters
        for (i = pos; i < ARGC; i++) {
            # Verbose mode: separator between sources
            if (Option["verbose"] && i > pos)
                print replicate("═", Option["width"])

            translate(ARGV[i], 1) # inline mode
        }

        # If input not specified, we're done
    } else {
        # No more parameter besides options

        # If input not specified, use stdin
        if (!Option["input"]) Option["input"] = "/dev/stdin"
    }

    # If input specified, start translating
    if (Option["input"])
        translateMain()

    exit ExitCode
}

####################################################################
# Main.awk                                                         #
####################################################################

# Detect gawk version.
function initGawk(    group) {
    Gawk = "gawk"
    GawkVersion = PROCINFO["version"]

    split(PROCINFO["version"], group, ".")
    if (group[1] < 4) {
        e("[ERROR] Oops! Your gawk (version " GawkVersion ") appears to be too old.\nYou need at least gawk 4.0.0 to run this program.")
        exit 1
    }
}

# Pre-initialization (before option parsing).
function preInit() {
    initGawk()          #<< AnsiCode

    # Languages
    initBiDi()
    initLocale()
    initLocaleDisplay() #<< Locale, BiDi
    initUserLang()      #<< Locale

    RS = "\n"

    ExitCode = 0

    Option["debug"] = 0

    Option["verbose"] = 1
    if (ENVIRON["COLUMNS"])
        Option["width"] = ENVIRON["COLUMNS"]
    else {
        "tput cols 2>/dev/null" |& getline Option["width"]
        if (!Option["width"]) Option["width"] = 64
    }

    Option["browser"] = ENVIRON["BROWSER"]

    Option["play"] = 0
    Option["player"] = ENVIRON["PLAYER"]

    Option["proxy"] = ENVIRON["HTTP_PROXY"] ? ENVIRON["HTTP_PROXY"] : ENVIRON["http_proxy"]

    Option["interactive"] = 0
    Option["no-rlwrap"] = 0
    Option["emacs"] = 0
    Option["prompt"] = ENVIRON["TRANS_PS"] ? ENVIRON["TRANS_PS"] : "%s>"
    Option["prompt-color"] = ENVIRON["TRANS_PS_COLOR"] ? ENVIRON["TRANS_PS_COLOR"] : "blue"

    Option["input"] = ""
    Option["output"] = "/dev/stdout"

    Option["hl"] = ENVIRON["HOME_LANG"] ? ENVIRON["HOME_LANG"] : UserLang
    Option["sl"] = ENVIRON["SOURCE_LANG"] ? ENVIRON["SOURCE_LANG"] : "auto"
    Option["tl"][1] = ENVIRON["TARGET_LANG"] ? ENVIRON["TARGET_LANG"] : UserLang
}

# Post-initialization (after option parsing).
function postInit() {
    # Translate
    initHttpService()
}

# Main entry point.
BEGIN {
    preInit()

    pos = 0
    while (ARGV[++pos]) {
        # -, -no-op
        match(ARGV[pos], /^-(-?no-op)?$/)
        if (RSTART) continue

        # -V, -version
        match(ARGV[pos], /^--?(vers(i(on?)?)?|V)$/)
        if (RSTART) {
            print getVersion()
            exit
        }

        # -H, -h, -help
        match(ARGV[pos], /^--?(h(e(lp?)?)?|H)$/)
        if (RSTART) {
            if (ENVIRON["TRANS_MANPAGE"])
                system("echo -E \"${TRANS_MANPAGE}\" | " \
                       "groff -Wall -mtty-char -mandoc -Tutf8 -Dutf8 -rLL=${COLUMNS}n -rLT=${COLUMNS}n | " \
                       (system("most 2>/dev/null") ?
                        "less -s -P\"\\ \\Manual page " Command "(1) line %lt (press h for help or q to quit)\"" :
                        "most -Cs"))
            else
                print getHelp()
            exit
        }

        # -r, -reference
        match(ARGV[pos], /^--?r(e(f(e(r(e(n(ce?)?)?)?)?)?)?)?$/)
        if (RSTART) {
            print getReference("endonym")
            exit
        }

        # -R, -reference-english
        match(ARGV[pos], /^--?(reference-(e(n(g(l(i(sh?)?)?)?)?)?)?|R)$/)
        if (RSTART) {
            print getReference("name")
            exit
        }

        # -d, -debug
        match(ARGV[pos], /^--?d(e(b(ug?)?)?)?$/)
        if (RSTART) {
            Option["debug"] = 1
            continue
        }

        # -v, -verbose
        match(ARGV[pos], /^--?v(e(r(b(o(se?)?)?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = 1 # default value
            continue
        }

        # -b, -brief
        match(ARGV[pos], /^--?b(r(i(ef?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = 0
            continue
        }

        # -w [num], -width [num]
        match(ARGV[pos], /^--?w(i(d(th?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["width"] = group[4] ?
                (group[5] ? group[5] : Option["width"]) :
                ARGV[++pos]
            continue
        }

        # -browser [program]
        match(ARGV[pos], /^--?browser(=(.*)?)?$/, group)
        if (RSTART) {
            Option["browser"] = group[1] ?
                (group[2] ? group[2] : Option["browser"]) :
                ARGV[++pos]
            continue
        }

        # -p, -play
        match(ARGV[pos], /^--?p(l(ay?)?)?$/)
        if (RSTART) {
            Option["play"] = 1
            continue
        }

        # -player [program]
        match(ARGV[pos], /^--?player(=(.*)?)?$/, group)
        if (RSTART) {
            Option["play"] = 1
            Option["player"] = group[1] ?
                (group[2] ? group[2] : Option["player"]) :
                ARGV[++pos]
            continue
        }

        # -x [proxy], -proxy [proxy]
        match(ARGV[pos], /^--?(proxy|x)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["proxy"] = group[2] ?
                (group[3] ? group[3] : Option["proxy"]) :
                ARGV[++pos]
            continue
        }

        # -I, -interactive
        match(ARGV[pos], /^--?(int(e(r(a(c(t(i(ve?)?)?)?)?)?)?)?|I)$/)
        if (RSTART) {
            Option["interactive"] = 1
            continue
        }

        # -no-rlwrap
        match(ARGV[pos], /^--?no-rlwrap/)
        if (RSTART) {
            Option["no-rlwrap"] = 1
            continue
        }

        # -E, -emacs
        match(ARGV[pos], /^--?(emacs|E)$/)
        if (RSTART) {
            Option["emacs"] = 1
            continue
        }

        # -prompt [prompt_string]
        match(ARGV[pos], /^--?prompt(=(.*)?)?$/, group)
        if (RSTART) {
            Option["prompt"] = group[1] ?
                (group[2] ? group[2] : Option["prompt"]) :
                ARGV[++pos]
            continue
        }

        # -prompt-color [color_code]
        match(ARGV[pos], /^--?prompt-color(=(.*)?)?$/, group)
        if (RSTART) {
            Option["prompt-color"] = group[1] ?
                (group[2] ? group[2] : Option["prompt-color"]) :
                ARGV[++pos]
            continue
        }

        # -i [file], -input [file]
        match(ARGV[pos], /^--?i(n(p(ut?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["input"] = group[4] ?
                (group[5] ? group[5] : Option["input"]) :
                ARGV[++pos]
            continue
        }

        # -o [file], -output [file]
        match(ARGV[pos], /^--?o(u(t(p(ut?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["output"] = group[5] ?
                (group[6] ? group[6] : Option["output"]) :
                ARGV[++pos]
            continue
        }

        # -l [code], -lang [code]
        match(ARGV[pos], /^--?l(a(ng?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["hl"] = group[3] ?
                (group[4] ? group[4] : Option["hl"]) :
                ARGV[++pos]
            continue
        }

        # -s [code], -source [code]
        match(ARGV[pos], /^--?s(o(u(r(ce?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["sl"] = group[5] ?
                (group[6] ? group[6] : Option["sl"]) :
                ARGV[++pos]
            continue
        }

        # -t [codes], -target [codes]
        match(ARGV[pos], /^--?t(a(r(g(et?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            if (group[5]) {
                if (group[6]) split(group[6], Option["tl"], "+")
            } else
                split(ARGV[++pos], Option["tl"], "+")
            continue
        }

        # Shortcut format
        # '[code]:[code]+...' or '[code]=[code]+...'
        match(ARGV[pos], /^[{([]?([[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?(:|=)((@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?\+)*(@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?)[})\]]?$/, group)
        if (RSTART) {
            if (group[1]) Option["sl"] = group[1]
            if (group[4]) split(group[4], Option["tl"], "+")
            continue
        }

        # --
        match(ARGV[pos], /^--$/)
        if (RSTART) {
            ++pos # skip the end-of-options option
            break # no more option from here
        }

        break # no more option from here
    }

    # Option parsing finished
    postInit()

    if (Option["interactive"] && !Option["no-rlwrap"]) {
        # Interactive mode
        initRlwrap() # initialize Rlwrap

        if (Rlwrap && (ENVIRON["TRANS_PROGRAM"] || fileExists(EntryPoint))) {
            command = Rlwrap " " Gawk " " (ENVIRON["TRANS_PROGRAM"] ?
                                           "\"${TRANS_PROGRAM}\"" :
                                           "-f " EntryPoint) " -" \
                " -no-rlwrap" # be careful - never fork Rlwrap recursively!
            for (i = 1; i < length(ARGV); i++)
                if (ARGV[i])
                    command = command " " parameterize(ARGV[i])

            if (!system(command))
                exit # child process finished, exit
            else
                ; # skip
        } else
            ; # skip

    } else if (!Option["interactive"] && !Option["no-rlwrap"] && Option["emacs"]) {
        # Emacs interface
        Emacs = "emacs"

        if (ENVIRON["TRANS_PROGRAM"] || fileExists(EntryPoint)) {
            params = ""
            for (i = 1; i < length(ARGV); i++)
                if (ARGV[i])
                    params = params " " (parameterize(ARGV[i], "\""))
            if (ENVIRON["TRANS_PROGRAM"]) {
                el = "(progn (setq trans-program (getenv \"TRANS_PROGRAM\")) " \
                    "(setq explicit-shell-file-name \"" Gawk "\") " \
                    "(setq explicit-" Gawk "-args (cons trans-program '(\"-\" \"-I\" \"-no-rlwrap\"" params "))) " \
                    "(command-execute 'shell) (rename-buffer \"" Name "\"))"
            } else {
                el = "(progn (setq explicit-shell-file-name \"" Gawk "\") " \
                    "(setq explicit-" Gawk "-args '(\"-f\" \"" EntryPoint "\" \"--\" \"-I\" \"-no-rlwrap\"" params ")) " \
                    "(command-execute 'shell) (rename-buffer \"" Name "\"))"
            }
            command = Emacs " --eval " parameterize(el)

            if (!system(command))
                exit # child process finished, exit
            else
                Option["interactive"] = 1 # skip
        } else
            Option["interactive"] = 1 # skip
    }

    if (Option["play"]) {
        # Initialize audio player or speech synthesizer
        if (!Option["player"]) {
            initAudioPlayer()
            Option["player"] = AudioPlayer ? AudioPlayer : Option["player"]
            if (!Option["player"])
                initSpeechSynthesizer()
        }

        if (!Option["player"] && !SpeechSynthesizer) {
            w("[WARNING] No available audio player or speech synthesizer is found.")
            Option["play"] = 0
        }
    }

    # Initialize browser
    if (!Option["browser"]) {
        "xdg-mime query default text/html 2>/dev/null" |& getline Option["browser"]
        match(Option["browser"], "(.*).desktop$", group)
        Option["browser"] = group[1]
    }

    if (pos < ARGC) {
        # More parameters

        # Translate the remaining parameters
        for (i = pos; i < ARGC; i++) {
            # Verbose mode: separator between sources
            if (Option["verbose"] && i > pos)
                print replicate("═", Option["width"])

            translate(ARGV[i], 1) # inline mode
        }

        # If input not specified, we're done
    } else {
        # No more parameter besides options

        # If input not specified, use stdin
        if (!Option["input"]) Option["input"] = "/dev/stdin"
    }

    # If input specified, start translating
    if (Option["input"])
        translateMain()

    exit ExitCode
}


Define BRLAPI_DOT_CHORD. (dm)

Define BRLAPI_DOT_CHORD. (dm)

git-svn-id: 30a5f035a20f1bc647618dbad7eea2a951b61b7c@4388 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-2009 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; either version 2 of the License, or (at your option) any
# later version. Please see the file LICENSE-GPL for details.
#
# Web Page: http://mielke.cc/brltty/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

BEGIN {
  writeHeaderPrologue("BRLAPI_INCLUDED_CONSTANTS", "brlapi.h")
  beginDoxygenFile()
  print "/** \\ingroup brlapi_keycodes"
  print " * @{ */"
  print ""
}

END {
  writeBrlapiDots()
  print "/** @} */"
  print ""
  writeHeaderEpilogue()
}

function brlCommand(name, symbol, value, help) {
  writeMacroDefinition("BRLAPI_KEY_CMD_" name, "(BRLAPI_KEY_CMD(0) + " 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$/) {
    writeMacroDefinition("BRLAPI_KEY_CMD_" name, "BRLAPI_KEY_CMD(" substr(value, 1, length(value)-2) ")", help)
  }
}

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

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

function brlDot(number, symbol, value, help) {
  writeMacroDefinition("BRLAPI_DOT" number, value, help)
}

function writeBrlapiDots() {
  print ""
  print "/** Helper macro to easily produce braille patterns */"

  arguments = ""
  argumentDelimiter = ""
  expression = ""
  subexpressionDelimiter = ""

  for (dotNumber=1; dotNumber<=8; ++dotNumber) {
    argumentName = "dot" dotNumber

    arguments = arguments argumentDelimiter argumentName
    argumentDelimiter = ", "

    subexpression = "((" argumentName ")? BRLAPI_DOT" dotNumber ": 0)"
    expression = expression subexpressionDelimiter "  " subexpression
    subexpressionDelimiter = " | \\\n"
  }

  print "#define BRLAPI_DOTS(" arguments ") (\\\n" expression " \\\n)"

  print ""
  writeMacroDefinition("BRLAPI_DOT_CHORD", 0X100, "space key")
}

###############################################################################
# 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-2009 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; either version 2 of the License, or (at your option) any
# later version. Please see the file LICENSE-GPL for details.
#
# Web Page: http://mielke.cc/brltty/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

BEGIN {
  writeHeaderPrologue("BRLAPI_INCLUDED_CONSTANTS", "brlapi.h")
  beginDoxygenFile()
  print "/** \\ingroup brlapi_keycodes"
  print " * @{ */"
  print ""
}

END {
  writeBrlapiDots()
  print "/** @} */"
  print ""
  writeHeaderEpilogue()
}

function brlCommand(name, symbol, value, help) {
  writeMacroDefinition("BRLAPI_KEY_CMD_" name, "(BRLAPI_KEY_CMD(0) + " 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$/) {
    writeMacroDefinition("BRLAPI_KEY_CMD_" name, "BRLAPI_KEY_CMD(" substr(value, 1, length(value)-2) ")", help)
  }
}

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

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

function brlDot(number, symbol, value, help) {
  writeMacroDefinition("BRLAPI_DOT" number, value, help)
}

function writeBrlapiDots() {
  print ""
  print "/** Helper macro to easily produce braille patterns */"

  arguments = ""
  argumentDelimiter = ""
  expression = ""
  subexpressionDelimiter = ""

  for (dotNumber=1; dotNumber<=8; ++dotNumber) {
    argumentName = "dot" dotNumber

    arguments = arguments argumentDelimiter argumentName
    argumentDelimiter = ", "

    subexpression = "((" argumentName ")? BRLAPI_DOT" dotNumber ": 0)"
    expression = expression subexpressionDelimiter "  " subexpression
    subexpressionDelimiter = " | \\\n"
  }

  print "#define BRLAPI_DOTS(" arguments ") (\\\n" expression " \\\n)"
}


Created output level constants. Output styles. Variables in function moved to local scope. Improved multi-file support.

git-svn-id: 293778eaa97c8c94097d610b1bd5133a8f478f36@7020 4f837ed2-42f5-46e7-a7a5-fa17313484d4

#!/usr/bin/awk -f

#######
# BEGIN
#######

BEGIN {
 # Boolean
 false = 0;
 true = 1;

 # Format codes
 CODE_ATTRIBUTE      = "@"
 CODE_ESTIMATED_SIZE = "e"
 CODE_JOURNAL_TITLE  = "j"
 CODE_PARAMETER      = "%"
 CODE_PLUGIN         = "p"
 CODE_PUBLISHER      = "P"
 CODE_RIGHTS         = "R"
 CODE_SKIP_1         = "x"
 CODE_SKIP_2         = "X"
 CODE_STATUS         = "S"
 CODE_TITLE          = "t"

 # Archival unit statuses
 STATUS_DOES_NOT_EXIST = "does_not_exist"
 STATUS_DO_NOT_PROCESS = "do_not_process"
 STATUS_DOWN           = "down"
 STATUS_EXISTS         = "exists"
 STATUS_MANIFEST       = "manifest"
 STATUS_PRE_RELEASED   = "pre_released"
 STATUS_READY          = "ready"
 STATUS_RELEASED       = "released"
 STATUS_RETRACTED      = "retracted"
 STATUS_TESTING        = "testing"

 # Output levels and corresponding archival unit statuses
 LEVEL_PRODUCTION              = "production"
 STATUSES_PRODUCTION           = STATUS_RETRACTED "," STATUS_DOWN "," STATUS_RELEASED
 LEVEL_CONTENT_TESTING         = "contentTesting"
 STATUSES_CONTENT_TESTING      = STATUSES_PRODUCTION "," STATUS_PRE_RELEASED "," STATUS_READY "," STATUS_TESTING "," STATUS_MANIFEST "," STATUS_EXISTS
 LEVEL_DANGEROUS               = "dangerous"
 STATUSES_DANGEROUS            = STATUSES_CONTENT_TESTING "," STATUS_DO_NOT_PROCESS
 LEVEL_VERY_DANGEROUS          = "veryDangerous"
 STATUSES_VERY_DANGEROUS       = STATUSES_DANGEROUS "," STATUS_DOES_NOT_EXIST
 LEVEL_PRE_RELEASE             = "preRelease"
 STATUSES_PRE_RELEASE          = STATUS_PRE_RELEASED
 LEVEL_CONSERVATIVE_TESTING    = "conservativeTesting"
 STATUSES_CONSERVATIVE_TESTING = STATUS_RELEASED "," STATUS_PRE_RELEASED "," STATUS_READY "," STATUS_TESTING "," STATUS_MANIFEST
 LEVEL_DEFAULT                 = LEVEL_PRODUCTION

 # Output styles
 STYLE_XML         = "xml"
 STYLE_XML_ENTRIES = "xmlEntries"
 STYLE_XML_LEGACY  = "xmlLegacy"
 STYLE_DEFAULT     = STYLE_XML_ENTRIES

 # Exit codes
 EXIT_NO_FORMAT_STRING = 11

 # Initial setup
 FS="\t"
 parseCommandLine()

 # Preamble
 if (outputStyle == STYLE_XML || outputStyle == STYLE_XML_LEGACY) { preambleXml() }
}

###########
# FUNCTIONS
###########

#
# parseCommandLine
#
function parseCommandLine() {
 # Disallow overrides
 formatString = ""
 namePrefix = ""

 # Defaults
 if (outputStyle == "") { outputStyle = STYLE_DEFAULT }
 if (outputLevel == "") { outputLevel = LEVEL_DEFAULT }

 # Parse
 parseOutputLevel()
}

#
# parseFormatString
#
function parseFormatString(        _splitFormatString, _numFields, _field, _code) {
 # Reset format information
 delete indexOf
 numAdditionalParameters = 0
 delete indexAdditionalAttributes
 numParameters = 0
 delete indexParameters

 # For each format code...
 _numFields = split(formatString, _splitFormatString, ",")
 for (_field = 1 ; _field <= _numFields ; ++_field) {
  _code = _splitFormatString[_field]
  if (_code == CODE_SKIP_1 || _code == CODE_SKIP_2) { continue }
  else if (_code == CODE_ESTIMATED_SIZE || _code == CODE_JOURNAL_TITLE || _code == CODE_PLUGIN || _code == CODE_TITLE || _code == CODE_PUBLISHER || _code == CODE_STATUS || _code == CODE_RIGHTS) { indexOf[_code] = _field }
  else if (_code == CODE_ATTRIBUTE) { indexAdditionalAttributes[++numAdditionalAttributes] = _field }
  else if (_code == CODE_PARAMETER) { indexParameters[++numParameters] = _field }
  # FIXME: unknown code
 }
}

#
# parseOutputLevel
#
function parseOutputLevel(        _splitOutputLevel, _i, _statuses, _splitStatuses, _j) {
 # Reset output level information
 delete outputLevels

 # For each output level...
 split(outputLevel, _splitOutputLevel, ",")
 for (_i in _splitOutputLevel) {
  # Synonyms
  if (_splitOutputLevel[_i] == LEVEL_PRODUCTION) { _statuses = STATUSES_PRODUCTION }
  else if (_splitOutputLevel[_i] == LEVEL_PRE_RELEASE) { _statuses = STATUSES_PRE_RELEASE }
  else if (_splitOutputLevel[_i] == LEVEL_CONTENT_TESTING) { _statuses = STATUSES_CONTENT_TESTING }
  else if (_splitOutputLevel[_i] == LEVEL_CONSERVATIVE_TESTING) { _statuses = STATUSES_CONSERVATIVE_TESTING }
  else if (_splitOutputLevel[_i] == LEVEL_DANGEROUS) { _statuses = STATUSES_DANGEROUS }
  else if (_splitOutputLevel[_i] == LEVEL_VERY_DANGEROUS) { _statuses = STATUSES_VERY_DANGEROUS }
  else { _statuses = _splitOutputLevel[_i] } # Not a synonym
  # For each status...
  split(_statuses, _splitStatuses, ",")
  for (_j in _splitStatuses) { outputLevels[_splitStatuses[_j]] = true; }
 }
}

#
# preambleXml
#
function preambleXml() {
 xmlInOrgLockssTitle = false;

 printf  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
 printf  "<!DOCTYPE lockss-config [\n"
 printf  "<!ELEMENT lockss-config (if|property)+>\n"
 printf  "<!ELEMENT property (property|list|value|if)*>\n"
 printf  "<!ELEMENT list (value)+>\n"
 printf  "<!ELEMENT value (#PCDATA)>\n"
 printf  "<!ELEMENT test EMPTY>\n"
 printf  "<!ELEMENT and (and|or|not|test)*>\n"
 printf  "<!ELEMENT or (and|or|not|test)*>\n"
 printf  "<!ELEMENT not (and|or|not|test)*>\n"
 printf  "<!ELEMENT if (and|or|not|then|else|test|property)*>\n"
 printf  "<!ELEMENT then (if|property)*>\n"
 printf  "<!ELEMENT else (if|property)*>\n"
 printf  "<!ATTLIST property name CDATA #REQUIRED>\n"
 printf  "<!ATTLIST property value CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test hostname CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test group CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test daemonVersionMin CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test daemonVersionMax CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test daemonVersion CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test platformVersionMin CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test platformVersionMax CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test platformVersion CDATA #IMPLIED>\n"
 printf  "<!ATTLIST test platformName CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if hostname CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if group CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if daemonVersionMin CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if daemonVersionMax CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if daemonVersion CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if platformVersionMin CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if platformVersionMax CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if platformVersion CDATA #IMPLIED>\n"
 printf  "<!ATTLIST if platformName CDATA #IMPLIED>\n"
 printf  "<!ATTLIST list append CDATA #IMPLIED>\n"
 printf  "]>\n"
 printf  "\n"
 printf  "<lockss-config>\n"
 printf  "\n"
}

#
# postambleXml
#
function postambleXml() {
 if (xmlInOrgLockssTitle) {
  xmlInOrgLockssTitle = false;
  printf " </property>\n"
  printf "\n"
 }
 printf  "</lockss-config>\n"
}

#
# printOneXmlEntry
#
function printOneXmlEntry(        _status, _param, _attr) {
 # Skip based on output level
 _status = $indexOf[CODE_STATUS]
 if (!outputLevels[_status]) { return }

 # Start config subtree if needed
 if ((outputStyle == STYLE_XML || outputStyle == STYLE_XML_LEGACY) && !xmlInOrgLockssTitle) {
  xmlInOrgLockssTitle = true;
  printf " <property name=\"org.lockss.title\">\n"
  printf "\n"
 }

 # Begin
 printf  "  <property name=\"%s\">\n", getOpaqueName($indexOf[CODE_TITLE])

 # First the publisher if there is one
 if (indexOf[CODE_PUBLISHER] != "") { printOneXmlAttribute("publisher=" xml($indexOf[CODE_PUBLISHER])) }

 # Then the journal title, archival unit title and plugin
 printf  "   <property name=\"journalTitle\" value=\"%s\" />\n", xml($indexOf[CODE_JOURNAL_TITLE])
 printf  "   <property name=\"title\" value=\"%s%s\" />\n", xml($indexOf[CODE_TITLE]), (_status == STATUS_PRE_RELEASED ? " (Pre-release)" : "")
 printf  "   <property name=\"plugin\" value=\"%s\" />\n", $indexOf[CODE_PLUGIN]

 # Then the parameters
 for (_param = 1 ; _param <= numParameters ; ++_param) {
  _pair = $indexParameters[_param]
  if (_pair == "") { continue }
  printOneXmlParameter(_param, _pair)
 }
 # Down AUs are denoted by a parameter
 if (_status == STATUS_DOWN) { printOneXmlParameter(99, "pub_down=true") }

 # Then any additional parameters
 for (_attr = 1 ; _attr <= numAdditionalAttributes ; ++_attr) {
  _pair = $indexAdditionalAttributes[_attr]
  if (_pair == "") { continue }
  printOneXmlAttribute(_pair)
 }

 # Then other tidbits
 if (indexOf[CODE_RIGHTS] != "" && $indexOf[CODE_RIGHTS] == "openaccess") { printOneXmlAttribute("rights=openaccess") }
 if (indexOf[CODE_ESTIMATED_SIZE] != "" && $indexOf[CODE_ESTIMATED_SIZE] != "") {
  printf "   <property name=\"estSize\" value=\"%s\" />\n", $indexOf[CODE_ESTIMATED_SIZE]
 }
 if (_status == STATUS_PRE_RELEASED) { printOneXmlAttribute("releaseStatus=pre-release") }

 # End
 printf  "  </property>\n"
 printf  "\n"
}

#
# printOneXmlParameter
#
function printOneXmlParameter(_num, _pair) {
 printf  "   <property name=\"param.%d\">\n", _num
 printf  "    <property name=\"key\" value=\"%s\" />\n", getKey(_pair)
 printf  "    <property name=\"value\" value=\"%s\" />\n", getValue(_pair)
 printf  "   </property>\n"
}

#
# printOneXmlAttribute
#
function printOneXmlAttribute(_pair) {
 printf  "   <property name=\"attributes.%s\" value=\"%s\" />\n", getKey(_pair), getValue(_pair)
}

#
# getOpaqueName
#
function getOpaqueName(_str) {
 gsub(/ Volume /, "", _str); # FIXME
 gsub(/&/, "and", _str);
 gsub(/[^a-zA-Z0-9]/, "", _str);
 return namePrefix _str
}

#
# getKey
#
function getKey(_str) {
 return match(_str, /^[^=]+=/) ? substr(_str, 1, RLENGTH - 1) : _str
}

#
# getValue
#
function getValue(_str) {
 return match(_str, /^[^=]+=/) ? substr(_str, RLENGTH + 1, length(_str) - RLENGTH) : _str
}

#
# xml
#
function xml(_str) {
 gsub(/&/, "\&", _str);
 gsub(/</, "\<", _str);
 gsub(/>/, "\>", _str);
 return _str
}

##########
# PATTERNS
##########

#
# Blank line
#
/^\t*$/ {
 next
}

#
# Format line
#
/^# @formatString=/ {
 formatString = substr($1, 17, length($1) - 16)
 parseFormatString()
 next
}

#
# Name prefix line
#
/^# @namePrefix=/ {
 namePrefix = substr($1, 15, length($1) - 14)
 next
}

#
# Comment line
#
/^#/ {
 next
}

# Normal line
# unconditional
{
 if (formatString == "") { exit EXIT_NO_FORMAT_STRING }
 if (outputStyle == STYLE_XML || outputStyle == STYLE_XML_ENTRIES || outputStyle == STYLE_XML_LEGACY) { printOneXmlEntry() }
 next
}

#####
# END
#####

END {
 # Postamble
 if (outputStyle == STYLE_XML || outputStyle == STYLE_XML_LEGACY) { postambleXml() }
}

#!/usr/bin/awk -f

#
# BEGIN
#

BEGIN {
 # Constants
 false = 0;
 true = 1;
 CODE_ATTRIBUTE      = "@"
 CODE_ESTIMATED_SIZE = "e"
 CODE_JOURNAL_TITLE  = "j"
 CODE_PARAMETER      = "%"
 CODE_PLUGIN         = "p"
 CODE_PUBLISHER      = "P"
 CODE_RIGHTS         = "R"
 CODE_SKIP_1         = "x"
 CODE_SKIP_2         = "X"
 CODE_STATUS         = "S"
 CODE_TITLE          = "t"
 STATUS_DOES_NOT_EXIST = "does_not_exist"
 STATUS_DO_NOT_PROCESS = "do_not_process"
 STATUS_DOWN           = "down"
 STATUS_EXISTS         = "exists"
 STATUS_MANIFEST       = "manifest"
 STATUS_PRE_RELEASED   = "pre_released"
 STATUS_READY          = "ready"
 STATUS_RELEASED       = "released"
 STATUS_RETRACTED      = "retracted"
 STATUS_TESTING        = "testing"
 LEVEL_CONSERVATIVE_TESTING = "conservativeTesting"
 LEVEL_CONTENT_TESTING      = "contentTesting"
 LEVEL_DANGEROUS            = "dangerous"
 LEVEL_PRE_RELEASE          = "preRelease"
 LEVEL_PRODUCTION           = "production"
 LEVEL_VERY_DANGEROUS       = "veryDangerous"
 LEVEL_DEFAULT              = LEVEL_PRODUCTION
 EXIT_NO_FORMAT_STRING = 11

 # Initial setup
 FS="\t"
 preamble = true
 numAdditionalAttributes = 0
 numParameters = 0
 parseCommandLine()
}

#
# FUNCTIONS
#

# parseCommandLine
function parseCommandLine() {
 if (formatString != "") { parseFormatString() }
 if (outputLevel == "") { outputLevel = LEVEL_DEFAULT }
 parseOutputLevel()
}

# parseFormatString
function parseFormatString() {
 numFields = split(formatString, _fields, ",")
 for (_field = 1 ; _field <= numFields ; ++_field) {
  _code = _fields[_field]
  if (_code == CODE_SKIP_1 || _code == CODE_SKIP_2) { continue }
  else if (_code == CODE_ESTIMATED_SIZE || _code == CODE_JOURNAL_TITLE || _code == CODE_PLUGIN || _code == CODE_TITLE || _code == CODE_PUBLISHER || _code == CODE_STATUS || _code == CODE_RIGHTS) { indexOf[_code] = _field }
  else if (_code == CODE_ATTRIBUTE) { indexAdditionalAttributes[++numAdditionalAttributes] = _field }
  else if (_code == CODE_PARAMETER) { indexParameters[++numParameters] = _field }
 }
}

# parseOutputLevel
function parseOutputLevel() {
 split(outputLevel, _levels, ",")
 for (_i in _levels) {
  if (_levels[_i] == LEVEL_PRODUCTION) { _status = STATUS_RETRACTED "," STATUS_DOWN "," STATUS_RELEASED }
  else if (_levels[_i] == LEVEL_PRE_RELEASE) { _status = STATUS_PRE_RELEASED }
  else if (_levels[_i] == LEVEL_CONTENT_TESTING) { _status = STATUS_RETRACTED "," STATUS_DOWN "," STATUS_RELEASED "," STATUS_PRE_RELEASED "," STATUS_READY "," STATUS_TESTING "," STATUS_MANIFEST "," STATUS_EXISTS }
  else if (_levels[_i] == LEVEL_CONSERVATIVE_TESTING) { _status = STATUS_RELEASED "," STATUS_PRE_RELEASED "," STATUS_READY "," STATUS_TESTING "," STATUS_MANIFEST }
  else if (_levels[_i] == LEVEL_DANGEROUS) { _status = STATUS_RETRACTED "," STATUS_DOWN "," STATUS_RELEASED "," STATUS_PRE_RELEASED "," STATUS_READY "," STATUS_TESTING "," STATUS_MANIFEST "," STATUS_EXISTS "," STATUS_DO_NOT_PROCESS }
  else if (_levels[_i] == LEVEL_VERY_DANGEROUS) { _status = STATUS_RETRACTED "," STATUS_DOWN "," STATUS_RELEASED "," STATUS_PRE_RELEASED "," STATUS_READY "," STATUS_TESTING "," STATUS_MANIFEST "," STATUS_EXISTS "," STATUS_DO_NOT_PROCESS "," STATUS_DOES_NOT_EXIST }
  else { _status = _levels[_i] }
  split(_status, _statuses, ",")
  for (_j in _statuses) { outputLevels[_statuses[_j]] = true; }
 }
}

# printOneEntry
function printOneEntry() {
 _status = $indexOf[CODE_STATUS]
 if (!outputLevels[_status]) { return }

 printf  "  <property name=\"%s\">\n", getOpaqueName($indexOf[CODE_TITLE])

 if (indexOf[CODE_PUBLISHER] != "") { printOneAttribute("publisher=" xml($indexOf[CODE_PUBLISHER])) }
 printf  "   <property name=\"journalTitle\" value=\"%s\" />\n", xml($indexOf[CODE_JOURNAL_TITLE])
   printf  "   <property name=\"title\" value=\"%s%s\" />\n", xml($indexOf[CODE_TITLE]), (_status == STATUS_PRE_RELEASED ? " (Pre-release)" : "")
 printf  "   <property name=\"plugin\" value=\"%s\" />\n", $indexOf[CODE_PLUGIN]

 for (_param = 1 ; _param <= numParameters ; ++_param) {
  _pair = $indexParameters[_param]
  if (_pair == "") { continue }
  printOneParameter(_param, _pair)
 }
 if (_status == STATUS_DOWN) { printOneParameter(99, "pub_down=true") }

 for (_attr = 1 ; _attr <= numAdditionalAttributes ; ++_attr) {
  _pair = $indexAdditionalAttributes[_attr]
  if (_pair == "") { continue }
  printOneAttribute(_pair)
 }
 if (indexOf[CODE_RIGHTS] != "" && $indexOf[CODE_RIGHTS] == "openaccess") { printOneAttribute("rights=openaccess") }
 if (indexOf[CODE_ESTIMATED_SIZE] != "" && $indexOf[CODE_ESTIMATED_SIZE] != "") {
  printf "   <property name=\"estSize\" value=\"%s\" />\n", $indexOf[CODE_ESTIMATED_SIZE]
 }
 if (_status == STATUS_PRE_RELEASED) { printOneAttribute("releaseStatus=pre-release") }

 printf  "  </property>\n\n"

}

# printOneParameter
function printOneParameter(_num, _pair) {
 printf  "   <property name=\"param.%d\">\n", _num
 printf  "    <property name=\"key\" value=\"%s\" />\n", getKey(_pair)
 printf  "    <property name=\"value\" value=\"%s\" />\n", getValue(_pair)
 printf  "   </property>\n"
}

# printOneAttribute
function printOneAttribute(_pair) {
 printf  "   <property name=\"attributes.%s\" value=\"%s\" />\n", getKey(_pair), getValue(_pair)
}

# getOpaqueName
function getOpaqueName(_str) {
 gsub(/ Volume /, "", _str); # FIXME
 gsub(/&/, "and", _str);
 gsub(/[^a-zA-Z0-9]/, "", _str);
 return namePrefix _str
}

# getKey
function getKey(_str) {
 return match(_str, /^[^=]+=/) ? substr(_str, 1, RLENGTH - 1) : _str
}

# getValue
function getValue(_str) {
 return match(_str, /^[^=]+=/) ? substr(_str, RLENGTH + 1, length(_str) - RLENGTH) : _str
}

# xml
function xml(_str) {
 gsub(/&/, "\&", _str);
 gsub(/</, "\<", _str);
 gsub(/>/, "\>", _str);
 return _str
}

#
# PATTERNS
#

# Blank lines
/^\t*$/ {
 next
}

# Format line
/^# @formatString=/ {
 if (preamble && formatString == "") {
  formatString = substr($1, 17, length($1) - 16)
  parseFormatString()
 }
 next
}

# Name prefix line
/^# @namePrefix=/ {
 if (preamble && namePrefix == "") { namePrefix = substr($1, 15, length($1) - 14) }
 next
}

# Comment line
/^#/ {
 next
}

# Normal line
# unconditional
{
 preamble = false
 if (formatString == "") { exit EXIT_NO_FORMAT_STRING }
 printOneEntry()
}


Do not use invalid awk hash escape any more

BEGIN {
	FS="=";
	#print "# BEGIN";
	n="";
	v="";
	c=0; # Not a line continuation.
}
/^#/ { # The line is a comment.  Breaks line continuation.
	c=0;
	next;
}
/\\$/ && (c==0) && (NF>=2) { # Name value pair with a line continuation...
	e=index($0,"=");
	n=substr($0,1,e-1);
	v=substr($0,e+1,length($0) - e - 1);    # Trim off the backslash.
	c=1;                                    # Line continuation mode.
	next;
}
/^[^\\]+\\$/ && (c==1) { # Line continuation.  Accumulate the value.
	v= "" v substr($0,1,length($0)-1);
	next;
}
((c==1) || (NF>=2)) && !/^[^\\]+\\$/ { # End of line continuation, or a single line name/value pair
	if (c==0) {  # Single line name/value pair
		e=index($0,"=");
		n=substr($0,1,e-1);
		v=substr($0,e+1,length($0) - e);
	} else { # Line continuation mode - last line of the value.
		c=0; # Turn off line continuation mode.
		v= "" v $0;
	}
	# Make sure the name is a legal shell variable name
	if (sv==1) {
		gsub(/[^A-Za-z0-9_]/,"_",n);
	}
	# Remove newlines from the value.
	gsub(/[\n\r]/,"",v);
	print n "=\"" v "\"";
	n = "";
	v = "";
}
END {
	#print "# END";
}

BEGIN {
	FS="=";
	#print "# BEGIN";
	n="";
	v="";
	c=0; # Not a line continuation.
}
/^\#/ { # The line is a comment.  Breaks line continuation.
	c=0;
	next;
}
/\\$/ && (c==0) && (NF>=2) { # Name value pair with a line continuation...
	e=index($0,"=");
	n=substr($0,1,e-1);
	v=substr($0,e+1,length($0) - e - 1);    # Trim off the backslash.
	c=1;                                    # Line continuation mode.
	next;
}
/^[^\\]+\\$/ && (c==1) { # Line continuation.  Accumulate the value.
	v= "" v substr($0,1,length($0)-1);
	next;
}
((c==1) || (NF>=2)) && !/^[^\\]+\\$/ { # End of line continuation, or a single line name/value pair
	if (c==0) {  # Single line name/value pair
		e=index($0,"=");
		n=substr($0,1,e-1);
		v=substr($0,e+1,length($0) - e);
	} else { # Line continuation mode - last line of the value.
		c=0; # Turn off line continuation mode.
		v= "" v $0;
	}
	# Make sure the name is a legal shell variable name
	if (sv==1) {
		gsub(/[^A-Za-z0-9_]/,"_",n);
	}
	# Remove newlines from the value.
	gsub(/[\n\r]/,"",v);
	print n "=\"" v "\"";
	n = "";
	v = "";
}
END {
	#print "# END";
}


INTEGRATION: CWS beta2regression03 (1.1.58); FILE MERGED 2003/04/30 15:35:19 er 1.1.58.1: #i13811# (not really); adapt to reality

#!/usr/bin/gawk -f
# Usage: gawk -f currency-check.awk *.xml
# Check any
# <FormatCode>...[$xxx-...]...</FormatCode>
# against every
# <CurrencySymbol>xxx</CurrencySymbol>
# definition of the same XML file and output symbols if no match was found.
# For formatindex="12" to formatindex="15" and for formatindex="17" it is
# checked if the used currency symbol is the usedInCompatibleFormatCodes
# currency symbol as it is needed by the number formatter.
# Also generates output if the generic currency symbol (UTF8 string 0xC2A4)
# is used instead of a real currency symbol.
# Author: Eike Rathke <er@openoffice.org>

BEGIN {
    file = ""
}

file != FILENAME {
    if ( file )
        checkIt()
    file = FILENAME
    line = 0
    nFormats = 0
    nSymbols = 0
    bSymbolDefault = 0
    bSymbolCompati = 0
    bFormatAuto = 0
    sReplaceFrom = ""
    sReplaceTo = ""
    sMatchReplace = ""
    sRefCurrencyFromLocale = ""
}

{
    ++line
    if ( $1 ~ /^<LC_FORMAT$/ )
    {
        if ( $0 ~ /replaceFrom="\[CURRENCY\]"/ )
        {
            sReplaceFrom = "\\[CURRENCY\\]"
            sMatchReplace = "^<FormatCode>.*" sReplaceFrom
        }
        for ( j=2; j<=NF; ++j )
        {
            if ( $j ~ /^replaceTo="/ )
            {
                l = 12
                if ( $j ~ />$/ )
                    ++l
                if ( $j ~ /\/>$/ )
                    ++l
                sReplaceTo = substr( $j, 12, length($j)-l )
            }
        }
    }
    else if ( $1 ~ /^<FormatElement$/ )
    {
        if ( $0 ~ /usage="CURRENCY"/ )
        {
            if ( $0 ~ /formatindex="1[23457]"/ )
                bFormatAuto = 1
            else
                bFormatAuto = 0
        }
    }
    else if ( $0 ~ /^<FormatCode>.*\[\$.*-[0-9a-fA-F]+\]/ ||
            (sMatchReplace && $0 ~ sMatchReplace ) )
    {
        if ( sReplaceFrom )
            gsub( sReplaceFrom, sReplaceTo )
        split( $0, arr, /<|>/ )
        split( arr[3], code, /(\[\$)|(-[0-9a-fA-F]+\])/ )
        for ( j in code )
        {
            if ( code[j] && code[j] !~ /\#|0/ )
            {
                FormatLine[nFormats] = file " line " line
                FormatAuto[nFormats] = bFormatAuto
                Formats[nFormats++] = code[j]
            }
        }
        bFormatAuto = 0
    }
    else if ( $1 ~ /^<LC_CURRENCY$/ )
    {
        for ( j=2; j<=NF; ++j )
        {
            if ( $j ~ /^ref="/ )
            {
                l = 6
                if ( $j ~ />$/ )
                    ++l
                if ( $j ~ /\/>$/ )
                    ++l
                locale = substr( $j, 6, length($j)-l )
                sRefCurrencyFromLocale = file
                oldfile = file
                oldline = line
                file = locale ".xml"
                line = 0
                while ( (getline <file) > 0 )
                {
                    ++line
                    getCurrencyParams()
                }
                close( file )
                if ( !line )
                    print "ref locale not available: " file \
                        " (from " oldfile " line " oldline ")"
                file = oldfile
                line = oldline
                sRefCurrencyFromLocale = ""
            }
        }
    }
    else
        getCurrencyParams()
}

END {
    if ( file )
        checkIt()
}

function getCurrencyParams() {
    if ( $1 ~ /^<Currency$/ )
    {
        if ( $0 ~ /default="true"/ )
            bSymbolDefault = 1
        else
            bSymbolDefault = 0
        if ( $0 ~ /usedInCompatibleFormatCodes="true"/ )
            bSymbolCompati = 1
        else
            bSymbolCompati = 0
    }
    else if ( $0 ~ /^<CurrencySymbol>/ )
    {
        split( $0, arr, /<|>/ )
        if ( sRefCurrencyFromLocale )
            SymbolLine[nSymbols] = file " line " line \
                " (referenced from " sRefCurrencyFromLocale ")"
        else
            SymbolLine[nSymbols] = file " line " line
        SymbolDefault[nSymbols] = bSymbolDefault
        SymbolCompati[nSymbols] = bSymbolCompati
        Symbols[nSymbols++] = arr[3]
        bSymbolDefault = 0
        bSymbolCompati = 0
    }
}

function checkIt() {
    bad = 0
    for ( j=0; j<nFormats; ++j )
    {
        state = FormatInSymbol( Formats[j] )
        if ( Formats[j] == "\xc2\xa4" )
        {
            bad = 1
            print "    bad: `" Formats[j] "'   (" FormatLine[j] ")"
        }
        else if ( state == 0 )
        {
            bad = 1
            print "unknown: `" Formats[j] "'   (" FormatLine[j] ")"
        }
        else if ( FormatAuto[j] && state < 2 )
        {
            bad = 1
            print "badauto: `" Formats[j] "'   (" FormatLine[j] ")"
        }
    }
    if ( bad )
    {
        for ( j=0; j<nSymbols; ++j )
        {
            bDef = 0
            if ( Symbols[j] == "\xc2\xa4" )
                print "def bad: `" Symbols[j] "'   (" SymbolLine[j] ")"
            if ( SymbolDefault[j] )
            {
                bDef = 1
                print "default: `" Symbols[j] "'   (" SymbolLine[j] ")"
            }
            if ( SymbolCompati[j] )
            {
                bDef = 1
                print "compati: `" Symbols[j] "'   (" SymbolLine[j] ")"
            }
            if ( !bDef )
                print "defined: `" Symbols[j] "'   (" SymbolLine[j] ")"
        }
    }
    else
    {
        bHasDefault = 0
        bHasCompati = 0
        for ( j=0; j<nSymbols; ++j )
        {
            if ( Symbols[j] == "\xc2\xa4" )
            {
                bad = 1
                print "def bad: `" Symbols[j] "'   (" SymbolLine[j] ")"
            }
            if ( SymbolDefault[j] )
            {
                if ( !bHasDefault )
                    bHasDefault = 1
                else
                {
                    bad = 1
                    print "dupe default: `" Symbols[j] "'   (" SymbolLine[j] ")"
                }
            }
            if ( SymbolCompati[j] )
            {
                if ( !bHasCompati )
                    bHasCompati = 1
                else
                {
                    bad = 1
                    print "dupe compati: `" Symbols[j] "'   (" SymbolLine[j] ")"
                }
            }
        }
        if ( !bHasDefault )
        {
            bad = 1
            print "  no default: (" file ")"
        }
        if ( !bHasCompati )
        {
            bad = 1
            print "  no compati: (" file ")"
        }
    }
    if ( bad )
        print ""
}

function FormatInSymbol( format ) {
    for ( nSym=0; nSym<nSymbols; ++nSym )
    {
        if ( format == Symbols[nSym] )
        {
            if ( SymbolCompati[nSym] )
                return 2
            else
                return 1
        }
    }
    return 0
}

# vim: ts=4 sw=4 expandtab

#!/usr/bin/gawk -f
#// Usage: gawk -f currency-check.awk *.xml
#// Check any
#// <FormatCode>...[$xxx-...]...</FormatCode>
#// against every
#// <CurrencySymbol>xxx</CurrencySymbol>
#// definition of the same XML file and output symbols if no match was found.
#// For formatindex="12" to formatindex="15" and for formatindex="17" it is
#// checked if the used currency symbol is the usedInCompatibleFormatCodes
#// currency symbol as it is needed by the number formatter.
#// Also generates output if the generic currency symbol (UTF8 string 0xC2A4)
#// is used instead of a real currency symbol.
#// Author: Eike Rathke <erack@sun.com>

BEGIN {
	file = ""
	while ( getline > 0 )
	{
		if ( file != FILENAME )
		{
			if ( file )
				checkIt()
			file = FILENAME
			line = 0
			nFormats = 0
			nSymbols = 0
			bSymbolDefault = 0
            bSymbolCompati = 0
			bFormatAuto = 0
		}
		++line
		if ( $1 ~ /^<FormatElement$/ )
		{
			if ( $5 ~ /^usage="CURRENCY"$/ )
			{
				if ( $6 ~ /^formatindex="1[23457]">$/ )
					bFormatAuto = 1
				else
					bFormatAuto = 0
			}
		}
		else if ( $0 ~ /^<FormatCode>.*\[\$.*-[0-9a-fA-F]+\]/ )
		{
			split( $0, arr, /<|>/ )
			split( arr[3], code, /(\[\$)|(-[0-9a-fA-F]+\])/ )
			for ( j in code )
			{
				if ( code[j] && code[j] !~ /\#|0/ )
				{
					FormatLine[nFormats] = file " line " line
					FormatAuto[nFormats] = bFormatAuto
					Formats[nFormats++] = code[j]
				}
			}
			bFormatAuto = 0
		}
		else if ( $1 ~ /^<Currency$/ )
		{
            if ( $2 ~ /^default="true"/ )
				bSymbolDefault = 1
			else
				bSymbolDefault = 0
            if ( $3 ~ /^usedInCompatibleFormatCodes="true"/ )
                bSymbolCompati = 1
			else
                bSymbolCompati = 0
		}
		else if ( $0 ~ /^<CurrencySymbol>/ )
		{
			split( $0, arr, /<|>/ )
			SymbolLine[nSymbols] = file " line " line
			SymbolDefault[nSymbols] = bSymbolDefault
            SymbolCompati[nSymbols] = bSymbolCompati
			Symbols[nSymbols++] = arr[3]
			bSymbolDefault = 0
            bSymbolCompati = 0
		}
	}
	checkIt()
}

END {
}

function checkIt() {
	bad = 0
	for ( j=0; j<nFormats; ++j )
	{
		state = FormatInSymbol( Formats[j] )
		if ( Formats[j] == "\xc2\xa4" )
		{
			bad = 1
			print "    bad: `" Formats[j] "'   (" FormatLine[j] ")"
		}
		else if ( state == 0 )
		{
			bad = 1
			print "unknown: `" Formats[j] "'   (" FormatLine[j] ")"
		}
		else if ( FormatAuto[j] && state < 2 )
		{
			bad = 1
			print "badauto: `" Formats[j] "'   (" FormatLine[j] ")"
		}
	}
	if ( bad )
	{
		for ( j=0; j<nSymbols; ++j )
		{
            bDef = 0
			if ( Symbols[j] == "\xc2\xa4" )
				print "def bad: `" Symbols[j] "'   (" SymbolLine[j] ")"
            if ( SymbolDefault[j] )
            {
                bDef = 1
				print "default: `" Symbols[j] "'   (" SymbolLine[j] ")"
            }
            if ( SymbolCompati[j] )
            {
                bDef = 1
                print "compati: `" Symbols[j] "'   (" SymbolLine[j] ")"
            }
            if ( !bDef )
				print "defined: `" Symbols[j] "'   (" SymbolLine[j] ")"
		}
	}
	else
	{
        bHasDefault = 0
        bHasCompati = 0
		for ( j=0; j<nSymbols; ++j )
		{
			if ( Symbols[j] == "\xc2\xa4" )
			{
				bad = 1
				print "def bad: `" Symbols[j] "'   (" SymbolLine[j] ")"
			}
            if ( SymbolDefault[j] )
            {
                if ( !bHasDefault )
                    bHasDefault = 1
                else
                {
                    bad = 1
                    print "dupe default: `" Symbols[j] "'   (" SymbolLine[j] ")"
                }
            }
            if ( SymbolCompati[j] )
            {
                if ( !bHasCompati )
                    bHasCompati = 1
                else
                {
                    bad = 1
                    print "dupe compati: `" Symbols[j] "'   (" SymbolLine[j] ")"
                }
            }
		}
        if ( !bHasDefault )
        {
            bad = 1
            print "  no default: (" file ")"
        }
        if ( !bHasCompati )
        {
            bad = 1
            print "  no compati: (" file ")"
        }
	}
	if ( bad )
		print ""
}

function FormatInSymbol( format ) {
	for ( nSym=0; nSym<nSymbols; ++nSym )
	{
		if ( format == Symbols[nSym] )
		{
            if ( SymbolCompati[nSym] )
				return 2
			else
				return 1
		}
	}
	return 0
}


Escape $$ in $OpenBSD$, it's not supposed to be expanded.

# $OpenBSD: devlist2h.awk,v 1.2 2006/03/04 16:32:40 grange Exp $

#
# Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

BEGIN {
	hfile = "onewiredevs.h"
	dfile = "onewiredevs_data.h"
}

NR == 1	{
	VERSION = $0
	gsub("\\$", "", VERSION)

	printf("/*\t\$OpenBSD\$\t*/\n\n" \
	       "/*\n * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.\n" \
	       " *\n * Generated from:\n *\t%s\n */\n\n", VERSION) > hfile
	printf("/*\t\$OpenBSD\$\t*/\n\n" \
	       "/*\n * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.\n" \
	       " *\n * Generated from:\n *\t%s\n */\n\n", VERSION) > dfile
	printf("static const struct onewire_family " \
	       "onewire_familytab[] = {\n") > dfile
}

$1 == "family" {
	printf("#define ONEWIRE_FAMILY_%s\t%s\n", toupper($2), $3) > hfile
	printf("\t{ ONEWIRE_FAMILY_%s, \"", toupper($2)) > dfile

	f = 4
	while (f <= NF) {
		if (f > 4)
			printf(" ") > dfile
		printf("%s", $f) > dfile
		f++
	}
	printf("\" },\n") > dfile
	next
}

END {
	printf("\t{ 0, NULL }\n};\n") > dfile
}

# $OpenBSD: devlist2h.awk,v 1.1 2006/03/04 16:27:03 grange Exp $

#
# Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

BEGIN {
	hfile = "onewiredevs.h"
	dfile = "onewiredevs_data.h"
}

NR == 1	{
	VERSION = $0
	gsub("\\$", "", VERSION)

	printf("/*\t$OpenBSD: devlist2h.awk,v 1.1 2006/03/04 16:27:03 grange Exp $\t*/\n\n" \
	       "/*\n * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.\n" \
	       " *\n * Generated from:\n *\t%s\n */\n\n", VERSION) > hfile
	printf("/*\t$OpenBSD: devlist2h.awk,v 1.1 2006/03/04 16:27:03 grange Exp $\t*/\n\n" \
	       "/*\n * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.\n" \
	       " *\n * Generated from:\n *\t%s\n */\n\n", VERSION) > dfile
	printf("static const struct onewire_family " \
	       "onewire_familytab[] = {\n") > dfile
}

$1 == "family" {
	printf("#define ONEWIRE_FAMILY_%s\t%s\n", toupper($2), $3) > hfile
	printf("\t{ ONEWIRE_FAMILY_%s, \"", toupper($2)) > dfile

	f = 4
	while (f <= NF) {
		if (f > 4)
			printf(" ") > dfile
		printf("%s", $f) > dfile
		f++
	}
	printf("\" },\n") > dfile
	next
}

END {
	printf("\t{ 0, NULL }\n};\n") > dfile
}


Remove obsolete tv_season reference

Remove obsolete tv_season reference

# Generate SHORT_SPREADSHEET by processing LONG_SPREADSHEET to calculate and include durations
#
# Generate a grand total duration by adding up the duration of episodes and movies
# Generate totals for each show by adding up the duration of its episodes
# Update the number of episodes and the show's duration for any that are missing
# NOTE: Depends on file being sorted in reverse order

# INVOCATION:
#    tail -r $LONG_SPREADSHEET | awk -v ERRORS=$ERRORS -v DURATION="$DURATION" \
#        -f calculateBBoxShowDurations.awk | tail -r >>$SHORT_SPREADSHEET

# Field numbers returned by getBBoxCatalogFromSitemap.awk
#     1 Sortkey       2 Title         3 Seasons          4 Episodes         5 Duration      6 Genre
#     7 Year          8 Rating        9 Description     10 Content_Type    11 Content_ID   12 Entity_ID
#    13 Show_Type    14 Date_Type    15 Original_Date   16 Show_ID         17 Season_ID    18 Sn_#
#    19 Ep_#         20 1st_#        21 Last_#

BEGIN {
    FS = "\t"
    OFS = "\t"
}

# No processing on header and other lines unrelated to shows
$1 == "" || $1 == "Sortkey" {
    print
    next
}

# Accumulate total time on any line that has a valid duration
# this incudes all movies and all episodes
$5 != "" {
    # Check all durations for strict HH:MM:SS format
    if ($5 !~ /^[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}$/) {
        print "==> Bad duration " $5 " in " $0 >> ERRORS
        print
        next
    } else {
        split ($5, tm, ":")
        totalTime[3] += tm[3]
        totalTime[2] += tm[2] + int(totalTime[3] / 60)
        totalTime[1] += tm[1] + int(totalTime[2] / 60)
        totalTime[3] %= 60; totalTime[2] %= 60
    }
}

# "tv_episode" indicates an episode, which should always have a valid duration
# Accumulate series time and episode count on any line that has a valid duration
# But don't print episodes in short spreadsheet
$10 == "tv_episode" {
        secs += tm[3]
        mins += tm[2] + int(secs / 60)
        hrs += tm[1] + int(mins / 60)
        secs %= 60; mins %= 60
        episodes += 1
        next
}

# "tv_show" indicates a show, which may or may not have a duration
# If it has no duration, update it from the running total
$10 == "tv_show" {
    if ($5 == "") {
        $4 = episodes
        $5 = sprintf ("%02d:%02d:%02d", hrs, mins, secs)
        secs = 0; mins = 0; hrs = 0;
        episodes = 0
        print
        next
    }
}

$10 == "tv_movie" {
    print
}

END {
    printf ("%02d:%02d:%02d\n", totalTime[1], totalTime[2], totalTime[3]) >> DURATION
}

# Generate SHORT_SPREADSHEET by processing LONG_SPREADSHEET to calculate and include durations
#
# Generate a grand total duration by adding up the duration of episodes and movies
# Generate totals for each show by adding up the duration of its episodes
# Update the number of episodes and the show's duration for any that are missing
# NOTE: Depends on file being sorted in reverse order

# INVOCATION:
#    tail -r $LONG_SPREADSHEET | awk -v ERRORS=$ERRORS -v DURATION="$DURATION" \
#        -f calculateBBoxShowDurations.awk | tail -r >>$SHORT_SPREADSHEET

# Field numbers returned by getBBoxCatalogFromSitemap.awk
#     1 Sortkey       2 Title         3 Seasons          4 Episodes         5 Duration      6 Genre
#     7 Year          8 Rating        9 Description     10 Content_Type    11 Content_ID   12 Entity_ID
#    13 Show_Type    14 Date_Type    15 Original_Date   16 Show_ID         17 Season_ID    18 Sn_#
#    19 Ep_#         20 1st_#        21 Last_#

BEGIN {
    FS = "\t"
    OFS = "\t"
}

# No processing on header and other lines unrelated to shows
$1 == "" || $1 == "Sortkey" {
    print
    next
}

# Don't add seasons to short spreadsheet
$10 == "tv_season" {
    next
}

# Accumulate total time on any line that has a valid duration
# this incudes all movies and all episodes
$5 != "" {
    # Check all durations for strict HH:MM:SS format
    if ($5 !~ /^[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}$/) {
        print "==> Bad duration " $5 " in " $0 >> ERRORS
        print
        next
    } else {
        split ($5, tm, ":")
        totalTime[3] += tm[3]
        totalTime[2] += tm[2] + int(totalTime[3] / 60)
        totalTime[1] += tm[1] + int(totalTime[2] / 60)
        totalTime[3] %= 60; totalTime[2] %= 60
    }
}

# "tv_episode" indicates an episode, which should always have a valid duration
# Accumulate series time and episode count on any line that has a valid duration
# But don't print episodes in short spreadsheet
$10 == "tv_episode" {
        secs += tm[3]
        mins += tm[2] + int(secs / 60)
        hrs += tm[1] + int(mins / 60)
        secs %= 60; mins %= 60
        episodes += 1
        next
}

# "tv_show" indicates a show, which may or may not have a duration
# If it has no duration, update it from the running total
$10 == "tv_show" {
    if ($5 == "") {
        $4 = episodes
        $5 = sprintf ("%02d:%02d:%02d", hrs, mins, secs)
        secs = 0; mins = 0; hrs = 0;
        episodes = 0
        print
        next
    }
}

$10 == "tv_movie" {
    print
}

END {
    printf ("%02d:%02d:%02d\n", totalTime[1], totalTime[2], totalTime[3]) >> DURATION
}


Filter out invalid domain name like "newstarnet.com--NN--".

#!/usr/bin/awk -f

{
	if (/^$/ || /^#/ || /^\!/ || /^\[/ || /^@@/) {
		# Empty line, or line starts with #, !, [ or @@
		# https://adblockplus.org/en/filters#comments
		# https://adblockplus.org/en/filters#whitelist
	} else if (/(^\|\|)|(^\|)/) {
		# Line starts with || or |
		# https://adblockplus.org/en/filters#anchors
		sub(/(^\|\|)|(^\|)/, "") # remove leading || or |
		extract($0)
	} else if (/^\/.*\/$/) {
		# Line in two slashs, like /.../, is a regular expression.
		# https://adblockplus.org/en/filters#regexps
		gsub(/(^\/)|(\/$)/, "") # remove leading and tailing /
		extract_regex($0)
	} else {
		extract($0)
	}
}

END {
	for (i = 1; i <= domain_count; i++) {
		print domains[i] | "sort | uniq"
	}
	close("sort | uniq")
}

# Extract domain name from non-regex line
function extract(line) {

	# Remove everything till ://, such as http:// https://
	sub(/.*:\/\//, "", line)

	# Remove everything from /
	sub(/\/.*/, "", line)

	# Remove everything from :
	sub(/:.*/, "", line)

	# Remove segments(dot separated) contain *
	sub(/[^\.]*\*[^\.]*/, "", line)

	# Remove leading dot
	sub(/^\./, "", line)

	if (line ~ /^((([0-9]{1,2})|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))\.){3}(([0-9]{1,2})|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))$/) {
		# IPv4 string
		print "Skipping line " NR ". " line | "cat >&2"
		close("cat >&2")
	} else if (line ~ /^([A-Za-z0-9\-]+\.)+(xn\-\-)?[A-Za-z0-9]+$/) {
		domains[++domain_count] = line
	} else {
		print "Skipping line " NR ". " line | "cat >&2"
		close("cat >&2")
	}
}

# Extract domain name from regex line
function extract_regex(line) {
	# Expand the lines like (aa|bb|cc) into multiple records
	pos = match(line, /\([A-Za-z0-9\.\|]+\)/)
	if (pos != 0) {
		in_bracket = substr(line, RSTART + 1, RLENGTH - 2)
		n = split(in_bracket, arr, "|")
		for (i = 1; i <= n; i++) {
			expanded_line = line
			sub(/\([A-Za-z0-9\.\|]+\)/, arr[i], expanded_line)
			extract_regex(expanded_line)
		}
	} else {

		# Remove everything till :\/\/ in regex(:// in plain text, such as http:// https://)
		sub(/.*:\\\/\\\//, "", line)

		# Remove (...)*? such as ([^\/]+\.)
		gsub(/\([^\)]+\)\*?/, "", line)

		# Remove [...]
		gsub(/\[.*\]\+/, "", line)

		# Remove everything from \/ in regex(/ in plain text)
		sub(/\\\/.*/, "", line)

		# Replace \. to .
		gsub(/\\\./, ".", line)

		extract(line)
	}
}

#!/usr/bin/awk -f

{
	if (/^$/ || /^#/ || /^\!/ || /^\[/ || /^@@/) {
		# Empty line, or line starts with #, !, [ or @@
		# https://adblockplus.org/en/filters#comments
		# https://adblockplus.org/en/filters#whitelist
	} else if (/(^\|\|)|(^\|)/) {
		# Line starts with || or |
		# https://adblockplus.org/en/filters#anchors
		sub(/(^\|\|)|(^\|)/, "") # remove leading || or |
		extract($0)
	} else if (/^\/.*\/$/) {
		# Line in two slashs, like /.../, is a regular expression.
		# https://adblockplus.org/en/filters#regexps
		gsub(/(^\/)|(\/$)/, "") # remove leading and tailing /
		extract_regex($0)
	} else {
		extract($0)
	}
}

END {
	for (i = 1; i <= domain_count; i++) {
		print domains[i] | "sort | uniq"
	}
	close("sort | uniq")
}

# Extract domain name from non-regex line
function extract(line) {

	# Remove everything till ://, such as http:// https://
	sub(/.*:\/\//, "", line)

	# Remove everything from /
	sub(/\/.*/, "", line)

	# Remove everything from :
	sub(/:.*/, "", line)

	# Remove segments(dot separated) contain *
	sub(/[^\.]*\*[^\.]*/, "", line)

	# Remove leading dot
	sub(/^\./, "", line)

	if (line ~ /^((([0-9]{1,2})|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))\.){3}(([0-9]{1,2})|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))$/) {
		# IPv4 string
		print "Skipping line " NR ". " line | "cat >&2"
		close("cat >&2")
	} else if (line ~ /^([A-Za-z0-9\-]+\.)+[A-Za-z0-9\-]+$/) {
		domains[++domain_count] = line
	} else {
		print "Skipping line " NR ". " line | "cat >&2"
		close("cat >&2")
	}
}

# Extract domain name from regex line
function extract_regex(line) {
	# Expand the lines like (aa|bb|cc) into multiple records
	pos = match(line, /\([A-Za-z0-9\.\|]+\)/)
	if (pos != 0) {
		in_bracket = substr(line, RSTART + 1, RLENGTH - 2)
		n = split(in_bracket, arr, "|")
		for (i = 1; i <= n; i++) {
			expanded_line = line
			sub(/\([A-Za-z0-9\.\|]+\)/, arr[i], expanded_line)
			extract_regex(expanded_line)
		}
	} else {

		# Remove everything till :\/\/ in regex(:// in plain text, such as http:// https://)
		sub(/.*:\\\/\\\//, "", line)

		# Remove (...)*? such as ([^\/]+\.)
		gsub(/\([^\)]+\)\*?/, "", line)

		# Remove [...]
		gsub(/\[.*\]\+/, "", line)

		# Remove everything from \/ in regex(/ in plain text)
		sub(/\\\/.*/, "", line)

		# Replace \. to .
		gsub(/\\\./, ".", line)

		extract(line)
	}
}


Save rearranged titles

Save rearranged titles

We may later want to prevent renaming "The Queen" and others

# Print processed "Program" lines from a WebScraper csv file saved in tsv format

# Field numbers
#    1 web-scraper-order  2 web-scraper-start-url  3 URL        4 Program_Title   5 Sn_Years
#    6 Seasons            7  Mv_Year               8  Duration  9  Rating        10  Description

BEGIN {
    FS="\t"
    print "Sortkey\tTitle\tSeasons\tEpisodes\tDuration\tYear(s)\tRating\tDescription"
}

{
    for ( i = 1; i <= NF; i++ ) {
        if ($i == "null")
            $i = ""
    }
}

/\/us\/movie\/|\/us\/show\// {
    URL = $3
    showTitle = $4
    $7  == "" ? Year = $5 : Year = $7
    NumSeasons = $6
    Duration = $8
    Rating = $9
    Description = $10

    sub (/ Seasons?/,"",NumSeasons)
    sub( / min/,"",Duration)

    # Convert duration from minutes to HMS
    secs = 0
    mins = Duration % 60
    hrs = int(Duration / 60)
    HMS = sprintf ("%02d:%02d:%02d", hrs, mins, secs)
    if (HMS == "00:00:00")
        HMS = ""

    # Titles starting with "The" should not sort based on "The"
    if (match (showTitle, /^The /)) {
        print "==> Rearranging " showTitle >> ERROR_FILE
        showTitle = substr(showTitle, 5) ", The"
    }

    # Indicate different types of programs
    URL ~ /^\/us\/movie\// ? showtype = "M" : showtype = "S"

    # Extract sortkey from URL
    nflds = split (URL,fld,"_")
    if (URL ~ /_[[:digit:]]*$/) {
        sortkey = sprintf ("%s%05d", showtype, fld[nflds])
        savedLine = sprintf \
            ("%s (1) %s\t=HYPERLINK(\"https://www.britbox.com%s\";\"%s\"\)\t%s\t\t%s\t%s\t%s\t%s",\
             showTitle, sortkey, URL, showTitle, NumSeasons, HMS, Year, Rating, Description)

        # Make sure line doesn't start with a single quote so it sorts correctly in Open Office
        sub (/^'/,"",savedLine)

        print savedLine
    }
}

# Print processed "Program" lines from a WebScraper csv file saved in tsv format

# Field numbers
#    1 web-scraper-order  2 web-scraper-start-url  3 URL        4 Program_Title   5 Sn_Years
#    6 Seasons            7  Mv_Year               8  Duration  9  Rating        10  Description

BEGIN {
    FS="\t"
    print "Sortkey\tTitle\tSeasons\tEpisodes\tDuration\tYear(s)\tRating\tDescription"
}

{
    for ( i = 1; i <= NF; i++ ) {
        if ($i == "null")
            $i = ""
    }
}

/\/us\/movie\/|\/us\/show\// {
    URL = $3
    showTitle = $4
    $7  == "" ? Year = $5 : Year = $7
    NumSeasons = $6
    Duration = $8
    Rating = $9
    Description = $10

    sub (/ Seasons?/,"",NumSeasons)
    sub( / min/,"",Duration)

    # Convert duration from minutes to HMS
    secs = 0
    mins = Duration % 60
    hrs = int(Duration / 60)
    HMS = sprintf ("%02d:%02d:%02d", hrs, mins, secs)
    if (HMS == "00:00:00")
        HMS = ""

    # Titles starting with "The" should not sort based on "The"
    if (match (showTitle, /^The /))
        showTitle = substr(showTitle, 5) ", The"

    # Indicate different types of programs
    URL ~ /^\/us\/movie\// ? showtype = "M" : showtype = "S"

    # Extract sortkey from URL
    nflds = split (URL,fld,"_")
    if (URL ~ /_[[:digit:]]*$/) {
        sortkey = sprintf ("%s%05d", showtype, fld[nflds])
        savedLine = sprintf \
            ("%s (1) %s\t=HYPERLINK(\"https://www.britbox.com%s\";\"%s\"\)\t%s\t\t%s\t%s\t%s\t%s",\
             showTitle, sortkey, URL, showTitle, NumSeasons, HMS, Year, Rating, Description)

        # Make sure line doesn't start with a single quote so it sorts correctly in Open Office
        sub (/^'/,"",savedLine)

        print savedLine
    }
}


Check for errors when registering and unregistering firmware modules.  This
prevents the unfortunate situation whereby one might kldload a firmware
module by hand and later kldunload it while a driver still has an open
reference to it.

MFC after:	1 week
Glanced at by:	iedowse

#!/usr/bin/awk -f

#-
# Copyright (c) 2006 Max Laier.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$

#
# Script to generate module .c file from a list of firmware images
#

function usage ()
{
	print "usage: fw_stub <firmware:name>* [-m modname] [-c outfile]";
	exit 1;
}

#   These are just for convenience ...
function printc(s)
{
	if (opt_c)
		print s > ctmpfilename;
	else
		print s > "/dev/stdout";
}

BEGIN {

#
#   Process the command line.
#

num_files = 0;

for (i = 1; i < ARGC; i++) {
	if (ARGV[i] ~ /^-/) {
		#
		#   awk doesn't have getopt(), so we have to do it ourselves.
		#   This is a bit clumsy, but it works.
		#
		for (j = 2; j <= length(ARGV[i]); j++) {
			o = substr(ARGV[i], j, 1);
			if (o == "c") {
				if (length(ARGV[i]) > j) {
					opt_c = substr(ARGV[i], j + 1);
					break;
				}
				else {
					if (++i < ARGC)
						opt_c = ARGV[i];
					else
						usage();
				}
			} else if (o == "m") {
				if (length(ARGV[i]) > j) {
					opt_m = substr(ARGV[i], j + 1);
					break;
				}
				else {
					if (++i < ARGC)
						opt_m = ARGV[i];
					else
						usage();
				}
			} else
				usage();
		}
	} else {
		split(ARGV[i], curr, ":");
		filenames[num_files] = curr[1];
		if (length(curr[2]) > 0)
			shortnames[num_files] = curr[2];
		else
			shortnames[num_files] = curr[2];
		if (length(curr[3]) > 0)
			versions[num_files] = int(curr[3]);
		else
			versions[num_files] = 0;
		num_files++;
	}
}

if (!num_files || !opt_m)
	usage();

cfilename = opt_c;
ctmpfilename = cfilename ".tmp";

printc("#include <sys/param.h>\
#include <sys/errno.h>\
#include <sys/kernel.h>\
#include <sys/module.h>\
#include <sys/linker.h>\
#include <sys/firmware.h>\n");

for (file_i = 0; file_i < num_files; file_i++) {
	symb = filenames[file_i];
	# '-', '.' and '/' are converted to '_' by ld/objcopy
	gsub(/-|\.|\//, "_", symb);
	printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];");
}

printc("\nstatic int\n"\
opt_m "_fw_modevent(module_t mod, int type, void *unused)\
{\
	struct firmware *fp, *parent;\
	int error;\
	switch (type) {\
	case MOD_LOAD:");

for (file_i = 0; file_i < num_files; file_i++) {
	short = shortnames[file_i];
	symb = filenames[file_i];
	version = versions[file_i];
	# '-', '.' and '/' are converted to '_' by ld/objcopy
	gsub(/-|\.|\//, "_", symb);

	reg = "\t\tfp = ";
	reg = reg "firmware_register(\"" short "\", _binary_" symb "_start , ";
	reg = reg "(size_t)(_binary_" symb "_end - _binary_" symb "_start), ";
	reg = reg version ", ";

	if (file_i == 0)
		reg = reg "NULL);";
	else
		reg = reg "parent);";

	printc(reg);

	printc("\t\tif (fp == NULL)");
	printc("\t\t\tgoto fail_" file_i ";");
	if (file_i == 0)
		printc("\t\tparent = fp;");
}

printc("\t\treturn (0);");

for (file_i = num_files - 1; file_i > 0; file_i--) {
	printc("\tfail_" file_i ":")
	printc("\t\t(void)firmware_unregister(\"" shortnames[file_i - 1] "\");");
}

printc("\tfail_0:");
printc("\t\treturn (ENXIO);");

printc("\tcase MOD_UNLOAD:");

for (file_i = 1; file_i < num_files; file_i++) {
	printc("\t\terror = firmware_unregister(\"" shortnames[file_i] "\");");
	printc("\t\tif (error)");
	printc("\t\t\treturn (error);");
}

printc("\t\terror = firmware_unregister(\"" shortnames[0] "\");");

printc("\t\treturn (error);\
	}\
	return (EINVAL);\
}\
\
static moduledata_t " opt_m "_fw_mod = {\
        \"" opt_m "_fw\",\
        " opt_m "_fw_modevent,\
        0\
};\
DECLARE_MODULE(" opt_m "_fw, " opt_m "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
MODULE_VERSION(" opt_m "_fw, 1);\
MODULE_DEPEND(" opt_m "_fw, firmware, 1, 1, 1);\
");

if (opt_c)
	if ((rc = system("mv -f " ctmpfilename " " cfilename))) {
		print "'mv -f " ctmpfilename " " cfilename "' failed: " rc \
		    > "/dev/stderr";
		exit 1;
	}

exit 0;

}

#!/usr/bin/awk -f

#-
# Copyright (c) 2006 Max Laier.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$

#
# Script to generate module .c file from a list of firmware images
#

function usage ()
{
	print "usage: fw_stub <firmware:name>* [-m modname] [-c outfile]";
	exit 1;
}

#   These are just for convenience ...
function printc(s)
{
	if (opt_c)
		print s > ctmpfilename;
	else
		print s > "/dev/stdout";
}

BEGIN {

#
#   Process the command line.
#

num_files = 0;

for (i = 1; i < ARGC; i++) {
	if (ARGV[i] ~ /^-/) {
		#
		#   awk doesn't have getopt(), so we have to do it ourselves.
		#   This is a bit clumsy, but it works.
		#
		for (j = 2; j <= length(ARGV[i]); j++) {
			o = substr(ARGV[i], j, 1);
			if (o == "c") {
				if (length(ARGV[i]) > j) {
					opt_c = substr(ARGV[i], j + 1);
					break;
				}
				else {
					if (++i < ARGC)
						opt_c = ARGV[i];
					else
						usage();
				}
			} else if (o == "m") {
				if (length(ARGV[i]) > j) {
					opt_m = substr(ARGV[i], j + 1);
					break;
				}
				else {
					if (++i < ARGC)
						opt_m = ARGV[i];
					else
						usage();
				}
			} else
				usage();
		}
	} else {
		split(ARGV[i], curr, ":");
		filenames[num_files] = curr[1];
		if (length(curr[2]) > 0)
			shortnames[num_files] = curr[2];
		else
			shortnames[num_files] = curr[2];
		if (length(curr[3]) > 0)
			versions[num_files] = int(curr[3]);
		else
			versions[num_files] = 0;
		num_files++;
	}
}

if (!num_files || !opt_m)
	usage();

cfilename = opt_c;
ctmpfilename = cfilename ".tmp";

printc("#include <sys/param.h>\
#include <sys/errno.h>\
#include <sys/kernel.h>\
#include <sys/module.h>\
#include <sys/linker.h>\
#include <sys/firmware.h>\n");

for (file_i = 0; file_i < num_files; file_i++) {
	symb = filenames[file_i];
	# '-', '.' and '/' are converted to '_' by ld/objcopy
	gsub(/-|\.|\//, "_", symb);
	printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];");
}

printc("\nstatic int\n"\
opt_m "_fw_modevent(module_t mod, int type, void *unused)\
{\
	struct firmware *fp;\
	switch (type) {\
	case MOD_LOAD:");

for (file_i = 0; file_i < num_files; file_i++) {
	short = shortnames[file_i];
	symb = filenames[file_i];
	version = versions[file_i];
	# '-', '.' and '/' are converted to '_' by ld/objcopy
	gsub(/-|\.|\//, "_", symb);

	if (file_i == 0)
		reg = "\t\tfp = ";
	else
		reg = "\t\t(void)";

	reg = reg "firmware_register(\"" short "\", _binary_" symb "_start , ";
	reg = reg "(size_t)(_binary_" symb "_end - _binary_" symb "_start), ";
	reg = reg version ", ";

	if (file_i == 0)
		reg = reg "NULL);";
	else
		reg = reg "fp);";

	printc(reg);
}

printc("\t\treturn (0);\
	case MOD_UNLOAD:");

for (file_i = 1; file_i < num_files; file_i++) {
	printc("\t\tfirmware_unregister(\"" shortnames[file_i] "\");");
}

printc("\t\tfirmware_unregister(\"" shortnames[0] "\");");

printc("\t\treturn (0);\
	}\
	return (EINVAL);\
}\
\
static moduledata_t " opt_m "_fw_mod = {\
        \"" opt_m "_fw\",\
        " opt_m "_fw_modevent,\
        0\
};\
DECLARE_MODULE(" opt_m "_fw, " opt_m "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
MODULE_VERSION(" opt_m "_fw, 1);\
MODULE_DEPEND(" opt_m "_fw, firmware, 1, 1, 1);\
");

if (opt_c)
	if ((rc = system("mv -f " ctmpfilename " " cfilename))) {
		print "'mv -f " ctmpfilename " " cfilename "' failed: " rc \
		    > "/dev/stderr";
		exit 1;
	}

exit 0;

}


add all backgrounds in one place

add all backgrounds in one place

BEGIN {
  slidecount = 0
}

/
/ {
  print ""
  print "
"
  print "  "
  print "  Gabor.Greif@alcatel-lucent.com"
  print "
"
  print ""
  print "
"
  print "  "
  print "
"
  print ""
}

/
/ {
  slidecount++
  if (slidecount == 2)
  {
    sub(/slide/, "slide haskell")
  }
}

{ print }

BEGIN {
  slidecount = 0
}

/
/ {
  print ""
  print "
"
  print "  "
  print "
"
  print ""
}

/
/ {
  slidecount++
  if (slidecount == 2)
  {
    print ""
    print "
"
    print "  "
    print "
"
    print ""

    sub(/slide/, "slide haskell")
  }
}

{ print }