Make IMDB scripts shfmt compatible

Make IMDB scripts shfmt compatible


get_vectors updated (take 1/1000 of all vectors by default)

#!/usr/bin/awk -f

##################################################################
BEGIN {
    if (ARGC != 4) {
	printf("Incorrect number of arguments.") > "/sys/stderr"
	exit 1
    }

    ret = 0
    WCL = 0 + ARGV[1]
    # obtain words to fetch
    ifile = ARGV[2]
    while ((ret = (getline < ifile)) > 0) {
	if (!NF)
	    continue
	else if (NF != 2) {
	    printf("Incorrect line format: %s", $0) > "/sys/stderr"
	    exit 2
	}
	WORD2SEEK[$1] = ""
    }
    ARGV[1] = ARGV[2] = ""
    # obtain random line numbers to fetch
    srand()
    wcl = WCL - 1
    for (i = 1; i < WCL; ++i) {
	randarr[i] = rand() * wcl + 1
    }
    asorti(randarr, tmparr)
    wcl = WCL / 1000
    for (i = 1; i < wcl; ++i) {
	FNR2SEEK[tmparr[i]] = ""
    }
}

##################################################################
NF && FNR > 1 && ($1 in WORD2SEEK || FNR in FNR2SEEK)

#!/usr/bin/awk -f

##################################################################
BEGIN {
    FS = "\t"
    if (ARGC != 4) {
	printf("Incorrect number of arguments.") > "/sys/stderr"
	exit 1
    }

    ret = 0
    WCL = 0 + ARGV[1]
    # obtain words to fetch
    ifile = ARGV[2]
    while ((ret = (getline < ifile)) > 0) {
	if (!NF)
	    continue
	else if (NF != 2) {
	    printf("Incorrect line format: %s", $0) > "/sys/stderr"
	    exit 2
	}
	WORD2SEEK[$1] = ""
    }
    ARGV[1] = ARGV[2] = ""
    # obtain random line numbers to fetch
    srand()
    wcl = WCL - 1
    for (i = 1; i < WCL; ++i) {
	randarr[i] = rand() * wcl + 1
    }
    asorti(randarr, tmparr)
    delete randarr
    wcl = WCL / 100
    for (i = 1; i < WCL; ++i) {
	FNR2SEEK[tmparr[i]] = ""
    }
}

##################################################################
NF && FNR > 1 && ($1 in WORD2SEEK || FNR in FNR2SEEK)


TranslatorInterface: add abstract method _PostRequestUrl()

####################################################################
# TranslatorInterface.awk                                          #
####################################################################

# Abstract method foobarInit(): ()
function _Init(    vm) {
    vm = engineMethod("Init")
    return @vm()
}

# Abstract method foobarRequestUrl(text, sl, tl, hl: string): string
function _RequestUrl(text, sl, tl, hl,    vm) {
    vm = engineMethod("RequestUrl")
    return @vm(text, sl, tl, hl)
}

# Abstract method foobarPostRequestUrl(text, sl, tl, hl: string): string
function _PostRequestUrl(text, sl, tl, hl,    vm) {
    vm = engineMethod("PostRequestUrl")
    return @vm(text, sl, tl, hl)
}

# Abstract method foobarTTSUrl(text, tl: string): string
function _TTSUrl(text, tl,    vm) {
    vm = engineMethod("TTSUrl")
    return @vm(text, tl)
}

# Abstract method foobarWebTranslateUrl(uri, sl, tl, hl: string): string
function _WebTranslateUrl(uri, sl, tl, hl,    vm) {
    vm = engineMethod("WebTranslateUrl")
    return @vm(uri, sl, tl, hl)
}

# Abstract method foobarTranslate(text, sl, tl, hl: string,
#                                 isVerbose, toSpeech: boolean,
#                                 returnPlaylist, returnIl: array): string
function _Translate(text, sl, tl, hl,
                    isVerbose, toSpeech, returnPlaylist, returnIl,
                    ####
                    vm) {
    vm = engineMethod("Translate")
    return @vm(text, sl, tl, hl,
               isVerbose, toSpeech, returnPlaylist, returnIl)
}

####################################################################
# TranslatorInterface.awk                                          #
####################################################################

# Abstract method foobarInit(): ()
function _Init(    vm) {
    vm = engineMethod("Init")
    return @vm()
}

# Abstract method foobarRequestUrl(text, sl, tl, hl: string): string
function _RequestUrl(text, sl, tl, hl,    vm) {
    vm = engineMethod("RequestUrl")
    return @vm(text, sl, tl, hl)
}

# Abstract method foobarTTSUrl(text, tl: string): string
function _TTSUrl(text, tl,    vm) {
    vm = engineMethod("TTSUrl")
    return @vm(text, tl)
}

# Abstract method foobarWebTranslateUrl(uri, sl, tl, hl: string): string
function _WebTranslateUrl(uri, sl, tl, hl,    vm) {
    vm = engineMethod("WebTranslateUrl")
    return @vm(uri, sl, tl, hl)
}

# Abstract method foobarTranslate(text, sl, tl, hl: string,
#                                 isVerbose, toSpeech: boolean,
#                                 returnPlaylist, returnIl: array): string
function _Translate(text, sl, tl, hl,
                    isVerbose, toSpeech, returnPlaylist, returnIl,
                    ####
                    vm) {
    vm = engineMethod("Translate")
    return @vm(text, sl, tl, hl,
               isVerbose, toSpeech, returnPlaylist, returnIl)
}


fix inconsistency for parsing option -player

####################################################################
# 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
    }
}

# Main initialization.
function init() {
    initGawk()          #<< AnsiCode

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

    # Translate
    initHttpService()

    RS = "\n"

    ExitCode = 0

    Option["debug"] = 0

    Option["verbose"] = 1
    Option["width"] = ENVIRON["COLUMNS"] ? ENVIRON["COLUMNS"] : 64

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

    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
}

# Main entry point.
BEGIN {
    init()

    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 | " \
                       "less -P\"\\ \\Manual page " Command "(1) line %lt (press h for help or q to quit)\"")
            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
        }

        # -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
        }

        # -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
    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 (pos < ARGC) {
        # More parameters

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

            translate(ARGV[i])
        }

        # 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
    }
}

# Main initialization.
function init() {
    initGawk()          #<< AnsiCode

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

    # Translate
    initHttpService()

    RS = "\n"

    ExitCode = 0

    Option["debug"] = 0

    Option["verbose"] = 1
    Option["width"] = ENVIRON["COLUMNS"] ? ENVIRON["COLUMNS"] : 64

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

    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
}

# Main entry point.
BEGIN {
    init()

    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 | " \
                       "less -P\"\\ \\Manual page " Command "(1) line %lt (press h for help or q to quit)\"")
            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
        }

        # -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[2] ?
                (group[3] ? group[3] : Option["player"]) :
                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
    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 (pos < ARGC) {
        # More parameters

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

            translate(ARGV[i])
        }

        # 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
}


-discontinuity mode

-discontinuity mode

BEGIN{
    if(!maxInterval)
        maxInterval=60
    if(!maxChunkDuration)
        maxChunkDuration=12000
    if(!minChunkDuration)
        minChunkDuration=1000
    state = "waitChunk"
    if(!verbose)
        verbose=1
}

function addStats(caption,data){
    cnts[caption] = cnts[caption] + 1
    sums[caption] = sums[caption] + data
    sums2[caption] = sums2[caption] + data*data
}

function printStats(caption){
    cnt = cnts[caption]
    if(cnt){
        sum = sums[caption]
        sum2 = sums2[caption]
        stddev = 0
        if((cnt > 1)){
         stddev = sqrt( (sum2*cnt -sum*sum) / (cnt*(cnt-1)))
        }
        printf "%s avg request interval: %.2f stddev: %.2f #: %d\n", caption,sum/cnt,stddev,cnt
    } else {
        print "couldn't find stats for "caption
    }
}

function parseChunkName(arr){

   if(segId && (segId+1) == b[4] && (segTime + segDuration != b[2])){

        printf ("[%d] segment discontinuity: %d new { %d %d } old: { %d %d }\n",
         segId,b[2]-(segTime+segDuration),b[2],b[3],
         segTime,segDuration)
   }

    segTime = b[2]
    segDuration = b[3]
    segId = b[4]

    #printf("parseChunkName segTime=%d segDuration=%d segId=%d\n",
    #    segTime,
    #    segDuration,
    #    segId)

}

$0 ~ /\[debug\]/ && $0 ~ /GET \/hls\/(.*)\/playlist.json\/seg/ {
    split($10,b,"-");
    lastChunkPath=$10
    if(verbose){
        print $2 " "lastChunkPath;
    }

    if(length(b) == 6){
        lastChunkId = b[4]
        parseChunkName(b)
    } else {
        lastChunkId =  b[2]
    }
    if(lastChunk && lastChunk+1 != lastChunkId){
        print $2" "lastChunkPath" error: expected chunk "lastChunk+1" got: "lastChunkId
        delete __lastDTS[0]
    }
    lastChunk=lastChunkId;
    split($2,a,":");
    time=a[3]+a[2]*60+a[1]*3600;
    if(lastTime){
        diff=time-lastTime
        if(diff>maxInterval){
            print $2" "lastChunkPath" error: requested chunk after "diff" sec."
        }
        if(diff>0){
            addStats("chunkInterval",diff)
        }
    }
    lastTime = time
    state = "checkDTS"
}

verbose && state == "checkDTS" && $0 ~ /parsed clip source/ {
    print $2" "$11" "$12" "$13
}

state == "checkDTS" && $0 ~ /first frame dts/ {
    state = "waitChunk"
    if( __lastDTS[0]){
        chunkDuration = $11 -  __lastDTS[0]

        addStats("chunkDuration",chunkDuration)
        if(chunkDuration > maxChunkDuration || chunkDuration < minChunkDuration){
            print $2" "lastChunkPath" bad chunk duration "chunkDuration
        }
    }
     __lastDTS[0] = $11
}

$0 ~ /media_set_parse_json: produced segment/ {
    tmp1 = $9
    tmp2=$11
    tmp3=$13
    if(segment_index){
        if(segment_index == tmp1 - 1){
            if(segment_start_time+segment_duration != tmp2){
                printf (" chunk %d adjucent chunks  differ: diff: %d prev={ %d  %d}  cur={%d %d}\n",tmp1,
                (tmp2-segment_start_time-segment_duration),
                segment_start_time,
                segment_duration,
                tmp2,
                tmp3)
            }
        } else {
            print "segment discontinuity: cur: "tmp1" prev: "segment_index
        }
    }
    segment_index = tmp1
    segment_start_time=tmp2
    segment_duration=tmp3

  # print " debug info:  "segment_index" "segment_start_time" "segment_duration
}

END {
    printStats("chunkInterval")
    printStats("chunkDuration")
}

BEGIN{
    if(!maxInterval)
        maxInterval=60
    if(!maxChunkDuration)
        maxChunkDuration=12000
    if(!minChunkDuration)
        minChunkDuration=1000
    state = "waitChunk"
    if(!verbose)
        verbose=1
}

function addStats(caption,data){
    cnts[caption] = cnts[caption] + 1
    sums[caption] = sums[caption] + data
    sums2[caption] = sums2[caption] + data*data
}

function printStats(caption){
    cnt = cnts[caption]
    if(cnt){
        sum = sums[caption]
        sum2 = sums2[caption]
        stddev = 0
        if((cnt > 1)){
         stddev = sqrt( (sum2*cnt -sum*sum) / (cnt*(cnt-1)))
        }
        printf "%s avg request interval: %.2f stddev: %.2f #: %d\n", caption,sum/cnt,stddev,cnt
    } else {
        print "couldn't find stats for "caption
    }
}

$0 ~ /\[debug\]/ && $0 ~ /GET \/hls\/(.*)\/playlist.json\/seg/ {
    split($10,b,"-");
    lastChunkPath=$10
    if(verbose){
        print $2 " "lastChunkPath;
    }

    if(length(b) == 6){
        lastChunkId = b[4]
    } else {
        lastChunkId =  b[2]
    }
    if(lastChunk && lastChunk+1 != lastChunkId){
        print $2" "lastChunkPath" error: expected chunk "lastChunk+1" got: "lastChunkId
        delete __lastDTS[0]
    }
    lastChunk=lastChunkId;
    split($2,a,":");
    time=a[3]+a[2]*60+a[1]*3600;
    if(lastTime){
        diff=time-lastTime
        if(diff>maxInterval){
            print $2" "lastChunkPath" error: requested chunk after "diff" sec."
        }
        if(diff>0){
            addStats("chunkInterval",diff)
        }
    }
    lastTime = time
    state = "checkDTS"
}

verbose && state == "checkDTS" && $0 ~ /parsed clip source/ {
    print $2" "$11" "$12" "$13
}

state == "checkDTS" && $0 ~ /first frame dts/ {
    state = "waitChunk"
    if( __lastDTS[0]){
        chunkDuration = $11 -  __lastDTS[0]

        addStats("chunkDuration",chunkDuration)
        if(chunkDuration > maxChunkDuration || chunkDuration < minChunkDuration){
            print $2" "lastChunkPath" bad chunk duration "chunkDuration
        }
    }
     __lastDTS[0] = $11
}

$0 ~ /media_set_parse_json: produced segment/ {
    tmp1 = $9
    tmp2=$11
    tmp3=$13
    if(segment_index){
        if(segment_index == tmp1 - 1){
            if(segment_start_time+segment_duration != tmp2){
                printf (" chunk %d adjucent chunks  differ: diff: %d prev={ %d  %d}  cur={%d %d}\n",tmp1,
                (tmp2-segment_start_time+segment_duration),
                segment_start_time,
                segment_duration,
                tmp2,
                tmp3)
            }
        } else {
            print "segment discontinuity: cur: "tmp1" prev: "segment_index
        }
    }
    segment_index = tmp1
    segment_start_time=tmp2
    segment_duration=tmp3
}

END {
    printStats("chunkInterval")
    printStats("chunkDuration")
}


syscall: Convert errno to error after Exitsyscall.

R=iant
CC=gofrontend-dev
https://golang.org/cl/5969050

# Copyright 2011 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# This AWK script reads a Go file with comments describing syscall
# functions and the C routines they map to.  It generates the Go code
# which calls the C routines.

# The syscall functins are marked by lines beginning with "//sys" and
# read like func declarations if //sys is replaced by func, but:
#	* The parameter lists must give a name for each argument.
#	  This includes return parameters.
#	* The parameter lists must give a type for each argument:
#	   the (x, y, z int) shorthand is not allowed.
#	* If the return parameter is an error, it must be named err.

# A line beginning with //sysnb is like //sys, except that the
# goroutine will not be suspended during the execution of the library
# call.  This must only be used for library calls which can never
# block, as otherwise the library call could cause all goroutines to
# hang.

# After the //sys or //sysnb line comes a second line which describes
# the C function.  The name must be the name of the function in the C
# library, and may be the same as the Go function.  The limitations on
# the argument list are the same as for the //sys line, but there must
# be at most one result parameter, and it must be given as just a
# type, without a name.

BEGIN {
    print "// This file was automatically generated by mksyscall.awk"
    print ""
    print "package syscall"
    print ""
    print "import \"unsafe\""
    print ""
    status = 0
}

/^\/\/sys/ {
    if ($1 == "//sysnb") {
	blocking = 0
    } else {
	blocking = 1
    }

    line = $0

    if (match(line, "//sys(nb)?[ 	]*[a-zA-Z0-9_]+\\([^()]*\\) *(\\(([^()]+)\\))?") == 0) {
	print "unmatched line:", $0 | "cat 1>&2"
	status = 1
	next
    }

    # Sets a[1] = //sysnb, a[2] == function name.
    split(line, a, "[ 	(]*")
    gofnname = a[2]

    off = match(line, "\\([^()]*\\)")
    end = index(substr(line, off, length(line) - off + 1), ")")
    gofnparams = substr(line, off + 1, end - 2)

    line = substr(line, off + end, length(line) - (off + end) + 1)
    off = match(line, "\\([^()]*\\)")
    if (off == 0) {
	gofnresults = ""
    } else {
	end = index(substr(line, off, length(line) - off + 1), ")")
	gofnresults = substr(line, off + 1, end - 2)
    }

    getline
    line = $0

    if (match(line, "//[a-zA-Z0-9_]+\\([^()]*\\)") == 0) {
	print "unmatched C line", $0, "after", gofnname | "cat 1>&2"
	status = 1
	next
    }

    split(line, a, "[ 	(]*")
    cfnname = substr(a[1], 3, length(a[1]) - 2)

    off = match(line, "\\([^()]*\\)")
    end = index(substr(line, off, length(line) - off + 1), ")")
    cfnparams = substr(line, off + 1, end - 2)

    line = substr(line, off + end + 1, length(line) - (off + end) + 1)
    while (substr(line, 1, 1) == " ") {
	line = substr(line, 2, length(line) - 1)
    }
    end = index(line, " ")
    if (end != 0) {
	line = substr(line, 1, end)
    }
    cfnresult = line

    printf("// Automatically generated wrapper for %s/%s\n", gofnname, cfnname)
    printf("//extern %s\n", cfnname)
    printf("func c_%s(%s) %s\n", cfnname, cfnparams, cfnresult)
    printf("func %s(%s) %s%s%s%s{\n",
	   gofnname, gofnparams, gofnresults == "" ? "" : "(", gofnresults,
	   gofnresults == "" ? "" : ")", gofnresults == "" ? "" : " ")

    loc = gofnname "/" cfnname ":"

    split(gofnparams, goargs, ", *")
    split(cfnparams, cargs, ", *")
    args = ""
    carg = 1
    for (goarg = 1; goargs[goarg] != ""; goarg++) {
	if (cargs[carg] == "") {
	    print loc, "not enough C parameters"
	}

	if (args != "") {
	    args = args ", "
	}

	if (split(goargs[goarg], a) != 2) {
	    print loc, "bad parameter:", goargs[goarg] | "cat 1>&2"
	    status = 1
	    next
	}

	goname = a[1]
	gotype = a[2]

	if (split(cargs[carg], a) != 2) {
	    print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
	    status = 1
	    next
	}

	ctype = a[2]

	if (gotype ~ /^\*/) {
	    if (gotype != ctype) {
		print loc, "Go/C pointer type mismatch:", gotype, ctype | "cat 1>&2"
		status = 1
		next
	    }
	    args = args goname
	} else if (gotype == "string") {
	    if (ctype != "*byte") {
		print loc, "Go string not matched to C *byte:", gotype, ctype | "cat 1>&2"
		status = 1
		next
	    }
	    printf("\t_p%d := StringBytePtr(%s)\n", goarg, goname)
	    args = sprintf("%s_p%d", args, goarg)
	} else if (gotype ~ /^\[\](.*)/) {
	    if (ctype !~ /^\*/ || cargs[carg + 1] == "") {
		print loc, "bad C type for slice:", gotype, ctype | "cat 1>&2"
		status = 1
		next
	    }

	    # Convert a slice into a pair of pointer, length.
	    # Don't try to take the address of the zeroth element of a
	    # nil slice.
	    printf("\tvar _p%d %s\n", goarg, ctype)
	    printf("\tif len(%s) > 0 {\n", goname)
	    printf("\t\t_p%d = (%s)(unsafe.Pointer(&%s[0]))\n", goarg, ctype, goname)
	    printf("\t} else {\n")
	    printf("\t\t_p%d = (%s)(unsafe.Pointer(&_zero))\n", goarg, ctype)
	    printf("\t}\n")

	    ++carg
	    if (split(cargs[carg], cparam) != 2) {
		print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
		status = 1
		next
	    }

	    args = sprintf("%s_p%d, %s(len(%s))", args, goarg, cparam[2], goname)
	} else if (gotype == "uintptr" && ctype ~ /^\*/) {
	    args = sprintf("%s(%s)(unsafe.Pointer(%s))", args, ctype, goname)
	} else {
	    args = sprintf("%s%s(%s)", args, ctype, goname)
	}

	carg++
    }

    if (cargs[carg] != "") {
	print loc, "too many C parameters" | "cat 1>&2"
	status = 1
	next
    }

    if (blocking) {
	print "\tEntersyscall()"
    }

    printf("\t")
    if (gofnresults != "") {
	printf("_r := ")
    }
    printf("c_%s(%s)\n", cfnname, args)

    seterr = 0
    if (gofnresults != "") {
	fields = split(gofnresults, goresults, ", *")
	if (fields > 2) {
	    print loc, "too many Go results" | "cat 1>&2"
	    status = 1
	    next
	}
	usedr = 0
	for (goresult = 1; goresults[goresult] != ""; goresult++) {
	    if (split(goresults[goresult], goparam) != 2) {
		print loc, "bad result:", goresults[goresult] | "cat 1>&2"
		status = 1
		next
	    }

	    goname = goparam[1]
	    gotype = goparam[2]

	    if (goname == "err") {
		print "\tvar errno Errno"
		print "\tsetErrno := false"
		if (cfnresult ~ /^\*/) {
		    print "\tif _r == nil {"
		} else {
		    print "\tif _r < 0 {"
		}
		print "\t\terrno = GetErrno()"
		print "\t\tsetErrno = true"
		print "\t}"
		seterr = 1
	    } else if (gotype == "uintptr" && cfnresult ~ /^\*/) {
		printf("\t%s = (%s)(unsafe.Pointer(_r))\n", goname, gotype)
	    } else {
		if (usedr) {
		    print loc, "two parameters but no errno parameter" | "cat 1>&2"
		    status = 1
		    next
		}
		printf("\t%s = (%s)(_r)\n", goname, gotype)
		usedr = 1
	    }
	}
    }

    if (blocking) {
	print "\tExitsyscall()"
    }

    if (seterr) {
	print "\tif setErrno {"
	print "\t\terr = errno"
	print "\t}"
    }

    if (gofnresults != "") {
	print "\treturn"
    }

    print "}"

    print ""

    next
}

{ next }

END {
    if (status != 0) {
	print "*** mksyscall.awk failed" | "cat 1>&2"
	exit status
    }
}

# Copyright 2011 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# This AWK script reads a Go file with comments describing syscall
# functions and the C routines they map to.  It generates the Go code
# which calls the C routines.

# The syscall functins are marked by lines beginning with "//sys" and
# read like func declarations if //sys is replaced by func, but:
#	* The parameter lists must give a name for each argument.
#	  This includes return parameters.
#	* The parameter lists must give a type for each argument:
#	   the (x, y, z int) shorthand is not allowed.
#	* If the return parameter is an error, it must be named err.

# A line beginning with //sysnb is like //sys, except that the
# goroutine will not be suspended during the execution of the library
# call.  This must only be used for library calls which can never
# block, as otherwise the library call could cause all goroutines to
# hang.

# After the //sys or //sysnb line comes a second line which describes
# the C function.  The name must be the name of the function in the C
# library, and may be the same as the Go function.  The limitations on
# the argument list are the same as for the //sys line, but there must
# be at most one result parameter, and it must be given as just a
# type, without a name.

BEGIN {
    print "// This file was automatically generated by mksyscall.awk"
    print ""
    print "package syscall"
    print ""
    print "import \"unsafe\""
    print ""
    status = 0
}

/^\/\/sys/ {
    if ($1 == "//sysnb") {
	blocking = 0
    } else {
	blocking = 1
    }

    line = $0

    if (match(line, "//sys(nb)?[ 	]*[a-zA-Z0-9_]+\\([^()]*\\) *(\\(([^()]+)\\))?") == 0) {
	print "unmatched line:", $0 | "cat 1>&2"
	status = 1
	next
    }

    # Sets a[1] = //sysnb, a[2] == function name.
    split(line, a, "[ 	(]*")
    gofnname = a[2]

    off = match(line, "\\([^()]*\\)")
    end = index(substr(line, off, length(line) - off + 1), ")")
    gofnparams = substr(line, off + 1, end - 2)

    line = substr(line, off + end, length(line) - (off + end) + 1)
    off = match(line, "\\([^()]*\\)")
    if (off == 0) {
	gofnresults = ""
    } else {
	end = index(substr(line, off, length(line) - off + 1), ")")
	gofnresults = substr(line, off + 1, end - 2)
    }

    getline
    line = $0

    if (match(line, "//[a-zA-Z0-9_]+\\([^()]*\\)") == 0) {
	print "unmatched C line", $0, "after", gofnname | "cat 1>&2"
	status = 1
	next
    }

    split(line, a, "[ 	(]*")
    cfnname = substr(a[1], 3, length(a[1]) - 2)

    off = match(line, "\\([^()]*\\)")
    end = index(substr(line, off, length(line) - off + 1), ")")
    cfnparams = substr(line, off + 1, end - 2)

    line = substr(line, off + end + 1, length(line) - (off + end) + 1)
    while (substr(line, 1, 1) == " ") {
	line = substr(line, 2, length(line) - 1)
    }
    end = index(line, " ")
    if (end != 0) {
	line = substr(line, 1, end)
    }
    cfnresult = line

    printf("// Automatically generated wrapper for %s/%s\n", gofnname, cfnname)
    printf("//extern %s\n", cfnname)
    printf("func c_%s(%s) %s\n", cfnname, cfnparams, cfnresult)
    printf("func %s(%s) %s%s%s%s{\n",
	   gofnname, gofnparams, gofnresults == "" ? "" : "(", gofnresults,
	   gofnresults == "" ? "" : ")", gofnresults == "" ? "" : " ")

    loc = gofnname "/" cfnname ":"

    split(gofnparams, goargs, ", *")
    split(cfnparams, cargs, ", *")
    args = ""
    carg = 1
    for (goarg = 1; goargs[goarg] != ""; goarg++) {
	if (cargs[carg] == "") {
	    print loc, "not enough C parameters"
	}

	if (args != "") {
	    args = args ", "
	}

	if (split(goargs[goarg], a) != 2) {
	    print loc, "bad parameter:", goargs[goarg] | "cat 1>&2"
	    status = 1
	    next
	}

	goname = a[1]
	gotype = a[2]

	if (split(cargs[carg], a) != 2) {
	    print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
	    status = 1
	    next
	}

	ctype = a[2]

	if (gotype ~ /^\*/) {
	    if (gotype != ctype) {
		print loc, "Go/C pointer type mismatch:", gotype, ctype | "cat 1>&2"
		status = 1
		next
	    }
	    args = args goname
	} else if (gotype == "string") {
	    if (ctype != "*byte") {
		print loc, "Go string not matched to C *byte:", gotype, ctype | "cat 1>&2"
		status = 1
		next
	    }
	    printf("\t_p%d := StringBytePtr(%s)\n", goarg, goname)
	    args = sprintf("%s_p%d", args, goarg)
	} else if (gotype ~ /^\[\](.*)/) {
	    if (ctype !~ /^\*/ || cargs[carg + 1] == "") {
		print loc, "bad C type for slice:", gotype, ctype | "cat 1>&2"
		status = 1
		next
	    }

	    # Convert a slice into a pair of pointer, length.
	    # Don't try to take the address of the zeroth element of a
	    # nil slice.
	    printf("\tvar _p%d %s\n", goarg, ctype)
	    printf("\tif len(%s) > 0 {\n", goname)
	    printf("\t\t_p%d = (%s)(unsafe.Pointer(&%s[0]))\n", goarg, ctype, goname)
	    printf("\t} else {\n")
	    printf("\t\t_p%d = (%s)(unsafe.Pointer(&_zero))\n", goarg, ctype)
	    printf("\t}\n")

	    ++carg
	    if (split(cargs[carg], cparam) != 2) {
		print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
		status = 1
		next
	    }

	    args = sprintf("%s_p%d, %s(len(%s))", args, goarg, cparam[2], goname)
	} else if (gotype == "uintptr" && ctype ~ /^\*/) {
	    args = sprintf("%s(%s)(unsafe.Pointer(%s))", args, ctype, goname)
	} else {
	    args = sprintf("%s%s(%s)", args, ctype, goname)
	}

	carg++
    }

    if (cargs[carg] != "") {
	print loc, "too many C parameters" | "cat 1>&2"
	status = 1
	next
    }

    if (blocking) {
	print "\tEntersyscall()"
    }

    printf("\t")
    if (gofnresults != "") {
	printf("_r := ")
    }
    printf("c_%s(%s)\n", cfnname, args)

    if (gofnresults != "") {
	fields = split(gofnresults, goresults, ", *")
	if (fields > 2) {
	    print loc, "too many Go results" | "cat 1>&2"
	    status = 1
	    next
	}
	usedr = 0
	for (goresult = 1; goresults[goresult] != ""; goresult++) {
	    if (split(goresults[goresult], goparam) != 2) {
		print loc, "bad result:", goresults[goresult] | "cat 1>&2"
		status = 1
		next
	    }

	    goname = goparam[1]
	    gotype = goparam[2]

	    if (goname == "err") {
		if (cfnresult ~ /^\*/) {
		    print "\tif _r == nil {"
		} else {
		    print "\tif _r < 0 {"
		}
		print "\t\terr = GetErrno()"
		print "\t}"
	    } else if (gotype == "uintptr" && cfnresult ~ /^\*/) {
		printf("\t%s = (%s)(unsafe.Pointer(_r))\n", goname, gotype)
	    } else {
		if (usedr) {
		    print loc, "two parameters but no errno parameter" | "cat 1>&2"
		    status = 1
		    next
		}
		printf("\t%s = (%s)(_r)\n", goname, gotype)
		usedr = 1
	    }
	}
    }

    if (blocking) {
	print "\tExitsyscall()"
    }

    if (gofnresults != "") {
	print "\treturn"
    }

    print "}"

    print ""

    next
}

{ next }

END {
    if (status != 0) {
	print "*** mksyscall.awk failed" | "cat 1>&2"
	exit status
    }
}