Translate: fix redundant CRLF in postResponse

####################################################################
# Translate.awk                                                    #
####################################################################

function provides(engineName) {
    Translator[tolower(engineName)] = TRUE
}

function engineMethod(methodName,    engine, translator) {
    if (!Translator[Option["engine"]]) {
        # case-insensitive match engine name
        engine = tolower(Option["engine"])
        if (!Translator[engine]) # fuzzy match engine name
            for (translator in Translator)
                if (Translator[translator] && # there IS such a translator
                    translator ~ "^"engine) {
                    engine = translator
                    break
                }
        if (!Translator[engine]) {
            e("[ERROR] Translator not found: " Option["engine"] "\n"    \
              "        Run '-list-engines / -S' to see a list of available engines.")
            exit 1
        }
        Option["engine"] = engine
    }
    return Option["engine"] methodName
}

# Detect external audio player (mplayer, mpv, mpg123).
function initAudioPlayer() {
    AudioPlayer = !system("mpv" SUPOUT SUPERR) ?
        "mpv --no-config" :
        (!system("mplayer" SUPOUT SUPERR) ?
         "mplayer" :
         (!system("mpg123 --version" SUPOUT SUPERR) ?
          "mpg123" :
          ""))
}

# Detect external speech synthesizer (say, espeak).
function initSpeechSynthesizer() {
    SpeechSynthesizer = !system("say ''" SUPOUT SUPERR) ?
        "say" :
        (!system("espeak ''" SUPOUT SUPERR) ?
         "espeak" :
         "")
}

# Detect external terminal pager (less, more, most).
function initPager() {
    Pager = !system("less -V" SUPOUT SUPERR) ?
        "less" :
        (!system("more -V" SUPOUT SUPERR) ?
         "more" :
         (!system("most" SUPOUT SUPERR) ?
          "most" :
          ""))
}

# Initialize `HttpService`.
function initHttpService(    inet) {
    _Init()

    inet = "inet"
    if (Option["ip-version"])
        inet = inet Option["ip-version"]
    if (Option["proxy"]) {
        match(Option["proxy"], /^(http:\/*)?(([^:]+):([^@]+)@)?([^\/]*):([^\/:]*)/, HttpProxySpec)
        HttpAuthUser = HttpProxySpec[3]
        HttpAuthPass = HttpProxySpec[4]
        HttpAuthCredentials = base64(unquote(HttpAuthUser) ":" HttpAuthPass)
        HttpService = "/" inet "/tcp/0/" HttpProxySpec[5] "/" HttpProxySpec[6]
        HttpPathPrefix = HttpProtocol HttpHost
    } else {
        HttpService = "/" inet "/tcp/0/" HttpHost "/" HttpPort
        HttpPathPrefix = ""
    }

    # How long to wait in milliseconds for IPv6 before trying IPv4
    PROCINFO[HttpService, "READ_TIMEOUT"] = 2000
}

# Pre-process string (URL-encode before send).
function preprocess(text) {
    return quote(text)
}

# Pre-process string (using hexdump to URL-encode everything).
function preprocessByDump(text,    arr, i, len, temp) {
    len = dumpX(text, arr)
    temp = ""
    for (i = 1; i <= len; i++)
        temp = temp "%" arr[i]
    return temp
}

# [OBSOLETE] Is this function still relevant?
# Post-process string (remove any redundant whitespace).
function postprocess(text) {
    text = gensub(/ ([.,;:?!"])/, "\\1", "g", text)
    text = gensub(/(["]) /, "\\1", "g", text)
    return text
}

# Send an HTTP GET request and get response from an online translator.
function getResponse(text, sl, tl, hl,
                     ####
                     content, header, isBody, url, group, status, location) {
    url = _RequestUrl(text, sl, tl, hl)

    header = "GET " url " HTTP/1.1\r\n"           \
        "Host: " HttpHost "\r\n"                  \
        "Connection: close\r\n"
    if (Option["user-agent"])
        header = header "User-Agent: " Option["user-agent"] "\r\n"
    if (Cookie)
        header = header "Cookie: " Cookie "\r\n"
    if (HttpAuthUser && HttpAuthPass)
        # TODO: digest auth
        header = header "Proxy-Authorization: Basic " HttpAuthCredentials "\r\n"

    content = NULLSTR; isBody = 0
    while (1) {
        # separate header and body correctly with CRLF, per RFC 2616
        print (header "\r\n") |& HttpService
        while ((HttpService |& getline) > 0) {
            if (isBody)
                content = content ? content "\n" $0 : $0
            else if (length($0) <= 1)
                isBody = 1
            else { # interesting fields in header
                match($0, /^HTTP[^ ]* ([^ ]*)/, group)
                if (RSTART) status = group[1]
                match($0, /^Location: (.*)/, group)
                if (RSTART) location = squeeze(group[1]) # squeeze the URL!
            }
            l(sprintf("%4s bytes > %s", length($0), $0))
        }
        close(HttpService)

        if (ERRNO == "Connection timed out") {
            w("[WARNING] " ERRNO ". Retrying IPv4 connection.")
            Option["ip-version"] = 4
            initHttpService()
            PROCINFO[HttpService, "READ_TIMEOUT"] = 0
            ERRNO = ""
        } else
            break
    }

    if ((status == "301" || status == "302") && location) {
        content = curl(location)
    } else if (status == "429") {
        e("[ERROR] " ucfirst(Option["engine"]) " did not return results because rate limiting is in effect")
        assert(false, "[ERROR] Rate limiting")
    } else if (status >= "400") {
        e("[ERROR] " ucfirst(Option["engine"]) " returned an error response. HTTP status code: " status)
        assert(false, "[ERROR] Other HTTP error")
    }

    return assert(content, "[ERROR] Null response.")
}

# Send an HTTP POST request and return response from an online translator.
function postResponse(text, sl, tl, hl, type,
                      ####
                      content, contentLength, contentType, group,
                      header, isBody, reqBody, url, status, location, userAgent) {
    url = _PostRequestUrl(text, sl, tl, hl, type)
    contentType = _PostRequestContentType(text, sl, tl, hl, type)
    userAgent = _PostRequestUserAgent(text, sl, tl, hl, type)
    reqBody = _PostRequestBody(text, sl, tl, hl, type)
    if (DumpContentengths[reqBody])
        contentLength = DumpContentengths[reqBody]
    else
        contentLength = DumpContentengths[reqBody] = dump(reqBody, group)

    header = "POST " url " HTTP/1.1\r\n"                  \
        "Host: " HttpHost "\r\n"                          \
        "Connection: close\r\n"                           \
        "Content-Length: " contentLength "\r\n"           \
        "Content-Type: " contentType "\r\n"     # must!
    if (Option["user-agent"] && !userAgent)
        header = header "User-Agent: " Option["user-agent"] "\r\n"
    if (userAgent)
        header = header "User-Agent: " userAgent "\r\n"
    if (Cookie)
        header = header "Cookie: " Cookie "\r\n"
    if (HttpAuthUser && HttpAuthPass)
        # TODO: digest auth
        header = header "Proxy-Authorization: Basic " HttpAuthCredentials "\r\n"

    content = NULLSTR; isBody = 0
    while (1) {
        print (header "\r\n" reqBody) |& HttpService
        while ((HttpService |& getline) > 0) {
            if (isBody)
                content = content ? content "\n" $0 : $0
            else if (length($0) <= 1)
                isBody = 1
            else { # interesting fields in header
                match($0, /^HTTP[^ ]* ([^ ]*)/, group)
                if (RSTART) status = group[1]
                match($0, /^Location: (.*)/, group)
                if (RSTART) location = squeeze(group[1]) # squeeze the URL!
            }
            l(sprintf("%4s bytes > %s", length($0), $0))
        }
        close(HttpService)

        if (ERRNO == "Connection timed out") {
            w("[WARNING] " ERRNO ". Retrying IPv4 connection.")
            Option["ip-version"] = 4
            initHttpService()
            PROCINFO[HttpService, "READ_TIMEOUT"] = 0
            ERRNO = ""
        } else
            break
    }

    if (status == "404") {
        e("[ERROR] 404 Not Found")
        exit 1
    }
    if ((status == "301" || status == "302") && location) {
        url = "https" substr(url, 5) # switch to HTTPS; don't use location!
        content = curlPost(url, reqBody)
    } else if (status == "429") {
        e("[ERROR] " ucfirst(Option["engine"]) " did not return results because rate limiting is in effect")
        assert(false, "[ERROR] Rate limiting")
    } else if (status >= "400") {
        e("[ERROR] " ucfirst(Option["engine"]) " returned an error response. HTTP status code: " status)
        assert(false, "[ERROR] Other HTTP error")
    }

    return content
}

# Print a string (to output file or terminal pager).
function p(string) {
    if (Option["view"]) {
        # For environments that don't have LESS="-R"
        print string | Option["pager"] (Option["pager"] == "less" ? " -R" : "")
        close(Option["pager"] (Option["pager"] == "less" ? " -R" : ""))
    } else
        print string > Option["output"]
}

# Play using a Text-to-Speech engine.
function play(text, tl,    url, status) {
    url = _TTSUrl(text, tl)

    # Don't use getline from pipe here - the same pipe will be run only once for each AWK script!
    status = system(Option["player"] " " parameterize(url) SUPOUT SUPERR)

    if (status)
        w("Voice output isn't available for " getName(tl))

    return status
}

# Download audio from a Text-to-Speech engine.
function download_audio(text, tl,    url, output) {
    url = _TTSUrl(text, tl)

    if (Option["download-audio-as"])
        output = Option["download-audio-as"]
    else
        output = text " [" Option["engine"] "] (" Option["narrator"] ").ts"

    if (url ~ /^\//)
        system("mv -- " parameterize(url) " " parameterize(output))
    else
        curl(url, output)
}

# Get the translation of a string.
function getTranslation(text, sl, tl, hl,
                        isVerbose, toSpeech, returnPlaylist, returnIl) {
    return _Translate(text, sl, tl, hl,
                      isVerbose, toSpeech, returnPlaylist, returnIl)
}

# Translate a file.
function fileTranslation(uri,    group, temp1, temp2) {
    temp1 = Option["input"]
    temp2 = Option["verbose"]

    match(uri, /^file:\/\/(.*)/, group)
    Option["input"] = group[1]
    Option["verbose"] = 0

    translateMain()

    Option["input"] = temp1
    Option["verbose"] = temp2
}

# Start a browser session and translate a web page.
function webTranslation(uri, sl, tl, hl,    temp) {
    temp = _WebTranslateUrl(uri, sl, tl, hl)
    if (temp) {
        p(temp)
        if (Option["browser"] != NONE)
            system(Option["browser"] " " parameterize(temp) SUPOUT SUPERR)
    }
}

# Translate the source text (into all target languages).
function translate(text, inline,
                   ####
                   i, j, playlist, il, saveSortedIn) {

    if (!getCode(Option["hl"])) {
        # Check if host language is supported
        w("[WARNING] Unknown language code: " Option["hl"] ", fallback to English: en")
        Option["hl"] = "en" # fallback to English
    } else if (isRTL(Option["hl"])) {
        # Check if host language is R-to-L
        if (!FriBidi)
            w("[WARNING] " getName(Option["hl"]) " is a right-to-left language, but FriBidi is not found.")
    }

    if (!getCode(Option["sl"])) {
        # Check if source language is supported
        w("[WARNING] Unknown source language code: " Option["sl"])
    } else if (isRTL(Option["sl"])) {
        # Check if source language is R-to-L
        if (!FriBidi)
            w("[WARNING] " getName(Option["sl"]) " is a right-to-left language, but FriBidi is not found.")
    }

    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (i in Option["tl"]) {
        # Non-interactive verbose mode: separator between targets
        if (!Option["interactive"])
            if (Option["verbose"] && i > 1)
                p(prettify("target-seperator", replicate(Option["chr-target-seperator"], Option["width"])))

        if (inline &&
            startsWithAny(text, UriSchemes) == "file://") {
            # translate URL only from command-line parameters (inline)
            fileTranslation(text)
        } else if (inline &&
                   startsWithAny(text, UriSchemes) == "http://" ||
                   startsWithAny(text, UriSchemes) == "https://") {
            # translate URL only from command-line parameters (inline)
            webTranslation(text, Option["sl"], Option["tl"][i], Option["hl"])
        } else {
            if (!Option["no-translate"])
                p(getTranslation(text, Option["sl"], Option["tl"][i], Option["hl"], Option["verbose"], Option["play"] || Option["download-audio"], playlist, il))
            else
                il[0] = Option["sl"] == "auto" ? "en" : Option["sl"]

            if (Option["play"] == 1) {
                if (Option["player"])
                    for (j in playlist)
                        play(playlist[j]["text"], playlist[j]["tl"])
                else if (SpeechSynthesizer)
                    for (j in playlist)
                        print playlist[j]["text"] | SpeechSynthesizer
            } else if (Option["play"] == 2) {
                if (Option["player"])
                    play(text, il[0])
                else if (SpeechSynthesizer)
                    print text | SpeechSynthesizer
            }

            if (Option["download-audio"] == 1) {
                # Download the translation unless used with -sp or -no-trans
                if (Option["play"] != 2 && !Option["no-translate"])
                    download_audio(playlist[length(playlist) - 1]["text"], \
                                   playlist[length(playlist) - 1]["tl"])
                else
                    download_audio(text, il[0])
            }
        }
    }
    PROCINFO["sorted_in"] = saveSortedIn
}

# Translate the source text (from all source languages).
function translates(text, inline,
                    ####
                    i) {
    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (i in Option["sls"]) {
        # Non-interactive verbose mode: separator between sources
        if (!Option["interactive"])
            if (Option["verbose"] && i > 1)
                p(prettify("target-seperator", replicate(Option["chr-target-seperator"], Option["width"])))

        Option["sl"] = Option["sls"][i]
        translate(text, inline)
    }
    PROCINFO["sorted_in"] = saveSortedIn
}

# Read from input and translate each line.
function translateMain(    i, line) {
    if (Option["interactive"])
        prompt()

    if (Option["input"] == STDIN || fileExists(Option["input"])) {
        i = 0
        while (getline line < Option["input"])
            if (line) {
                # Non-interactive verbose mode: separator between sources
                if (!Option["interactive"])
                    if (Option["verbose"] && i++ > 0)
                        p(prettify("source-seperator",
                                   replicate(Option["chr-source-seperator"],
                                             Option["width"])))

                if (Option["interactive"])
                    repl(line)
                else
                    translates(line)
            } else {
                # Non-interactive brief mode: preserve line breaks
                if (!Option["interactive"])
                    if (!Option["verbose"])
                        p(line)
            }
    } else
        e("[ERROR] File not found: " Option["input"])
}

####################################################################
# Translate.awk                                                    #
####################################################################

function provides(engineName) {
    Translator[tolower(engineName)] = TRUE
}

function engineMethod(methodName,    engine, translator) {
    if (!Translator[Option["engine"]]) {
        # case-insensitive match engine name
        engine = tolower(Option["engine"])
        if (!Translator[engine]) # fuzzy match engine name
            for (translator in Translator)
                if (Translator[translator] && # there IS such a translator
                    translator ~ "^"engine) {
                    engine = translator
                    break
                }
        if (!Translator[engine]) {
            e("[ERROR] Translator not found: " Option["engine"] "\n"    \
              "        Run '-list-engines / -S' to see a list of available engines.")
            exit 1
        }
        Option["engine"] = engine
    }
    return Option["engine"] methodName
}

# Detect external audio player (mplayer, mpv, mpg123).
function initAudioPlayer() {
    AudioPlayer = !system("mpv" SUPOUT SUPERR) ?
        "mpv --no-config" :
        (!system("mplayer" SUPOUT SUPERR) ?
         "mplayer" :
         (!system("mpg123 --version" SUPOUT SUPERR) ?
          "mpg123" :
          ""))
}

# Detect external speech synthesizer (say, espeak).
function initSpeechSynthesizer() {
    SpeechSynthesizer = !system("say ''" SUPOUT SUPERR) ?
        "say" :
        (!system("espeak ''" SUPOUT SUPERR) ?
         "espeak" :
         "")
}

# Detect external terminal pager (less, more, most).
function initPager() {
    Pager = !system("less -V" SUPOUT SUPERR) ?
        "less" :
        (!system("more -V" SUPOUT SUPERR) ?
         "more" :
         (!system("most" SUPOUT SUPERR) ?
          "most" :
          ""))
}

# Initialize `HttpService`.
function initHttpService(    inet) {
    _Init()

    inet = "inet"
    if (Option["ip-version"])
        inet = inet Option["ip-version"]
    if (Option["proxy"]) {
        match(Option["proxy"], /^(http:\/*)?(([^:]+):([^@]+)@)?([^\/]*):([^\/:]*)/, HttpProxySpec)
        HttpAuthUser = HttpProxySpec[3]
        HttpAuthPass = HttpProxySpec[4]
        HttpAuthCredentials = base64(unquote(HttpAuthUser) ":" HttpAuthPass)
        HttpService = "/" inet "/tcp/0/" HttpProxySpec[5] "/" HttpProxySpec[6]
        HttpPathPrefix = HttpProtocol HttpHost
    } else {
        HttpService = "/" inet "/tcp/0/" HttpHost "/" HttpPort
        HttpPathPrefix = ""
    }

    # How long to wait in milliseconds for IPv6 before trying IPv4
    PROCINFO[HttpService, "READ_TIMEOUT"] = 2000
}

# Pre-process string (URL-encode before send).
function preprocess(text) {
    return quote(text)
}

# Pre-process string (using hexdump to URL-encode everything).
function preprocessByDump(text,    arr, i, len, temp) {
    len = dumpX(text, arr)
    temp = ""
    for (i = 1; i <= len; i++)
        temp = temp "%" arr[i]
    return temp
}

# [OBSOLETE] Is this function still relevant?
# Post-process string (remove any redundant whitespace).
function postprocess(text) {
    text = gensub(/ ([.,;:?!"])/, "\\1", "g", text)
    text = gensub(/(["]) /, "\\1", "g", text)
    return text
}

# Send an HTTP GET request and get response from an online translator.
function getResponse(text, sl, tl, hl,
                     ####
                     content, header, isBody, url, group, status, location) {
    url = _RequestUrl(text, sl, tl, hl)

    header = "GET " url " HTTP/1.1\r\n"           \
        "Host: " HttpHost "\r\n"                  \
        "Connection: close\r\n"
    if (Option["user-agent"])
        header = header "User-Agent: " Option["user-agent"] "\r\n"
    if (Cookie)
        header = header "Cookie: " Cookie "\r\n"
    if (HttpAuthUser && HttpAuthPass)
        # TODO: digest auth
        header = header "Proxy-Authorization: Basic " HttpAuthCredentials "\r\n"
    header = header "\r\n" # separate header and body correctly, per RFC 2616

    content = NULLSTR; isBody = 0
    while (1) {
        print header |& HttpService
        while ((HttpService |& getline) > 0) {
            if (isBody)
                content = content ? content "\n" $0 : $0
            else if (length($0) <= 1)
                isBody = 1
            else { # interesting fields in header
                match($0, /^HTTP[^ ]* ([^ ]*)/, group)
                if (RSTART) status = group[1]
                match($0, /^Location: (.*)/, group)
                if (RSTART) location = squeeze(group[1]) # squeeze the URL!
            }
            l(sprintf("%4s bytes > %s", length($0), $0))
        }
        close(HttpService)

        if (ERRNO == "Connection timed out") {
            w("[WARNING] " ERRNO ". Retrying IPv4 connection.")
            Option["ip-version"] = 4
            initHttpService()
            PROCINFO[HttpService, "READ_TIMEOUT"] = 0
            ERRNO = ""
        } else
            break
    }

    if ((status == "301" || status == "302") && location) {
        content = curl(location)
    } else if (status == "429") {
        e("[ERROR] " ucfirst(Option["engine"]) " did not return results because rate limiting is in effect")
        assert(false, "[ERROR] Rate limiting")
    } else if (status >= "400") {
        e("[ERROR] " ucfirst(Option["engine"]) " returned an error response. HTTP status code: " status)
        assert(false, "[ERROR] Other HTTP error")
    }

    return assert(content, "[ERROR] Null response.")
}

# Send an HTTP POST request and return response from an online translator.
function postResponse(text, sl, tl, hl, type,
                      ####
                      content, contentLength, contentType, group,
                      header, isBody, reqBody, url, status, location, userAgent) {
    url = _PostRequestUrl(text, sl, tl, hl, type)
    contentType = _PostRequestContentType(text, sl, tl, hl, type)
    userAgent = _PostRequestUserAgent(text, sl, tl, hl, type)
    reqBody = _PostRequestBody(text, sl, tl, hl, type)
    if (DumpContentengths[reqBody])
        contentLength = DumpContentengths[reqBody]
    else
        contentLength = DumpContentengths[reqBody] = dump(reqBody, group)

    header = "POST " url " HTTP/1.1\r\n"                  \
        "Host: " HttpHost "\r\n"                          \
        "Connection: close\r\n"                           \
        "Content-Length: " contentLength "\r\n"           \
        "Content-Type: " contentType "\r\n"     # must!
    if (Option["user-agent"] && !userAgent)
        header = header "User-Agent: " Option["user-agent"] "\r\n"
    if (userAgent)
        header = header "User-Agent: " userAgent "\r\n"
    if (Cookie)
        header = header "Cookie: " Cookie "\r\n"
    if (HttpAuthUser && HttpAuthPass)
        # TODO: digest auth
        header = header "Proxy-Authorization: Basic " HttpAuthCredentials "\r\n"
    header = header "\r\n" # separate header and body correctly, per RFC 2616

    content = NULLSTR; isBody = 0
    while (1) {
        print (header "\r\n" reqBody) |& HttpService
        while ((HttpService |& getline) > 0) {
            if (isBody)
                content = content ? content "\n" $0 : $0
            else if (length($0) <= 1)
                isBody = 1
            else { # interesting fields in header
                match($0, /^HTTP[^ ]* ([^ ]*)/, group)
                if (RSTART) status = group[1]
                match($0, /^Location: (.*)/, group)
                if (RSTART) location = squeeze(group[1]) # squeeze the URL!
            }
            l(sprintf("%4s bytes > %s", length($0), $0))
        }
        close(HttpService)

        if (ERRNO == "Connection timed out") {
            w("[WARNING] " ERRNO ". Retrying IPv4 connection.")
            Option["ip-version"] = 4
            initHttpService()
            PROCINFO[HttpService, "READ_TIMEOUT"] = 0
            ERRNO = ""
        } else
            break
    }

    if (status == "404") {
        e("[ERROR] 404 Not Found")
        exit 1
    }
    if ((status == "301" || status == "302") && location) {
        url = "https" substr(url, 5) # switch to HTTPS; don't use location!
        content = curlPost(url, reqBody)
    } else if (status == "429") {
        e("[ERROR] " ucfirst(Option["engine"]) " did not return results because rate limiting is in effect")
        assert(false, "[ERROR] Rate limiting")
    } else if (status >= "400") {
        e("[ERROR] " ucfirst(Option["engine"]) " returned an error response. HTTP status code: " status)
        assert(false, "[ERROR] Other HTTP error")
    }

    return content
}

# Print a string (to output file or terminal pager).
function p(string) {
    if (Option["view"]) {
        # For environments that don't have LESS="-R"
        print string | Option["pager"] (Option["pager"] == "less" ? " -R" : "")
        close(Option["pager"] (Option["pager"] == "less" ? " -R" : ""))
    } else
        print string > Option["output"]
}

# Play using a Text-to-Speech engine.
function play(text, tl,    url, status) {
    url = _TTSUrl(text, tl)

    # Don't use getline from pipe here - the same pipe will be run only once for each AWK script!
    status = system(Option["player"] " " parameterize(url) SUPOUT SUPERR)

    if (status)
        w("Voice output isn't available for " getName(tl))

    return status
}

# Download audio from a Text-to-Speech engine.
function download_audio(text, tl,    url, output) {
    url = _TTSUrl(text, tl)

    if (Option["download-audio-as"])
        output = Option["download-audio-as"]
    else
        output = text " [" Option["engine"] "] (" Option["narrator"] ").ts"

    if (url ~ /^\//)
        system("mv -- " parameterize(url) " " parameterize(output))
    else
        curl(url, output)
}

# Get the translation of a string.
function getTranslation(text, sl, tl, hl,
                        isVerbose, toSpeech, returnPlaylist, returnIl) {
    return _Translate(text, sl, tl, hl,
                      isVerbose, toSpeech, returnPlaylist, returnIl)
}

# Translate a file.
function fileTranslation(uri,    group, temp1, temp2) {
    temp1 = Option["input"]
    temp2 = Option["verbose"]

    match(uri, /^file:\/\/(.*)/, group)
    Option["input"] = group[1]
    Option["verbose"] = 0

    translateMain()

    Option["input"] = temp1
    Option["verbose"] = temp2
}

# Start a browser session and translate a web page.
function webTranslation(uri, sl, tl, hl,    temp) {
    temp = _WebTranslateUrl(uri, sl, tl, hl)
    if (temp) {
        p(temp)
        if (Option["browser"] != NONE)
            system(Option["browser"] " " parameterize(temp) SUPOUT SUPERR)
    }
}

# Translate the source text (into all target languages).
function translate(text, inline,
                   ####
                   i, j, playlist, il, saveSortedIn) {

    if (!getCode(Option["hl"])) {
        # Check if host language is supported
        w("[WARNING] Unknown language code: " Option["hl"] ", fallback to English: en")
        Option["hl"] = "en" # fallback to English
    } else if (isRTL(Option["hl"])) {
        # Check if host language is R-to-L
        if (!FriBidi)
            w("[WARNING] " getName(Option["hl"]) " is a right-to-left language, but FriBidi is not found.")
    }

    if (!getCode(Option["sl"])) {
        # Check if source language is supported
        w("[WARNING] Unknown source language code: " Option["sl"])
    } else if (isRTL(Option["sl"])) {
        # Check if source language is R-to-L
        if (!FriBidi)
            w("[WARNING] " getName(Option["sl"]) " is a right-to-left language, but FriBidi is not found.")
    }

    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (i in Option["tl"]) {
        # Non-interactive verbose mode: separator between targets
        if (!Option["interactive"])
            if (Option["verbose"] && i > 1)
                p(prettify("target-seperator", replicate(Option["chr-target-seperator"], Option["width"])))

        if (inline &&
            startsWithAny(text, UriSchemes) == "file://") {
            # translate URL only from command-line parameters (inline)
            fileTranslation(text)
        } else if (inline &&
                   startsWithAny(text, UriSchemes) == "http://" ||
                   startsWithAny(text, UriSchemes) == "https://") {
            # translate URL only from command-line parameters (inline)
            webTranslation(text, Option["sl"], Option["tl"][i], Option["hl"])
        } else {
            if (!Option["no-translate"])
                p(getTranslation(text, Option["sl"], Option["tl"][i], Option["hl"], Option["verbose"], Option["play"] || Option["download-audio"], playlist, il))
            else
                il[0] = Option["sl"] == "auto" ? "en" : Option["sl"]

            if (Option["play"] == 1) {
                if (Option["player"])
                    for (j in playlist)
                        play(playlist[j]["text"], playlist[j]["tl"])
                else if (SpeechSynthesizer)
                    for (j in playlist)
                        print playlist[j]["text"] | SpeechSynthesizer
            } else if (Option["play"] == 2) {
                if (Option["player"])
                    play(text, il[0])
                else if (SpeechSynthesizer)
                    print text | SpeechSynthesizer
            }

            if (Option["download-audio"] == 1) {
                # Download the translation unless used with -sp or -no-trans
                if (Option["play"] != 2 && !Option["no-translate"])
                    download_audio(playlist[length(playlist) - 1]["text"], \
                                   playlist[length(playlist) - 1]["tl"])
                else
                    download_audio(text, il[0])
            }
        }
    }
    PROCINFO["sorted_in"] = saveSortedIn
}

# Translate the source text (from all source languages).
function translates(text, inline,
                    ####
                    i) {
    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (i in Option["sls"]) {
        # Non-interactive verbose mode: separator between sources
        if (!Option["interactive"])
            if (Option["verbose"] && i > 1)
                p(prettify("target-seperator", replicate(Option["chr-target-seperator"], Option["width"])))

        Option["sl"] = Option["sls"][i]
        translate(text, inline)
    }
    PROCINFO["sorted_in"] = saveSortedIn
}

# Read from input and translate each line.
function translateMain(    i, line) {
    if (Option["interactive"])
        prompt()

    if (Option["input"] == STDIN || fileExists(Option["input"])) {
        i = 0
        while (getline line < Option["input"])
            if (line) {
                # Non-interactive verbose mode: separator between sources
                if (!Option["interactive"])
                    if (Option["verbose"] && i++ > 0)
                        p(prettify("source-seperator",
                                   replicate(Option["chr-source-seperator"],
                                             Option["width"])))

                if (Option["interactive"])
                    repl(line)
                else
                    translates(line)
            } else {
                # Non-interactive brief mode: preserve line breaks
                if (!Option["interactive"])
                    if (!Option["verbose"])
                        p(line)
            }
    } else
        e("[ERROR] File not found: " Option["input"])
}


optimization

optimization

# sameasFromNT
#

$2 == "<http://purl.org/dc/terms/isReferencedBy>" || $2 == "<http://www.w3.org/2002/07/owl#sameAs>" {
   print
}

# sameasFromNT
#

$2 == "<http://www.w3.org/2002/07/owl#sameAs>" {
   print
}
$2 == "<http://purl.org/dc/terms/isReferencedBy>" {
   print
}


copyright message added

copyright message added

#!/usr/bin/gawk -f
#
# create dxf file from space separated coordinate list
# Zoltan Siki siki.zoltan@epito.bme.hu
# usage:
#        gawk -f coo2dxf.awk coodinate_list > dxf_file

BEGIN { FS="[ ]";
    # minimal DXF header
    print "  0";
    print "SECTION";
    print "  2";
    print "ENTITIES"
}
{ # for each input line
    print "  0\nTEXT\n  8\nPTEXT\n 10"; # point id text & layer
    print $2 + 0.1;   # text position
    print " 20";
    print $3 - 0.25;
    print " 30\n0.00\n 40\n0.5\n  1";
    print $1
    print " 50\n0.00"
    print "  0\nPOINT\n  8\nPOINT";  # point entity & layer
    print " 10";  # position
    print $2;
    print " 20";
    print $3;
    print " 30";
    print $4
}
END {
    # footer for DXF
    print "  0\nENDSEC\n  0\nEOF"
}


added phi link

added phi link

function treeInfo()
{

  htmlHeader("Plant information", 400) ;

  apfam_load() ;
  loadColors();

  FS="|";
  while ((getline < "data/aa-tree.csv") > 0)
	{
	  if ($1 == f["tag"])
		{
		  print "
" $4 "
";
		  print "
" ;
		  if (apfam[$3] == "") print "
Family : " substr($3,1,1) tolower(substr($3,2)) "          Φ
" ;
		  else print "
Family : " substr($3,1,1) tolower(substr($3,2)) "          Φ
" ;
		  if ($6 != "") print "
Common name : " $6 "
" ;
		  if ($10 != "") print "
Section : " $10 "
" ;
		  if ($11 != "") print "
Collection : " $11 "
" ;
		  if ($8 > 0) print "
Diameter : " int($8) " " $9 "
" ;
		  # print "
Grid : " $12 "
" ;
		  print "
Tag : " $1 "
" ;
		  split($4,nam," ");
		  print "
Observations of this plant
" ;
		  print "
Images of this taxon
";
		  print "
Wood structure
"; # no point in passing spp since all spp in a genus are returned
		  print "
More info...
";
		  print "
";
		  print "";
		  print "
[ observe | map it | directions | home ]
" ;

		  break;
		}
	}
}

function apfam_load ()
{
  fams = "lamialesweb.htm#Acanthaceae|Acanthaceae malpighialesweb.htm#Achariaceae|Achariaceae caryophyllalesweb.htm#Achatocarpaceae|Achatocarpaceae acoralesweb.htm#Acoraceae|Acoraceae ericalesweb.htm#Actinidiaceae|Actinidiaceae dipsacalesweb.htm#Adoxaceae|Adoxaceae berberidopsidalesweb.html#Aextoxicaceae|Aextoxicaceae caryophyllalesweb.htm#Aizoaceae|Aizoaceae brassicalesweb.htm#Akaniaceae|Akaniaceae alismatalesweb.htm#Alismataceae|Alismataceae asteralesweb.htm#Alseuosmiaceae|Alseuosmiaceae lilialesweb.htm#Alstroemeriaceae|Alstroemeriaceae saxifragalesweb.htm#Altingiaceae|Altingiaceae myrtalesweb2.htm#Alzateaceae|Alzateaceae caryophyllalesweb.htm#Amaranthaceae|Amaranthaceae asparagalesweb.htm#Amaryllidaceae|Amaryllidaceae amborellalesweb2.htm#Amborellaceae|Amborellaceae  caryophyllalesweb.htm#Anacampseros|Anacampserotaceae sapindalesweb.htm#Anacardiaceae|Anacardiaceae poalesweb.htm#Anarthriaceae|Anarthriaceae caryophyllalesweb.htm#Ancistrocladaceae|Ancistrocladaceae cucurbitalesweb.htm#Anisophylleaceae|Anisophylleaceae magnolialesweb.htm#Annonaceae|Annonaceae saxifragalesweb.htm#Aphanopetalaceae|Aphanopetalaceae crossosomatalesweb.htm#Aphloiaceae|Aphloiaceae apialesweb.htm#Apiaceae|Apiaceae gentianalesweb.htm#Apocynaceae|Apocynaceae cucurbitalesweb.htm#Apodanthaceae|Apodanthaceae alismatalesweb.htm#Aponogetonaceae|Aponogetonaceae santalalesweb2.htm#Aptandraceae|Aptandraceae aquifolialesweb2.htm#Aquifoliaceae|Aquifoliaceae alismatalesweb.htm#Araceae|Araceae apialesweb.htm#Araliaceae|Araliaceae conifers.html#Araucariaceae|Araucariaceae arecalesweb.htm#Arecaceae|Arecaceae asteralesweb.htm#Argophyllaceae|Argophyllaceae piperalesweb2.htm#Aristolochiaceae|Aristolochiaceae asparagalesweb.htm#Asparagaceae|Asparagaceae asparagalesweb.htm#Asteliaceae|Asteliaceae asteralesweb.htm#Asteraceae|Asteraceae caryophyllalesweb.htm#Asteropeiaceae|Asteropeiaceae lauralesweb.htm#Atherospermataceae|Atherospermataceae austrobaileyalesweb.htm#Austrobaileyaceae|Austrobaileyaceae santalalesweb2.htm#Balanophoraceae|Balanophoraceae ericalesweb.htm#Balsaminaceae|Balsaminaceae caryophyllalesweb.htm#Barbeuiaceae|Barbeuiaceae rosalesweb.htm#Barbeyaceae|Barbeyaceae caryophyllalesweb.htm#Basellaceae|Basellaceae brassicalesweb.htm#Bataceae|Bataceae cucurbitalesweb.htm#Begoniaceae|Begoniaceae ranunculalesweb.htm#Berberidaceae|Berberidaceae berberidopsidalesweb.html#Berberidopsidaceae|Berberidopsidaceae fagalesweb.htm#Betulaceae|Betulaceae sapindalesweb.htm#Biebersteiniaceae|Biebersteiniaceae lamialesweb.htm#Bignoniaceae|Bignoniaceae malvalesweb.htm#CocBixDie|Bixaceae asparagalesweb.htm#Blandfordiaceae|Blandfordiaceae malpighialesweb.htm#Bonnetiaceae|Bonnetiaceae gentianalesweb.htm#Boraginaceae|Boraginaceae asparagalesweb.htm#Boryaceae|Boryaceae brassicalesweb.htm#Brassicoideae|Brassicaceae poalesweb.htm#Bromeliaceae|Bromeliaceae oxalidalesweb.htm#Brunelliaceae|Brunelliaceae brunialesweb.htm#Bruniaceae|Bruniaceae dioscorealesweb.htm#Burmanniaceae|Burmanniaceae sapindalesweb.htm#Burseraceae|Burseraceae alismatalesweb.htm#Butomaceae|Butomaceae buxalesweb.htm#Buxaceae|Buxaceae lamialesweb.htm#Byblidaceae|Byblidaceae caryophyllalesweb.htm#Cactaceae|Cactaceae lamialesweb.htm#Calceolariaceae|Calceolariaceae malpighialesweb.htm#Calophyllaceae|Calophyllaceae lauralesweb.htm#Calycanthaceae|Calycanthaceae asteralesweb.htm#Calyceraceae|Calyceraceae asteralesweb.htm#Campanulaceae|Campanulaceae lilialesweb.htm#Campynemataceae|Campynemataceae canellalesweb.htm#Canellaceae|Canellaceae rosalesweb.htm#Cannabaceae|Cannabaceae zingiberalesweb.htm#Cannaceae|Cannaceae brassicalesweb.htm#Capparoideae|Capparaceae dipsacalesweb.htm#Caprifoliaceae|Caprifoliaceae aquifolialesweb2.htm#Cardiopteridaceae|Cardiopteridaceae brassicalesweb.htm#Caricaceae|Caricaceae lamialesweb.htm#Carlemanniaceae|Carlemanniaceae malpighialesweb.htm#Caryocaraceae|Caryocaraceae caryophyllalesweb.htm#Caryophyllaceae|Caryophyllaceae fagalesweb.htm#Casuarinaceae|Casuarinaceae celastralesweb.html#Celastraceae|Celastraceae poalesweb.htm#Centrolepidaceae|Centrolepidaceae malpighialesweb.htm#Centroplacaceae|Centroplacaceae oxalidalesweb.htm#Cephalotaceae|Cephalotaceae ceratophyllalesweb.htm#Ceratophyllaceae|Ceratophyllaceae saxifragalesweb.htm#Cercidiphyllaceae|Cercidiphyllaceae chloranthalesweb.htm#Chloranthaceae|Chloranthaceae malpighialesweb.htm#Chrysobalanaceae|Chrysobalanaceae ranunculalesweb.htm#Circaeasteraceae|Circaeasteraceae malvalesweb.htm#Cistaceae|Cistaceae brassicalesweb.htm#Cleomoideae|Cleomaceae ericalesweb.htm#Clethraceae|Clethraceae malpighialesweb.htm#Clusiaceae|Clusiaceae lilialesweb.htm#Colchicaceae|Colchicaceae brunialesweb.htm#Columelliaceae|Columelliaceae myrtalesweb2.htm#Combretaceae|Combretaceae commelinalesweb.htm#Commelinaceae|Commelinaceae oxalidalesweb.htm#Connaraceae|Connaraceae solanalesweb.htm#Convolvulaceae|Convolvulaceae cucurbitalesweb.htm#Coriariaceae|Coriariaceae cornalesweb.htm#Cornaceae|Cornaceae lilialesweb.htm#Corsiaceae|Corsiaceae cucurbitalesweb.htm#Corynocarpaceae|Corynocarpaceae zingiberalesweb.htm#Costaceae|Costaceae santalalesweb2.htm#Coulaceae|Coulaceae saxifragalesweb.htm#Crassulaceae|Crassulaceae crossosomatalesweb.htm#Crossosomataceae|Crossosomataceae myrtalesweb2.htm#Crypteroniaceae|Crypteroniaceae malpighialesweb.htm#Ctenolophonaceae|Ctenolophonaceae cucurbitalesweb.htm#Cucurbitaceae|Cucurbitaceae oxalidalesweb.htm#Cunoniaceae|Cunoniaceae conifers.html#Cupressaceae|Cupressaceae cornalesweb.htm#Curtisiaceae|Curtisiaceae Cycadales.html#Cycadaceae|Cycadaceae pandanalesweb.htm#Cyclanthaceae|Cyclanthaceae alismatalesweb.htm#Cymodoceaceae|Cymodoceaceae saxifragalesweb.htm#Cynomoriaceae|Cynomoriaceae poalesweb.htm#Cyperaceae|Cyperaceae ericalesweb.htm#Cyrillaceae|Cyrillaceae malvalesweb.htm#Cytinaceae|Cytinaceae saxifragalesweb.htm#Daphniphyllaceae|Daphniphyllaceae arecalesweb.htm#Dasypogonaceae|Dasypogonaceae  cucurbitalesweb.htm#Datiscaceae|Datiscaceae magnolialesweb.htm#Degeneriaceae|Degeneriaceae ericalesweb.htm#Diapensiaceae|Diapensiaceae malpighialesweb.htm#Dichapetalaceae|Dichapetalaceae caryophyllalesweb.htm#Didiereaceae|Didiereaceae buxalesweb.htm#Didymelaceae|Didymelaceae dipsacalesweb.htm#Diervillaceae|Diervillaceae dillenialesweb.html#Dilleniaceae|Dilleniaceae caryophyllalesweb.htm#Dioncophyllaceae|Dioncophyllaceae dioscorealesweb.htm#Dioscoreaceae|Dioscoreaceae huertealesweb.htm#Dipentodontaceae|Dipentodontaceae dipsacalesweb.htm#Dipsacaceae|Dipsacaceae malvalesweb.htm#Dipterocarpaceae|Dipterocarpaceae rosalesweb.htm#Dirachmaceae|Dirachmaceae asparagalesweb.htm#Doryanthaceae|Doryanthaceae caryophyllalesweb.htm#Droseraceae|Droseraceae caryophyllalesweb.htm#Drosophyllaceae|Drosophyllaceae poalesweb.htm#Ecdeiocoleaceae|Ecdeiocoleaceae rosalesweb.htm#Elaeagnaceae|Elaeagnaceae oxalidalesweb.htm#Elaeocarpaceae|Elaeocarpaceae malpighialesweb.htm#Elatinaceae|Elatinaceae brassicalesweb.htm#Emblingiaceae|Emblingiaceae gnetales.html#Ephedraceae|Ephedraceae ericalesweb.htm#Ericaceae|Ericaceae poalesweb.htm#Eriocaulaceae|Eriocaulaceae santalalesweb2.htm#Erythropalaceae|Erythropalaceae malpighialesweb.htm#Erythroxylaceae|Erythroxylaceae Escalloniales.html#Escalloniaceae|Escalloniaceae garryalesweb.htm#Eucommiaceae|Eucommiaceae malpighialesweb.htm#Euphorbiaceae|Euphorbiaceae malpighialesweb.htm#Euphroniaceae|Euphroniaceae magnolialesweb.htm#Eupomatiaceae|Eupomatiaceae ranunculalesweb.htm#Eupteleaceae|Eupteleaceae fagalesweb.htm#Fagaceae|Fagaceae poalesweb.htm#Flagellariaceae|Flagellariaceae ericalesweb.htm#Fouquieriaceae|Fouquieriaceae geranialesweb.htm#Francoaceae|Francoaceae caryophyllalesweb.htm#Frankeniaceae|Frankeniaceae garryalesweb.htm#Garryaceae|Garryaceae crossosomatalesweb.htm#Geissolomataceae|Geissolomataceae gentianalesweb.htm#Gelsemiaceae|Gelsemiaceae gentianalesweb.htm#Gentianaceae|Gentianaceae geranialesweb.htm#Geraniaceae|Geraniaceae huertealesweb.htm#Gerrardinaceae|Gerrardinaceae lamialesweb.htm#Gesneriaceae|Gesneriaceae ginkgoales.html#Ginkgoaceae|Ginkgoaceae caryophyllalesweb.htm#Gisekiaceae|Gisekiaceae gnetales.html#Gnetaceae|Gnetaceae lauralesweb.htm#Gomortegaceae|Gomortegaceae asteralesweb.htm#Goodeniaceae|Goodeniaceae malpighialesweb.htm#Goupiaceae|Goupiaceae apialesweb.htm#Griseliniaceae|Griseliniaceae saxifragalesweb.htm#Grossulariaceae|Grossulariaceae cornalesweb.htm#Grubbiaceae|Grubbiaceae crossosomatalesweb.htm#Guametalaceae|Guamatelaceae gunneralesweb.htm#Gunneraceae|Gunneraceae brassicalesweb.htm#Gyrostemonaceae|Gyrostemonaceae commelinalesweb.htm#Haemodoraceae|Haemodoraceae caryophyllalesweb.htm#Halophytaceae|Halophytaceae saxifragalesweb.htm#Haloragaceae|Haloragaceae saxifragalesweb.htm#Hamamelidaceae|Hamamelidaceae commelinalesweb.htm#Hanguanaceae|Hanguanaceae zingiberalesweb.htm#Heliconiaceae|Heliconiaceae aquifolialesweb2.htm#Helwingiaceae|Helwingiaceae lauralesweb.htm#Hernandiaceae|Hernandiaceae magnolialesweb.htm#Himantandraceae|Himantandraceae oxalidalesweb.htm#Huaceae|Huaceae malpighialesweb.htm#Humiriaceae|Humiriaceae nymphaealesweb.htm#Hydatellaceae|Hydatellaceae piperalesweb2.htm#Hydnoraceae|Hydnoraceae cornalesweb.htm#Hydrangeaceae|Hydrangeaceae alismatalesweb.htm#Hydrocharitaceae|Hydrocharitaceae solanalesweb.htm#Hydroleaceae|Hydroleaceae cornalesweb.htm#Hydrostachyaceae|Hydrostachyaceae malpighialesweb.htm#Hypericaceae|Hypericaceae asparagalesweb.htm#Hypoxidaceae|Hypoxidaceae asparagalesweb.htm#Iridaceae|Iridaceae malpighialesweb.htm#Irvingiaceae|Irvingiaceae saxifragalesweb.htm#Iteaceae|Iteaceae asparagalesweb.htm#Ixioliriaceae|Ixiolirionaceae malpighialesweb.htm#Ixonanthaceae|Ixonanthaceae poalesweb.htm#Joinvilleaceae|Joinvilleaceae fagalesweb.htm#Juglandaceae|Juglandaceae poalesweb.htm#Juncaceae|Juncaceae alismatalesweb.htm#Juncaginaceae|Juncaginaceae sapindalesweb.htm#Kirkiaceae|Kirkiaceae brassicalesweb.htm#Koeberliniaceae|Koeberliniaceae zygophyllalesweb.htm#Krameriaceae|Krameriaceae malpighialesweb.htm#Lacistemataceae|Lacistemataceae lamialesweb.htm#Lamiaceae|Lamiaceae asparagalesweb.htm#Lanariaceae|Lanariaceae ranunculalesweb.htm#Lardizabalaceae|Lardizabalaceae lauralesweb.htm#Lauraceae|Lauraceae ericalesweb.htm#Lecythidaceae|Lecythidaceae geranialesweb.htm#Ledocarpaceae|Ledocarpaceae lamialesweb.htm#Lentibulariaceae|Lentibulariaceae celastralesweb.html#Lepidobotryaceae|Lepidobotryaceae lilialesweb.htm#Liliaceae|Liliaceae Caryophyllalesweb.htm#Limeaceae|Limeaceae brassicalesweb.htm#Limnanthaceae|Limnanthaceae malpighialesweb.htm#Linaceae|Linaceae lamialesweb.htm#Linderniaceae|Linderniaceae dipsacalesweb.htm#Linnaeaceae|Linnaeaceae cornalesweb.htm#Loasaceae|Loasaceae gentianalesweb.htm#Loganiaceae|Loganiaceae caryophyllalesweb.htm#Lophiocarpaceae|Lophiocarpaceae malpighialesweb.htm#Lophopyxidaceae|Lophopyxidaceae santalalesweb2.htm#Loranthaceae|Loranthaceae zingiberalesweb.htm#Lowiaceae|Lowiaceae myrtalesweb2.htm#Lythraceae|Lythraceae magnolialesweb.htm#Magnoliaceae|Magnoliaceae malpighialesweb.htm#Malpighiaceae|Malpighiaceae malvalesweb.htm#Malvaceae|Malvaceae zingiberalesweb.htm#Marantaceae|Marantaceae ericalesweb.htm#Marcgraviaceae|Marcgraviaceae lamialesweb.htm#Martyniaceae|Martyniaceae alismatalesweb.htm#Maundiaceae|Maundiaceae poalesweb.htm#Mayacaceae|Mayacaceae lilialesweb.htm#Melanthiaceae|Melanthiaceae myrtalesweb2.htm#Melastomataceae|Melastomataceae sapindalesweb.htm#Meliaceae|Meliaceae geranialesweb.htm#Melianthaceae|Melianthaceae ranunculalesweb.htm#Menispermaceae|Menispermaceae asteralesweb.htm#Menyanthaceae|Menyanthaceae garryalesweb.htm#Metteniusaceae|Metteniusaceae caryophyllalesweb.htm#Microteaceae|Microteaceae santalalesweb2.htm#Misodendraceae|Misodendraceae ericalesweb.htm#Mitrastemonaceae|Mitrastemonaceae caryophyllalesweb.htm#Molluginaceae|Molluginaceae lauralesweb.htm#Monimiaceae|Monimiaceae caryophyllalesweb.htm#Montiaceae|Montiaceae solanalesweb.htm#Montiniaceae|Montiniaceae rosalesweb.htm#Moraceae|Moraceae dipsacalesweb.htm#Morinaceae|Morinaceae brassicalesweb.htm#Moringaceae|Moringaceae malvalesweb.htm#Muntingiaceae|Muntingiaceae zingiberalesweb.htm#Musaceae|Musaceae apialesweb.htm#Myodocarpaceae|Myodocarpaceae fagalesweb.htm#Myricaceae|Myricaceae magnolialesweb.htm#Myristicaceae|Myristicaceae gunneralesweb.htm#Myrothamnaceae|Myrothamnaceae myrtalesweb2.htm#Myrtaceae|Myrtaceae dioscorealesweb.htm#Nartheciaceae|Nartheciaceae protealesweb.html#Nelumbonaceae|Nelumbonaceae caryophyllalesweb.htm#Nepenthaceae|Nepenthaceae malvalesweb.htm#Neuradaceae|Neuradaceae sapindalesweb.htm#Nitrariaceae|Nitrariaceae fagalesweb.htm#Nothofagaceae|Nothofagaceae caryophyllalesweb.htm#Nyctaginaceae|Nyctaginaceae nymphaealesweb.htm#Nymphaeaceae|Nymphaeaceae malpighialesweb.htm#Ochnaceae|Ochnaceae santalalesweb2.htm#Octonemaceae|Octonemaceae santalalesweb2.htm#Olacaceae|Olacaceae lamialesweb.htm#Oleaceae|Oleaceae myrtalesweb2.htm#Onagraceae|Onagraceae garryalesweb.htm#Oncothecaceae|Oncothecaceae santalalesweb2.htm#Opiliaceae|Opiliaceae asparagalesweb.htm#Orchidaceae|Orchidaceae lamialesweb.htm#Orobanchaceae|Orobanchaceae oxalidalesweb.htm#Oxalidaceae|Oxalidaceae saxifragalesweb.htm#Paeoniaceae|Paeoniaceae malpighialesweb.htm#Pandaceae|Pandaceae pandanalesweb.htm#Pandanaceae|Pandanaceae ranunculalesweb.htm#Papaveraceae|Papaveraceae Paracryphiales.html#Paracryphiaceae|Paracryphiaceae malpighialesweb.htm#Passifloraceae|Passifloraceae lamialesweb.htm#Paulowniaceae |Paulowniaceae lamialesweb.htm#Pedaliaceae|Pedaliaceae myrtalesweb2.htm#Penaeaceae|Penaeaceae apialesweb.htm#Pennantiaceae|Pennantiaceae brassicalesweb.htm#Pentadiplandraceae|Pentadiplandraceae asteralesweb.htm#Pentaphragmataceae|Pentaphragmataceae ericalesweb.htm#Pentaphylacaceae|Pentaphylacaceae saxifragalesweb.htm#Penthoraceae|Penthoraceae malpighialesweb.htm#Peraceae|Peraceae saxifragalesweb.htm#Peridiscaceae|Peridiscaceae huertealesweb.htm#Petenaeaceae|Petenaeaceae lilialesweb.htm#Petermanniaceae|Petermanniaceae petrosavialesweb.htm#Petrosaviaceae|Petrosaviaceae asteralesweb.htm#Phellinaceae|Phellinaceae lilialesweb.htm#Philesiaceae|Philesiaceae commelinalesweb.htm#Philydraceae|Philydraceae lamialesweb.htm#Phrymaceae|Phrymaceae malpighialesweb.htm#Phyllanthaceae|Phyllanthaceae aquifolialesweb2.htm#Phyllonomaceae|Phyllonomaceae caryophyllalesweb.htm#Physenaceae|Physenaceae caryophyllalesweb.htm#Phytolaccaceae|Phytolaccaceae picramnialesweb.html#Picramniaceae|Picramniaceae malpighialesweb.htm#Picrodendraceae|Picrodendraceae conifers.html#Pinaceae|Pinaceae piperalesweb2.htm#Piperaceae|Piperaceae apialesweb.htm#Pittosporaceae|Pittosporaceae lamialesweb.htm#Plantaginaceae|Plantaginaceae protealesweb.html#Platanaceae|Platanaceae lamialesweb.htm#Plocospermataceae|Plocospermataceae caryophyllalesweb.htm#Plumbaginaceae|Plumbaginaceae poalesweb.htm#Poaceae|Poaceae conifers.html#Podocarpaceae|Podocarpaceae malpighialesweb.htm#Podostemaceae|Podostemaceae ericalesweb.htm#Polemoniaceae|Polemoniaceae fabalesweb.htm#Polygalaceae|Polygalaceae caryophyllalesweb.htm#Polygonaceae|Polygonaceae commelinalesweb.htm#Pontederiaceae|Pontederiaceae caryophyllalesweb.htm#Portulacaceae|Portulacaceae alismatalesweb.htm#Posidoniaceae|Posidoniaceae alismatalesweb.htm#Potamogetonaceae|Potamogetonaceae ericalesweb.htm#Primulaceae|Primulaceae protealesweb.html#Proteaceae|Proteaceae malpighialesweb.htm#Putranjivaceae|Putranjivaceae fabalesweb.htm#Quillajaceae|Quillajaceae ranunculalesweb.htm#Ranunculaceae|Ranunculaceae poalesweb.htm#Rapateaceae |Rapateaceae brassicalesweb.htm#Resedaceae|Resedaceae poalesweb.htm#Restionaceae|Restionaceae caryophyllalesweb.htm#Rhabdodendraceae|Rhabdodendraceae rosalesweb.htm#Rhamnaceae|Rhamnaceae lilialesweb.htm#Rhipogonaceae|Rhipogonaceae malpighialesweb.htm#Rhizophoraceae|Rhizophoraceae fagalesweb.htm#Rhoipteleaceae|Rhoipteleaceae ericalesweb.htm#Roridulaceae|Roridulaceae rosalesweb.htm#Rosaceae|Rosaceae asteralesweb.htm#Rousseaceae|Rousseaceae gentianalesweb.htm#Rubiaceae|Rubiaceae alismatalesweb.htm#Ruppiaceae|Ruppiaceae sapindalesweb.htm#Rutaceae|Rutaceae Sabiales.html#Sabiaceae|Sabiaceae malpighialesweb.htm#Salicaceae|Salicaceae brassicalesweb.htm#Salvadoraceae|Salvadoraceae santalalesweb2.htm#Santalaceae|Santalaceae sapindalesweb.htm#Sapindaceae|Sapindaceae ericalesweb.htm#Sapotaceae|Sapotaceae caryophyllalesweb.htm#Sarcobataceae|Sarcobataceae malvalesweb.htm#Sarcolaenaceae|Sarcolaenaceae ericalesweb.htm#Sarraceniaceae|Sarraceniaceae piperalesweb2.htm#Saururaceae|Saururaceae saxifragalesweb.htm#Saxifragaceae|Saxifragaceae alismatalesweb.htm#Scheuchzeriaceae|Scheuchzeriaceae austrobaileyalesweb.htm#Schisandraceae|Schisandraceae lamialesweb.htm#Schlegeliaceae|Schlegeliaceae santalalesweb2.htm#Schoepfiaceae|Schoepfiaceae conifers.html#Sciadopityaceae|Sciadopityaceae lamialesweb.htm#Scrophulariaceae|Scrophulariaceae brassicalesweb.htm#Setchellanthaceae|Setchellanthaceae sapindalesweb.htm#Simaroubaceae|Simaroubaceae caryophyllalesweb.htm#Simmondsiaceae|Simmondsiaceae lauralesweb.htm#Siparunaceae|Siparunaceae ericalesweb.htm#Sladeniaceae|Sladeniaceae lilialesweb.htm#Smilacaceae|Smilacaceae solanalesweb.htm#Solanaceae|Solanaceae malvalesweb.htm#Sphaerosepalaceae|Sphaerosepalaceae solanalesweb.htm#Sphenocleaceae|Sphenocleaceae crossosomatalesweb.htm#Stachyuraceae|Stachyuraceae crossosomatalesweb.htm#Staphyleaceae|Staphyleaceae caryophyllalesweb.htm#Stegnospermataceae|Stegnospermataceae pandanalesweb.htm#Stemonaceae|Stemonaceae aquifolialesweb2.htm#Stemonuraceae|Stemonuraceae lamialesweb.htm#Stilbaceae|Stilbaceae brassicalesweb.htm#Stixaceae|Stixaceae crossosomatalesweb.htm#Strasburgeriaceae|Strasburgeriaceae zingiberalesweb.htm#Strelitziaceae|Strelitziaceae santalalesweb2.htm#Strombosiaceae|Strombosiaceae asteralesweb.htm#Stylidiaceae|Stylidiaceae ericalesweb.htm#Styracaceae|Styracaceae fabalesweb.htm#Surianaceae|Surianaceae ericalesweb.htm#Symplocaceae|Symplocaceae caryophyllalesweb.htm#Talinaceae|Talinaceae caryophyllalesweb.htm#Tamaricaceae|Tamaricaceae huertealesweb.htm#Tapisciaceae|Tapisciaceae conifers.html#Taxaceae|Taxaceae asparagalesweb.htm#Tecophilaeaceae|Tecophilaeaceae saxifragalesweb.htm#Tetracarpaeaceae|Tetracarpaeaceae lamialesweb.htm#Tetrachondraceae|Tetrachondraceae cucurbitalesweb.htm#Tetramelaceae|Tetramelaceae ericalesweb.htm#Tetrameristaceae|Tetrameristaceae ericalesweb.htm#Theaceae|Theaceae dioscorealesweb.htm#Thismiaceae|Thismiaceae lamialesweb.htm#Thomandersiaceae|Thomandersiaceae poalesweb.htm#Thurniaceae|Thurniaceae malvalesweb.htm#Thymelaeaceae|Thymelaeaceae fagalesweb.htm#Ticodendraceae|Ticodendraceae alismatalesweb.htm#Tofieldiaceae|Tofieldiaceae apialesweb.htm#Torricelliaceae|Torricelliaceae brassicalesweb.htm#Tovariaceae|Tovariaceae malpighialesweb.htm#Trigoniaceae|Trigoniaceae austrobaileyalesweb.htm#Trimeniaceae|Trimeniaceae pandanalesweb.htm#Triuridaceae|Triuridaceae trochodendralesweb.html#Trochodendraceae|Trochodendraceae brassicalesweb.htm#Tropaeolaceae|Tropaeolaceae poalesweb.htm#Typhaceae|Typhaceae rosalesweb.htm#Ulmaceae|Ulmaceae rosalesweb.htm#Urticaceae|Urticaceae gentianalesweb.htm#Vahliaceae|Vahliaceae dipsacalesweb.htm#Valerianaceae|Valerianaceae pandanalesweb.htm#Velloziaceae|Velloziaceae lamialesweb.htm#Verbenaceae|Verbenaceae malpighialesweb.htm#Violaceae|Violaceae vitalesweb.html#Vitaceae|Vitaceae geranialesweb.htm#Vivianiaceae|Vivianiaceae myrtalesweb2.htm#Vochysiaceae|Vochysiaceae gnetales.html#Welwitschiaceae|Welwitschiaceae canellalesweb.htm#Winteraceae|Winteraceae asparagalesweb.htm#Xanthorrhoeaceae|Xanthorrhoeaceae asparagalesweb.htm#Xeronemataceae|Xeronemataceae santalalesweb2.htm#Ximeniaceae|Ximeniaceae poalesweb.htm#Xyridaceae|Xyridaceae zingiberalesweb.htm#Zingiberaceae|Zingiberaceae alismatalesweb.htm#Zosteraceae|Zosteraceae zygophyllalesweb.htm#Zygophyllaceae|Zygophyllaceae" ;

  split(fams, tmp, " ");
  for (i in tmp)
  {
      split(tmp[i], tmp2, "|");
      apfam[toupper(tmp2[2])] = tmp2[1];
  }
}

function treeInfo()
{

  htmlHeader("Plant information", 400) ;

  apfam_load() ;
  loadColors();

  FS="|";
  while ((getline < "data/aa-tree.csv") > 0)
	{
	  if ($1 == f["tag"])
		{
		  print "
" $4 "
";
		  print "
" ;
		  if (apfam[$3] == "") print "
Family : " substr($3,1,1) tolower(substr($3,2)) "
" ;
		  else print "
Family : " substr($3,1,1) tolower(substr($3,2)) "
" ;
		  if ($6 != "") print "
Common name : " $6 "
" ;
		  if ($10 != "") print "
Section : " $10 "
" ;
		  if ($11 != "") print "
Collection : " $11 "
" ;
		  if ($8 > 0) print "
Diameter : " int($8) " " $9 "
" ;
		  # print "
Grid : " $12 "
" ;
		  print "
Tag : " $1 "
" ;
		  split($4,nam," ");
		  print "
Observations of this plant
" ;
		  print "
Images of this taxon
";
		  print "
Wood structure
"; # no point in passing spp since all spp in a genus are returned
		  print "
More info...
";
		  print "
";
		  print "";
		  print "
[ observe | map it | directions | home ]
" ;

		  break;
		}
	}
}

function apfam_load ()
{
  fams = "lamialesweb.htm#Acanthaceae|Acanthaceae malpighialesweb.htm#Achariaceae|Achariaceae caryophyllalesweb.htm#Achatocarpaceae|Achatocarpaceae acoralesweb.htm#Acoraceae|Acoraceae ericalesweb.htm#Actinidiaceae|Actinidiaceae dipsacalesweb.htm#Adoxaceae|Adoxaceae berberidopsidalesweb.html#Aextoxicaceae|Aextoxicaceae caryophyllalesweb.htm#Aizoaceae|Aizoaceae brassicalesweb.htm#Akaniaceae|Akaniaceae alismatalesweb.htm#Alismataceae|Alismataceae asteralesweb.htm#Alseuosmiaceae|Alseuosmiaceae lilialesweb.htm#Alstroemeriaceae|Alstroemeriaceae saxifragalesweb.htm#Altingiaceae|Altingiaceae myrtalesweb2.htm#Alzateaceae|Alzateaceae caryophyllalesweb.htm#Amaranthaceae|Amaranthaceae asparagalesweb.htm#Amaryllidaceae|Amaryllidaceae amborellalesweb2.htm#Amborellaceae|Amborellaceae  caryophyllalesweb.htm#Anacampseros|Anacampserotaceae sapindalesweb.htm#Anacardiaceae|Anacardiaceae poalesweb.htm#Anarthriaceae|Anarthriaceae caryophyllalesweb.htm#Ancistrocladaceae|Ancistrocladaceae cucurbitalesweb.htm#Anisophylleaceae|Anisophylleaceae magnolialesweb.htm#Annonaceae|Annonaceae saxifragalesweb.htm#Aphanopetalaceae|Aphanopetalaceae crossosomatalesweb.htm#Aphloiaceae|Aphloiaceae apialesweb.htm#Apiaceae|Apiaceae gentianalesweb.htm#Apocynaceae|Apocynaceae cucurbitalesweb.htm#Apodanthaceae|Apodanthaceae alismatalesweb.htm#Aponogetonaceae|Aponogetonaceae santalalesweb2.htm#Aptandraceae|Aptandraceae aquifolialesweb2.htm#Aquifoliaceae|Aquifoliaceae alismatalesweb.htm#Araceae|Araceae apialesweb.htm#Araliaceae|Araliaceae conifers.html#Araucariaceae|Araucariaceae arecalesweb.htm#Arecaceae|Arecaceae asteralesweb.htm#Argophyllaceae|Argophyllaceae piperalesweb2.htm#Aristolochiaceae|Aristolochiaceae asparagalesweb.htm#Asparagaceae|Asparagaceae asparagalesweb.htm#Asteliaceae|Asteliaceae asteralesweb.htm#Asteraceae|Asteraceae caryophyllalesweb.htm#Asteropeiaceae|Asteropeiaceae lauralesweb.htm#Atherospermataceae|Atherospermataceae austrobaileyalesweb.htm#Austrobaileyaceae|Austrobaileyaceae santalalesweb2.htm#Balanophoraceae|Balanophoraceae ericalesweb.htm#Balsaminaceae|Balsaminaceae caryophyllalesweb.htm#Barbeuiaceae|Barbeuiaceae rosalesweb.htm#Barbeyaceae|Barbeyaceae caryophyllalesweb.htm#Basellaceae|Basellaceae brassicalesweb.htm#Bataceae|Bataceae cucurbitalesweb.htm#Begoniaceae|Begoniaceae ranunculalesweb.htm#Berberidaceae|Berberidaceae berberidopsidalesweb.html#Berberidopsidaceae|Berberidopsidaceae fagalesweb.htm#Betulaceae|Betulaceae sapindalesweb.htm#Biebersteiniaceae|Biebersteiniaceae lamialesweb.htm#Bignoniaceae|Bignoniaceae malvalesweb.htm#CocBixDie|Bixaceae asparagalesweb.htm#Blandfordiaceae|Blandfordiaceae malpighialesweb.htm#Bonnetiaceae|Bonnetiaceae gentianalesweb.htm#Boraginaceae|Boraginaceae asparagalesweb.htm#Boryaceae|Boryaceae brassicalesweb.htm#Brassicoideae|Brassicaceae poalesweb.htm#Bromeliaceae|Bromeliaceae oxalidalesweb.htm#Brunelliaceae|Brunelliaceae brunialesweb.htm#Bruniaceae|Bruniaceae dioscorealesweb.htm#Burmanniaceae|Burmanniaceae sapindalesweb.htm#Burseraceae|Burseraceae alismatalesweb.htm#Butomaceae|Butomaceae buxalesweb.htm#Buxaceae|Buxaceae lamialesweb.htm#Byblidaceae|Byblidaceae caryophyllalesweb.htm#Cactaceae|Cactaceae lamialesweb.htm#Calceolariaceae|Calceolariaceae malpighialesweb.htm#Calophyllaceae|Calophyllaceae lauralesweb.htm#Calycanthaceae|Calycanthaceae asteralesweb.htm#Calyceraceae|Calyceraceae asteralesweb.htm#Campanulaceae|Campanulaceae lilialesweb.htm#Campynemataceae|Campynemataceae canellalesweb.htm#Canellaceae|Canellaceae rosalesweb.htm#Cannabaceae|Cannabaceae zingiberalesweb.htm#Cannaceae|Cannaceae brassicalesweb.htm#Capparoideae|Capparaceae dipsacalesweb.htm#Caprifoliaceae|Caprifoliaceae aquifolialesweb2.htm#Cardiopteridaceae|Cardiopteridaceae brassicalesweb.htm#Caricaceae|Caricaceae lamialesweb.htm#Carlemanniaceae|Carlemanniaceae malpighialesweb.htm#Caryocaraceae|Caryocaraceae caryophyllalesweb.htm#Caryophyllaceae|Caryophyllaceae fagalesweb.htm#Casuarinaceae|Casuarinaceae celastralesweb.html#Celastraceae|Celastraceae poalesweb.htm#Centrolepidaceae|Centrolepidaceae malpighialesweb.htm#Centroplacaceae|Centroplacaceae oxalidalesweb.htm#Cephalotaceae|Cephalotaceae ceratophyllalesweb.htm#Ceratophyllaceae|Ceratophyllaceae saxifragalesweb.htm#Cercidiphyllaceae|Cercidiphyllaceae chloranthalesweb.htm#Chloranthaceae|Chloranthaceae malpighialesweb.htm#Chrysobalanaceae|Chrysobalanaceae ranunculalesweb.htm#Circaeasteraceae|Circaeasteraceae malvalesweb.htm#Cistaceae|Cistaceae brassicalesweb.htm#Cleomoideae|Cleomaceae ericalesweb.htm#Clethraceae|Clethraceae malpighialesweb.htm#Clusiaceae|Clusiaceae lilialesweb.htm#Colchicaceae|Colchicaceae brunialesweb.htm#Columelliaceae|Columelliaceae myrtalesweb2.htm#Combretaceae|Combretaceae commelinalesweb.htm#Commelinaceae|Commelinaceae oxalidalesweb.htm#Connaraceae|Connaraceae solanalesweb.htm#Convolvulaceae|Convolvulaceae cucurbitalesweb.htm#Coriariaceae|Coriariaceae cornalesweb.htm#Cornaceae|Cornaceae lilialesweb.htm#Corsiaceae|Corsiaceae cucurbitalesweb.htm#Corynocarpaceae|Corynocarpaceae zingiberalesweb.htm#Costaceae|Costaceae santalalesweb2.htm#Coulaceae|Coulaceae saxifragalesweb.htm#Crassulaceae|Crassulaceae crossosomatalesweb.htm#Crossosomataceae|Crossosomataceae myrtalesweb2.htm#Crypteroniaceae|Crypteroniaceae malpighialesweb.htm#Ctenolophonaceae|Ctenolophonaceae cucurbitalesweb.htm#Cucurbitaceae|Cucurbitaceae oxalidalesweb.htm#Cunoniaceae|Cunoniaceae conifers.html#Cupressaceae|Cupressaceae cornalesweb.htm#Curtisiaceae|Curtisiaceae Cycadales.html#Cycadaceae|Cycadaceae pandanalesweb.htm#Cyclanthaceae|Cyclanthaceae alismatalesweb.htm#Cymodoceaceae|Cymodoceaceae saxifragalesweb.htm#Cynomoriaceae|Cynomoriaceae poalesweb.htm#Cyperaceae|Cyperaceae ericalesweb.htm#Cyrillaceae|Cyrillaceae malvalesweb.htm#Cytinaceae|Cytinaceae saxifragalesweb.htm#Daphniphyllaceae|Daphniphyllaceae arecalesweb.htm#Dasypogonaceae|Dasypogonaceae  cucurbitalesweb.htm#Datiscaceae|Datiscaceae magnolialesweb.htm#Degeneriaceae|Degeneriaceae ericalesweb.htm#Diapensiaceae|Diapensiaceae malpighialesweb.htm#Dichapetalaceae|Dichapetalaceae caryophyllalesweb.htm#Didiereaceae|Didiereaceae buxalesweb.htm#Didymelaceae|Didymelaceae dipsacalesweb.htm#Diervillaceae|Diervillaceae dillenialesweb.html#Dilleniaceae|Dilleniaceae caryophyllalesweb.htm#Dioncophyllaceae|Dioncophyllaceae dioscorealesweb.htm#Dioscoreaceae|Dioscoreaceae huertealesweb.htm#Dipentodontaceae|Dipentodontaceae dipsacalesweb.htm#Dipsacaceae|Dipsacaceae malvalesweb.htm#Dipterocarpaceae|Dipterocarpaceae rosalesweb.htm#Dirachmaceae|Dirachmaceae asparagalesweb.htm#Doryanthaceae|Doryanthaceae caryophyllalesweb.htm#Droseraceae|Droseraceae caryophyllalesweb.htm#Drosophyllaceae|Drosophyllaceae poalesweb.htm#Ecdeiocoleaceae|Ecdeiocoleaceae rosalesweb.htm#Elaeagnaceae|Elaeagnaceae oxalidalesweb.htm#Elaeocarpaceae|Elaeocarpaceae malpighialesweb.htm#Elatinaceae|Elatinaceae brassicalesweb.htm#Emblingiaceae|Emblingiaceae gnetales.html#Ephedraceae|Ephedraceae ericalesweb.htm#Ericaceae|Ericaceae poalesweb.htm#Eriocaulaceae|Eriocaulaceae santalalesweb2.htm#Erythropalaceae|Erythropalaceae malpighialesweb.htm#Erythroxylaceae|Erythroxylaceae Escalloniales.html#Escalloniaceae|Escalloniaceae garryalesweb.htm#Eucommiaceae|Eucommiaceae malpighialesweb.htm#Euphorbiaceae|Euphorbiaceae malpighialesweb.htm#Euphroniaceae|Euphroniaceae magnolialesweb.htm#Eupomatiaceae|Eupomatiaceae ranunculalesweb.htm#Eupteleaceae|Eupteleaceae fagalesweb.htm#Fagaceae|Fagaceae poalesweb.htm#Flagellariaceae|Flagellariaceae ericalesweb.htm#Fouquieriaceae|Fouquieriaceae geranialesweb.htm#Francoaceae|Francoaceae caryophyllalesweb.htm#Frankeniaceae|Frankeniaceae garryalesweb.htm#Garryaceae|Garryaceae crossosomatalesweb.htm#Geissolomataceae|Geissolomataceae gentianalesweb.htm#Gelsemiaceae|Gelsemiaceae gentianalesweb.htm#Gentianaceae|Gentianaceae geranialesweb.htm#Geraniaceae|Geraniaceae huertealesweb.htm#Gerrardinaceae|Gerrardinaceae lamialesweb.htm#Gesneriaceae|Gesneriaceae ginkgoales.html#Ginkgoaceae|Ginkgoaceae caryophyllalesweb.htm#Gisekiaceae|Gisekiaceae gnetales.html#Gnetaceae|Gnetaceae lauralesweb.htm#Gomortegaceae|Gomortegaceae asteralesweb.htm#Goodeniaceae|Goodeniaceae malpighialesweb.htm#Goupiaceae|Goupiaceae apialesweb.htm#Griseliniaceae|Griseliniaceae saxifragalesweb.htm#Grossulariaceae|Grossulariaceae cornalesweb.htm#Grubbiaceae|Grubbiaceae crossosomatalesweb.htm#Guametalaceae|Guamatelaceae gunneralesweb.htm#Gunneraceae|Gunneraceae brassicalesweb.htm#Gyrostemonaceae|Gyrostemonaceae commelinalesweb.htm#Haemodoraceae|Haemodoraceae caryophyllalesweb.htm#Halophytaceae|Halophytaceae saxifragalesweb.htm#Haloragaceae|Haloragaceae saxifragalesweb.htm#Hamamelidaceae|Hamamelidaceae commelinalesweb.htm#Hanguanaceae|Hanguanaceae zingiberalesweb.htm#Heliconiaceae|Heliconiaceae aquifolialesweb2.htm#Helwingiaceae|Helwingiaceae lauralesweb.htm#Hernandiaceae|Hernandiaceae magnolialesweb.htm#Himantandraceae|Himantandraceae oxalidalesweb.htm#Huaceae|Huaceae malpighialesweb.htm#Humiriaceae|Humiriaceae nymphaealesweb.htm#Hydatellaceae|Hydatellaceae piperalesweb2.htm#Hydnoraceae|Hydnoraceae cornalesweb.htm#Hydrangeaceae|Hydrangeaceae alismatalesweb.htm#Hydrocharitaceae|Hydrocharitaceae solanalesweb.htm#Hydroleaceae|Hydroleaceae cornalesweb.htm#Hydrostachyaceae|Hydrostachyaceae malpighialesweb.htm#Hypericaceae|Hypericaceae asparagalesweb.htm#Hypoxidaceae|Hypoxidaceae asparagalesweb.htm#Iridaceae|Iridaceae malpighialesweb.htm#Irvingiaceae|Irvingiaceae saxifragalesweb.htm#Iteaceae|Iteaceae asparagalesweb.htm#Ixioliriaceae|Ixiolirionaceae malpighialesweb.htm#Ixonanthaceae|Ixonanthaceae poalesweb.htm#Joinvilleaceae|Joinvilleaceae fagalesweb.htm#Juglandaceae|Juglandaceae poalesweb.htm#Juncaceae|Juncaceae alismatalesweb.htm#Juncaginaceae|Juncaginaceae sapindalesweb.htm#Kirkiaceae|Kirkiaceae brassicalesweb.htm#Koeberliniaceae|Koeberliniaceae zygophyllalesweb.htm#Krameriaceae|Krameriaceae malpighialesweb.htm#Lacistemataceae|Lacistemataceae lamialesweb.htm#Lamiaceae|Lamiaceae asparagalesweb.htm#Lanariaceae|Lanariaceae ranunculalesweb.htm#Lardizabalaceae|Lardizabalaceae lauralesweb.htm#Lauraceae|Lauraceae ericalesweb.htm#Lecythidaceae|Lecythidaceae geranialesweb.htm#Ledocarpaceae|Ledocarpaceae lamialesweb.htm#Lentibulariaceae|Lentibulariaceae celastralesweb.html#Lepidobotryaceae|Lepidobotryaceae lilialesweb.htm#Liliaceae|Liliaceae Caryophyllalesweb.htm#Limeaceae|Limeaceae brassicalesweb.htm#Limnanthaceae|Limnanthaceae malpighialesweb.htm#Linaceae|Linaceae lamialesweb.htm#Linderniaceae|Linderniaceae dipsacalesweb.htm#Linnaeaceae|Linnaeaceae cornalesweb.htm#Loasaceae|Loasaceae gentianalesweb.htm#Loganiaceae|Loganiaceae caryophyllalesweb.htm#Lophiocarpaceae|Lophiocarpaceae malpighialesweb.htm#Lophopyxidaceae|Lophopyxidaceae santalalesweb2.htm#Loranthaceae|Loranthaceae zingiberalesweb.htm#Lowiaceae|Lowiaceae myrtalesweb2.htm#Lythraceae|Lythraceae magnolialesweb.htm#Magnoliaceae|Magnoliaceae malpighialesweb.htm#Malpighiaceae|Malpighiaceae malvalesweb.htm#Malvaceae|Malvaceae zingiberalesweb.htm#Marantaceae|Marantaceae ericalesweb.htm#Marcgraviaceae|Marcgraviaceae lamialesweb.htm#Martyniaceae|Martyniaceae alismatalesweb.htm#Maundiaceae|Maundiaceae poalesweb.htm#Mayacaceae|Mayacaceae lilialesweb.htm#Melanthiaceae|Melanthiaceae myrtalesweb2.htm#Melastomataceae|Melastomataceae sapindalesweb.htm#Meliaceae|Meliaceae geranialesweb.htm#Melianthaceae|Melianthaceae ranunculalesweb.htm#Menispermaceae|Menispermaceae asteralesweb.htm#Menyanthaceae|Menyanthaceae garryalesweb.htm#Metteniusaceae|Metteniusaceae caryophyllalesweb.htm#Microteaceae|Microteaceae santalalesweb2.htm#Misodendraceae|Misodendraceae ericalesweb.htm#Mitrastemonaceae|Mitrastemonaceae caryophyllalesweb.htm#Molluginaceae|Molluginaceae lauralesweb.htm#Monimiaceae|Monimiaceae caryophyllalesweb.htm#Montiaceae|Montiaceae solanalesweb.htm#Montiniaceae|Montiniaceae rosalesweb.htm#Moraceae|Moraceae dipsacalesweb.htm#Morinaceae|Morinaceae brassicalesweb.htm#Moringaceae|Moringaceae malvalesweb.htm#Muntingiaceae|Muntingiaceae zingiberalesweb.htm#Musaceae|Musaceae apialesweb.htm#Myodocarpaceae|Myodocarpaceae fagalesweb.htm#Myricaceae|Myricaceae magnolialesweb.htm#Myristicaceae|Myristicaceae gunneralesweb.htm#Myrothamnaceae|Myrothamnaceae myrtalesweb2.htm#Myrtaceae|Myrtaceae dioscorealesweb.htm#Nartheciaceae|Nartheciaceae protealesweb.html#Nelumbonaceae|Nelumbonaceae caryophyllalesweb.htm#Nepenthaceae|Nepenthaceae malvalesweb.htm#Neuradaceae|Neuradaceae sapindalesweb.htm#Nitrariaceae|Nitrariaceae fagalesweb.htm#Nothofagaceae|Nothofagaceae caryophyllalesweb.htm#Nyctaginaceae|Nyctaginaceae nymphaealesweb.htm#Nymphaeaceae|Nymphaeaceae malpighialesweb.htm#Ochnaceae|Ochnaceae santalalesweb2.htm#Octonemaceae|Octonemaceae santalalesweb2.htm#Olacaceae|Olacaceae lamialesweb.htm#Oleaceae|Oleaceae myrtalesweb2.htm#Onagraceae|Onagraceae garryalesweb.htm#Oncothecaceae|Oncothecaceae santalalesweb2.htm#Opiliaceae|Opiliaceae asparagalesweb.htm#Orchidaceae|Orchidaceae lamialesweb.htm#Orobanchaceae|Orobanchaceae oxalidalesweb.htm#Oxalidaceae|Oxalidaceae saxifragalesweb.htm#Paeoniaceae|Paeoniaceae malpighialesweb.htm#Pandaceae|Pandaceae pandanalesweb.htm#Pandanaceae|Pandanaceae ranunculalesweb.htm#Papaveraceae|Papaveraceae Paracryphiales.html#Paracryphiaceae|Paracryphiaceae malpighialesweb.htm#Passifloraceae|Passifloraceae lamialesweb.htm#Paulowniaceae |Paulowniaceae lamialesweb.htm#Pedaliaceae|Pedaliaceae myrtalesweb2.htm#Penaeaceae|Penaeaceae apialesweb.htm#Pennantiaceae|Pennantiaceae brassicalesweb.htm#Pentadiplandraceae|Pentadiplandraceae asteralesweb.htm#Pentaphragmataceae|Pentaphragmataceae ericalesweb.htm#Pentaphylacaceae|Pentaphylacaceae saxifragalesweb.htm#Penthoraceae|Penthoraceae malpighialesweb.htm#Peraceae|Peraceae saxifragalesweb.htm#Peridiscaceae|Peridiscaceae huertealesweb.htm#Petenaeaceae|Petenaeaceae lilialesweb.htm#Petermanniaceae|Petermanniaceae petrosavialesweb.htm#Petrosaviaceae|Petrosaviaceae asteralesweb.htm#Phellinaceae|Phellinaceae lilialesweb.htm#Philesiaceae|Philesiaceae commelinalesweb.htm#Philydraceae|Philydraceae lamialesweb.htm#Phrymaceae|Phrymaceae malpighialesweb.htm#Phyllanthaceae|Phyllanthaceae aquifolialesweb2.htm#Phyllonomaceae|Phyllonomaceae caryophyllalesweb.htm#Physenaceae|Physenaceae caryophyllalesweb.htm#Phytolaccaceae|Phytolaccaceae picramnialesweb.html#Picramniaceae|Picramniaceae malpighialesweb.htm#Picrodendraceae|Picrodendraceae conifers.html#Pinaceae|Pinaceae piperalesweb2.htm#Piperaceae|Piperaceae apialesweb.htm#Pittosporaceae|Pittosporaceae lamialesweb.htm#Plantaginaceae|Plantaginaceae protealesweb.html#Platanaceae|Platanaceae lamialesweb.htm#Plocospermataceae|Plocospermataceae caryophyllalesweb.htm#Plumbaginaceae|Plumbaginaceae poalesweb.htm#Poaceae|Poaceae conifers.html#Podocarpaceae|Podocarpaceae malpighialesweb.htm#Podostemaceae|Podostemaceae ericalesweb.htm#Polemoniaceae|Polemoniaceae fabalesweb.htm#Polygalaceae|Polygalaceae caryophyllalesweb.htm#Polygonaceae|Polygonaceae commelinalesweb.htm#Pontederiaceae|Pontederiaceae caryophyllalesweb.htm#Portulacaceae|Portulacaceae alismatalesweb.htm#Posidoniaceae|Posidoniaceae alismatalesweb.htm#Potamogetonaceae|Potamogetonaceae ericalesweb.htm#Primulaceae|Primulaceae protealesweb.html#Proteaceae|Proteaceae malpighialesweb.htm#Putranjivaceae|Putranjivaceae fabalesweb.htm#Quillajaceae|Quillajaceae ranunculalesweb.htm#Ranunculaceae|Ranunculaceae poalesweb.htm#Rapateaceae |Rapateaceae brassicalesweb.htm#Resedaceae|Resedaceae poalesweb.htm#Restionaceae|Restionaceae caryophyllalesweb.htm#Rhabdodendraceae|Rhabdodendraceae rosalesweb.htm#Rhamnaceae|Rhamnaceae lilialesweb.htm#Rhipogonaceae|Rhipogonaceae malpighialesweb.htm#Rhizophoraceae|Rhizophoraceae fagalesweb.htm#Rhoipteleaceae|Rhoipteleaceae ericalesweb.htm#Roridulaceae|Roridulaceae rosalesweb.htm#Rosaceae|Rosaceae asteralesweb.htm#Rousseaceae|Rousseaceae gentianalesweb.htm#Rubiaceae|Rubiaceae alismatalesweb.htm#Ruppiaceae|Ruppiaceae sapindalesweb.htm#Rutaceae|Rutaceae Sabiales.html#Sabiaceae|Sabiaceae malpighialesweb.htm#Salicaceae|Salicaceae brassicalesweb.htm#Salvadoraceae|Salvadoraceae santalalesweb2.htm#Santalaceae|Santalaceae sapindalesweb.htm#Sapindaceae|Sapindaceae ericalesweb.htm#Sapotaceae|Sapotaceae caryophyllalesweb.htm#Sarcobataceae|Sarcobataceae malvalesweb.htm#Sarcolaenaceae|Sarcolaenaceae ericalesweb.htm#Sarraceniaceae|Sarraceniaceae piperalesweb2.htm#Saururaceae|Saururaceae saxifragalesweb.htm#Saxifragaceae|Saxifragaceae alismatalesweb.htm#Scheuchzeriaceae|Scheuchzeriaceae austrobaileyalesweb.htm#Schisandraceae|Schisandraceae lamialesweb.htm#Schlegeliaceae|Schlegeliaceae santalalesweb2.htm#Schoepfiaceae|Schoepfiaceae conifers.html#Sciadopityaceae|Sciadopityaceae lamialesweb.htm#Scrophulariaceae|Scrophulariaceae brassicalesweb.htm#Setchellanthaceae|Setchellanthaceae sapindalesweb.htm#Simaroubaceae|Simaroubaceae caryophyllalesweb.htm#Simmondsiaceae|Simmondsiaceae lauralesweb.htm#Siparunaceae|Siparunaceae ericalesweb.htm#Sladeniaceae|Sladeniaceae lilialesweb.htm#Smilacaceae|Smilacaceae solanalesweb.htm#Solanaceae|Solanaceae malvalesweb.htm#Sphaerosepalaceae|Sphaerosepalaceae solanalesweb.htm#Sphenocleaceae|Sphenocleaceae crossosomatalesweb.htm#Stachyuraceae|Stachyuraceae crossosomatalesweb.htm#Staphyleaceae|Staphyleaceae caryophyllalesweb.htm#Stegnospermataceae|Stegnospermataceae pandanalesweb.htm#Stemonaceae|Stemonaceae aquifolialesweb2.htm#Stemonuraceae|Stemonuraceae lamialesweb.htm#Stilbaceae|Stilbaceae brassicalesweb.htm#Stixaceae|Stixaceae crossosomatalesweb.htm#Strasburgeriaceae|Strasburgeriaceae zingiberalesweb.htm#Strelitziaceae|Strelitziaceae santalalesweb2.htm#Strombosiaceae|Strombosiaceae asteralesweb.htm#Stylidiaceae|Stylidiaceae ericalesweb.htm#Styracaceae|Styracaceae fabalesweb.htm#Surianaceae|Surianaceae ericalesweb.htm#Symplocaceae|Symplocaceae caryophyllalesweb.htm#Talinaceae|Talinaceae caryophyllalesweb.htm#Tamaricaceae|Tamaricaceae huertealesweb.htm#Tapisciaceae|Tapisciaceae conifers.html#Taxaceae|Taxaceae asparagalesweb.htm#Tecophilaeaceae|Tecophilaeaceae saxifragalesweb.htm#Tetracarpaeaceae|Tetracarpaeaceae lamialesweb.htm#Tetrachondraceae|Tetrachondraceae cucurbitalesweb.htm#Tetramelaceae|Tetramelaceae ericalesweb.htm#Tetrameristaceae|Tetrameristaceae ericalesweb.htm#Theaceae|Theaceae dioscorealesweb.htm#Thismiaceae|Thismiaceae lamialesweb.htm#Thomandersiaceae|Thomandersiaceae poalesweb.htm#Thurniaceae|Thurniaceae malvalesweb.htm#Thymelaeaceae|Thymelaeaceae fagalesweb.htm#Ticodendraceae|Ticodendraceae alismatalesweb.htm#Tofieldiaceae|Tofieldiaceae apialesweb.htm#Torricelliaceae|Torricelliaceae brassicalesweb.htm#Tovariaceae|Tovariaceae malpighialesweb.htm#Trigoniaceae|Trigoniaceae austrobaileyalesweb.htm#Trimeniaceae|Trimeniaceae pandanalesweb.htm#Triuridaceae|Triuridaceae trochodendralesweb.html#Trochodendraceae|Trochodendraceae brassicalesweb.htm#Tropaeolaceae|Tropaeolaceae poalesweb.htm#Typhaceae|Typhaceae rosalesweb.htm#Ulmaceae|Ulmaceae rosalesweb.htm#Urticaceae|Urticaceae gentianalesweb.htm#Vahliaceae|Vahliaceae dipsacalesweb.htm#Valerianaceae|Valerianaceae pandanalesweb.htm#Velloziaceae|Velloziaceae lamialesweb.htm#Verbenaceae|Verbenaceae malpighialesweb.htm#Violaceae|Violaceae vitalesweb.html#Vitaceae|Vitaceae geranialesweb.htm#Vivianiaceae|Vivianiaceae myrtalesweb2.htm#Vochysiaceae|Vochysiaceae gnetales.html#Welwitschiaceae|Welwitschiaceae canellalesweb.htm#Winteraceae|Winteraceae asparagalesweb.htm#Xanthorrhoeaceae|Xanthorrhoeaceae asparagalesweb.htm#Xeronemataceae|Xeronemataceae santalalesweb2.htm#Ximeniaceae|Ximeniaceae poalesweb.htm#Xyridaceae|Xyridaceae zingiberalesweb.htm#Zingiberaceae|Zingiberaceae alismatalesweb.htm#Zosteraceae|Zosteraceae zygophyllalesweb.htm#Zygophyllaceae|Zygophyllaceae" ;

  split(fams, tmp, " ");
  for (i in tmp)
  {
      split(tmp[i], tmp2, "|");
      apfam[toupper(tmp2[2])] = tmp2[1];
  }
}


Added check for non-interleaving readpairs. Fixed bug with readnames not starting with @

BEGIN{
    attach_in_readname = 1;
    attach_in_comment = 1;

    for (i = 1; i < ARGC; i++) {
        if (ARGV[i] == "-n")
            attach_in_readname = 0
        else if (ARGV[i] == "-c")
            attach_in_comment = 0
        else if (ARGV[i] ~ /^-./) {
            e = sprintf("%s: unrecognized option -- %c",
                    ARGV[0], substr(ARGV[i], 2, 1))
            print e > "/dev/stderr"
        } else
            break
        delete ARGV[i]
    }

}
{
    if (NR % 8 == 1 && NR > 1) {
        read_name1 = substr(read_pair[1], 1, match(read_pair[1], / /) - 1)
        read_name2 = substr(read_pair[5], 1, match(read_pair[5], / /) - 1)

        if (read_name1 != read_name2){
            print "Read pairs at line " NR " do not interleave correctly: " read_pair[1] "\t" read_pair[5] ;
        } else {
            barcode = substr(read_pair[2], 1, 16);

            if (attach_in_readname) {
                initial = "@"barcode"-1_";
                read_pair[1] = substr(read_pair[1], 2)
                read_pair[5] = substr(read_pair[5], 2)
            }

            if (attach_in_comment) {
                final = " BX:Z:"barcode"-1";
            }

            printf initial read_pair[1] final"\n"
            printf substr(read_pair[2], 17)"\n"
            printf read_pair[3]"\n"
            printf substr(read_pair[4], 17)"\n"
            printf initial read_pair[5] final"\n"
            printf read_pair[6]"\n"
            printf read_pair[7]"\n"
            printf read_pair[0]"\n"
        }
    }
    read_pair[NR % 8] = $0
}

BEGIN{
    attach_in_readname = 1;
    attach_in_comment = 1;

    for (i = 1; i < ARGC; i++) {
        if (ARGV[i] == "-n")
            attach_in_readname = 0
        else if (ARGV[i] == "-c")
            attach_in_comment = 0
        else if (ARGV[i] ~ /^-./) {
            e = sprintf("%s: unrecognized option -- %c",
                    ARGV[0], substr(ARGV[i], 2, 1))
            print e > "/dev/stderr"
        } else
            break
        delete ARGV[i]
    }

}

{
    if (NR % 8 == 1 && NR > 1) {
        barcode = substr(read_pair[2], 1, 16);
        if (attach_in_readname) {
            initial = barcode"-1_";
        }

        if (attach_in_comment) {
            final = " BX:Z:"barcode"-1";
        }

        printf initial read_pair[1] final"\n"
        printf substr(read_pair[2], 17)"\n"
        printf read_pair[3]"\n"
        printf substr(read_pair[4], 17)"\n"
        printf initial read_pair[5] final"\n"
        printf read_pair[6]"\n"
        printf read_pair[7]"\n"
        printf read_pair[0]"\n"
    }
    read_pair[NR % 8] = $0
}


-Added some ignore cases in remove dups awk scripts

git-svn-id: 392d0e5ce652024192c571322d40dcc23d6d83b0@27 8a65f31f-a56f-4bd6-98e8-2755f64920ec

BEGIN {
   seen_count = 0;
}
{
   discard = 0;
   if ($1 ~ "[0-9]") {
	  seen[seen_count] = $1

	  for (i = seen_count-1; i >= 0; --i) {
		 file1 = destDir "/frames/Frame" $1 ".html"
		 file2 = destDir "/frames/Frame" seen[i] ".html"
		 diff_cmd = sprintf("diff -s --brief -I \"Arrival Time\" -I \"Frame [:digit:]*\" -I \"Resent Packet\" -I \"Suspected resend of frame\" -I \"Request Frame: [:digit:]*\" -I \"Response Time (ms): [:digit:]*\" -I \"Release Time (ms): [:digit:]*\" %s %s > /dev/null", file1, file2);
		 #diff_cmd = sprintf("diff -s --brief -I \"Arrival Time\" -I \"Frame [:digit:]*\" -I \"Resent Packet\" -I \"Suspected resend of frame\" %s %s > /dev/null", file1, file2);
		 if (system(diff_cmd) == 0) {
			report_dup = sprintf("echo '%s is identical to %s' 1>&2", file1, file2);
			system(report_dup);
			discard = 1;
			break;
		 }
	  }
	  seen_count++;
   }

   if (discard == 0) {
	  print $0;
   }
}

BEGIN {
   seen_count = 0;
}
{
   discard = 0;
   if ($1 ~ "[0-9]") {
	  seen[seen_count] = $1

	  for (i = seen_count-1; i >= 0; --i) {
		 file1 = destDir "/frames/Frame" $1 ".html"
		 file2 = destDir "/frames/Frame" seen[i] ".html"
		 diff_cmd = sprintf("diff -s --brief -I \"Arrival Time\" -I \"Frame [:digit:]*\" -I \"Resent Packet\" -I \"Suspected resend of frame\" %s %s > /dev/null", file1, file2);
		 if (system(diff_cmd) == 0) {
			report_dup = sprintf("echo '%s is identical to %s' 1>&2", file1, file2);
			system(report_dup);
			discard = 1;
			break;
		 }
	  }
	  seen_count++;
   }

   if (discard == 0) {
	  print $0;
   }
}


cfg80211: add function helpers to genregdb.awk

This has no functional change, this just lets us reuse
helpers at a later time.

Signed-off-by: Luis R. Rodriguez <d4fa18192c5a479e564d29c2300c2e15afd1d8d7@do-not-panic.com>
Acked-by: John W. Linville <2a53bac7a5d324865ef46ec4c38b2c0fba1456b4@tuxdriver.com>
Signed-off-by: Johannes Berg <bff32994ff0f8d048f262a8388145a71b6071bfe@intel.com>


Patch from Stefan Allius:

Patch from Stefan Allius:

    Hi Erik,

    I patched the initfini.awk script, so we can build crt[in].S for the SuperH
    targets with gmon-support.

    The patch moves all labels into the wright sections, and add some assembler
    statements to jump over them. (only activ on SH targets)

    The patch also avoid any references of _GLOBAL_OFFSET_TABLE_ or *gmon_start*
    in the crtn.S file. This should work on every target.

    Bye Stefan

#! /usr/bin/awk -f
# Contributed by Christian MICHON <christian_michon@yahoo.fr> to
#   eliminate the compile time dependancy on perl introduced by
#   Erik's older initfini.pl
# vim:ai:sw=2:

BEGIN \
{ alignval="";
  endp=0;
  end=0;
  system("touch crt[in].S");
  system("/bin/rm -f crt[in].S");
  omitcrti=0;
  omitcrtn=0;
  glb_idx = 0;
  while(getline < "initfini.S")
  { if(/\.endp/) {endp=1}
    if(/\.end/) {end=1}
    if(/\.align/) {alignval=$2}
# here comes some special stuff for the SuperH targets
#  We search for all labels, which uses the _GLOBAL_OFFSET_TABLE_
#  or a call_gmon_start function reference, and store
#  them in the glb_label array.
    if(/_init_EPILOG_BEGINS/) {glb_idx=1;glb_idx_arr[glb_idx]=0}
    if(/_fini_EPILOG_BEGINS/) {glb_idx=2;glb_idx_arr[glb_idx]=0}
    if(/EPILOG_ENDS/)         {glb_idx=0}
    if(/_GLOBAL_OFFSET_TABLE_/||/call_gmon_start/) {
      glb_label[glb_idx,glb_idx_arr[glb_idx]] = last;
      glb_idx_arr[glb_idx] += 1;
      glb_label[glb_idx,glb_idx_arr[glb_idx]] = $0;
      glb_idx_arr[glb_idx] += 1;
    }
    last = $1;
  }
  close("initfini.S");
}
# special rules for the SuperH targets (They do nothing on other targets)
/SH_GLB_BEGINS/ && glb_idx_arr[1]==0 && glb_idx_arr[2]==0 {omitcrti +=1}
/_init_SH_GLB/  {glb_idx=1}
/_fini_SH_GLB/  {glb_idx=2}
/SH_GLB_ENDS/ {omitcrti -=1}
/SH_GLB/ \
{
  if (glb_idx>0)
    {
      for (i=0;i<glb_idx_arr[glb_idx];i+=1) {
	print glb_label[glb_idx,i] >> "crti.S";
      }
      glb_idx = 0;
    }
  next;
}
# special rules for H8/300 (sorry quick hack)
/.h8300h/ {end=0}

# rules for all targets
/HEADER_ENDS/{omitcrti=1;omitcrtn=1;getline}
/PROLOG_BEGINS/{omitcrti=0;omitcrtn=0;getline}
/i_am_not_a_leaf/{getline}
/_init:/||/_fini:/{omitcrtn=1}
/PROLOG_PAUSES/{omitcrti=1;getline}
/PROLOG_UNPAUSES/{omitcrti=0;getline}
/PROLOG_ENDS/{omitcrti=1;getline}
/EPILOG_BEGINS/{omitcrtn=0;getline}
/EPILOG_ENDS/{omitcrtn=1;getline}
/TRAILER_BEGINS/{omitcrti=0;omitcrtn=0;getline}
/GMON_STUFF_BEGINS/{omitcrtn=1;getline}
/GMON_STUFF_PAUSES/{omitcrtn=0;getline}
/GMON_STUFF_UNPAUSES/{omitcrtn=1;getline}
/GMON_STUFF_ENDS/{omitcrtn=0;getline}

/_GLOBAL_OFFSET_TABLE_/||/gmon_start/ \
{
  if(omitcrti==0) {print >> "crti.S";}
  next;  # no gmon_start or GLOBAL_OFFSET_TABLE references in crtn.S
}

/END_INIT/ \
{ if(endp)
  { gsub("END_INIT",".endp _init",$0)
  }
  else
  { if(end)
    { gsub("END_INIT",".end _init",$0)
    }
    else
    { gsub("END_INIT","",$0)
    }
  }
}

/END_FINI/ \
{ if(endp)
  { gsub("END_FINI",".endp _fini",$0)
  }
  else
  { if(end)
    { gsub("END_FINI",".end _fini",$0)
    }
    else
    { gsub("END_FINI","",$0)
    }
  }
}

/ALIGN/ \
{ if(alignval!="")
  { gsub("ALIGN",sprintf(".align %s",alignval),$0)
  }
  else
  { gsub("ALIGN","",$0)
  }
}

omitcrti==0 {print >> "crti.S"}
omitcrtn==0 {print >> "crtn.S"}

END \
{ close("crti.S");
  close("crtn.S");
}

#! /usr/bin/awk -f
# Contributed by Christian MICHON <christian_michon@yahoo.fr> to
#   eliminate the compile time dependancy on perl introduced by
#   Erik's older initfini.pl
# vim:ai:sw=2:

BEGIN \
{ alignval="";
  endp=0;
  end=0;
  system("touch crt[in].S");
  system("/bin/rm -f crt[in].S");
  omitcrti=0;
  omitcrtn=0;
  do_sh_specials = 0;
  glb_idx = 0;
  while(getline < "initfini.S")
  { if(/\.endp/) {endp=1}
    if(/\.end/) {end=1}
    if(/\.align/) {alignval=$2}
# here comes some special stuff for the SuperH targets
#  We search for all labels, which uses the _GLOBAL_OFFSET_TABLE_
#  definition, and store them in the glb_label array.
    if(/_GLOBAL_OFFSET_TABLE_/) {
      glb_label[glb_idx] = last;
      glb_idx += 1;
      glb = $0;
    }
    last = $1;
  }
  close("initfini.S");
}
# special rules for the SuperH targets (They do nothing on other targets)
/SH_GLB_BEGINS/ && glb_idx==0 {omitcrti +=1;do_sh_specials++}
/_init_SH_GLB/  && glb_idx>=1 {print glb_label[0] glb >> "crti.S"}
/_fini_SH_GLB/  && glb_idx>=2 {print glb_label[1] glb >> "crti.S"}
/SH_GLB_ENDS/   && glb_idx==0 {omitcrti -=1}
/SH_GLB/ || /_GLOBAL_OFFSET_TABLE_/ && do_sh_specials>=1 {getline}
# special rules for H8/300 (sorry quick hack)
/.h8300h/ {end=0}

# rules for all targets
/HEADER_ENDS/{omitcrti=1;omitcrtn=1;getline}
/PROLOG_BEGINS/{omitcrti=0;omitcrtn=0;getline}
/i_am_not_a_leaf/{getline}
/_init:/||/_fini:/{omitcrtn=1}
/PROLOG_PAUSES/{omitcrti=1;getline}
/PROLOG_UNPAUSES/{omitcrti=0;getline}
/PROLOG_ENDS/{omitcrti=1;getline}
/EPILOG_BEGINS/{omitcrtn=0;getline}
/EPILOG_ENDS/{omitcrtn=1;getline}
/TRAILER_BEGINS/{omitcrti=0;omitcrtn=0;getline}
/GMON_STUFF_BEGINS/{omitcrtn=1;getline}
/GMON_STUFF_PAUSES/{omitcrtn=0;getline}
/GMON_STUFF_UNPAUSES/{omitcrtn=1;getline}
/GMON_STUFF_ENDS/{omitcrtn=0;getline}

/END_INIT/ \
{ if(endp)
  { gsub("END_INIT",".endp _init",$0)
  }
  else
  { if(end)
    { gsub("END_INIT",".end _init",$0)
    }
    else
    { gsub("END_INIT","",$0)
    }
  }
}

/END_FINI/ \
{ if(endp)
  { gsub("END_FINI",".endp _fini",$0)
  }
  else
  { if(end)
    { gsub("END_FINI",".end _fini",$0)
    }
    else
    { gsub("END_FINI","",$0)
    }
  }
}

/ALIGN/ \
{ if(alignval!="")
  { gsub("ALIGN",sprintf(".align %s",alignval),$0)
  }
  else
  { gsub("ALIGN","",$0)
  }
}

omitcrti==0 {print >> "crti.S"}
omitcrtn==0 {print >> "crtn.S"}

END \
{ close("crti.S");
  close("crtn.S");
}


adds sensible defaults to bawlk.awk

adds sensible defaults to bawlk.awk

#!/usr/bin/awk -F, -f

BEGIN {
    FS=","
    print "#!/usr/bin/awk -F, -f" RS

    print "# generated by: awk-csvalid https://github.com/tesera/awk-csvalid" RS
    print "# awk-csvalid csv toolset generator: https://github.com/tesera/awk-csvalid"
    print "# usage:"
    print "#    validate:     awk -f action=validate validator.awk > violations.txt"
    print "#    create table: awk -v action=table -f validator.awk | psql afgo_dev"
    print "#    sanitize csv: awk -v action=sanitize -f validator.awk > sanitized.csv"
    print "#    insert sql:   awk -v action=insert -f validator.awk | psql afgo_dev" RS
    print "# awk is a simple unix text file parser: http://www.gnu.org/software/gawk/manual/gawk.html"
    print "# awk primer:"
    print "#    NR = number/index current record"
    print "#    RS = record seperator new line i.e. \\n"
    print "#    FS = field seperator i.e. ,"
    print "#    /pattern/ { expression } = if pattern is truthy run expression" RS

    print "BEGIN {"
    print "    FS=\",\"; OFS=\",\"; err_count=0; cats[\"na\"]=0;"
    print "    if(!action) action == \"validate\""
    print "}" RS

    print "# builtin helper functions"
    print "function eql(x,y) {v=1; for (i in x) v=(v&&x[i]==y[i]); return v;}"
    print "function are_headers_valid(valid_headers) { v=0; split($0, h, \",\"); split(valid_headers, vh, \"|\"); return eql(h, vh); }"
    print "function is_unique(i, val) { if (vals[i,val]) { return 0; } else { vals[i,val] = 1; return 1; } }"
    print "function is_numeric(x){ return(x==x+0) }"
    print "function print_cats(categories) { for (category in categories) { if (categories[category]) print \"      \" category \": \" categories[category]; } }"
    print "function log_err(cat) { cats[cat]++; err_count++; }"
    print RS
}

$1 == "option" {
    options[$2]=$3;
}

$1 == "headers" && $2 == "names" {
    split($3, headers, "|")
    print "# make header index/map"
    print "NR > 1 {"
    for (i in headers) {
        header_name = headers[i]
        header_index[header_name] = i
        print "    " headers[i]  "=$" i
    }

    print "}" RS
    print "# awk rules based on user csv ruleset"
    print "NR == 1 { headers=\"" $3 "\"; if (!are_headers_valid(headers)) print \"invalid headers\" }"
}

$1 == "field" {
    defaults["mode"]="append"
    defaults["summary"]="true"
    defaults["dcat"]="warning"
    defaults["dvalnum"]=-9999
    defaults["dvalstr"]="NA"
    for (option in defaults) {
        if (!options[option]) options[option] = defaults[option]
    }
    rule_type=$2
    split($3,params," ")
    field=params[1]
    cat=params[3]
    field_index=header_index[field]
    test=""
    msg=""

    if (rule_type == "type") {
        type=params[2]
        if (type == "numeric"){
            test=field " && !is_numeric(" field ")"
            msg="Field " field " in \" FILENAME \" line \" NR \" should be a numeric but was \" " field " \" "
        }
    } else if (rule_type == "required") {
        test=field " == \"\""
        msg="Field " field " in \" FILENAME \" line \" NR \" is required"
    } else if (rule_type == "unique") {
        test="!is_unique(" field ")"
        msg="Field " field " in \" FILENAME \" line \" NR \" is a duplicate and should be unique"
    } else if (rule_type ~ /^min|max$/) {
        comparator=$2 == "max" ? ">" : "<"
        limit=params[2]
        term=$2 == "max" ? "less" : "greater"

        test=field " " comparator " " limit
        msg=field " in line \" NR \" should be " term " than " limit " and was \" " field " \" "
    } else if (rule_type == "pattern") {
        pattern=params[2]

        test=field " != \"\" && " field " !~ " pattern
        msg=field " in line \" NR \" should match the following pattern " pattern " and was \" " field " \" "
    }

    if (!options["mode"]) options["mode"] = "text"
    if (!options["dcat"]) options["dcat"] = "na"
    if (!cat) cat = options["dcat"]
    handler_prefix="{ log_err(\"" cat "\"); "
    if (options["mode"] == "text") {
        err_handler= handler_prefix "print \"" msg "\" RS $0 RS; }"
    } else if (options["mode"] == "wrap") {
        acc="$" field_index
        err_handler= handler_prefix "FS=\",\";" acc "=\">>\" " acc " \"<<\"; print $0 }"
    } else if (options["mode"] == "append") {
        err_handler= handler_prefix "print $0 FS \"" msg "\" }"
    }

    if (rule_type !~ /^(none|colmap)$/) { print "action == \"validate\" && NR > 1 && " test " " err_handler " " }
}

$1 == "field" {
    rule_type=$2
    split($3,params," ")
    field=params[1]

    if (rule_type ~ /^(min|max)$/ || (rule_type == "type" && params[2] == "numeric")) {
        types[field] = "numeric"
    } else if (rule_type != "colmap") {
        types[field] = "text"
    }

    if(rule_type == "colmap") mappings[field]=params[2]
}

END {
    print RS "# sanitize rules"
    print "action ~ /^(sanitize|insert)$/ && NR > 1 {"
    for (field in types) {
        type=types[field]
        field_index=header_index[field]
        dval= type == "numeric" ? options["dvalnum"] : options["dvalstr"]
        print "    if (" field " == \"\") $" field_index " = \"" dval "\""
    }
    print "}"

    print RS "# action handlers"
    print "action == \"insert\" && NR == 1 {"
    print "    print \"SET client_encoding = 'UTF8';\""
    print "    gsub(\"Range\", \"rangeno\");"
    print "    print \"COPY " options["table"] " (\" $0 \") FROM stdin;\""
    print "}"

    print "action == \"insert\" && NR > 1 {"
    print "    gsub(\",\", \"\t\");"
    print "    print;"
    print "}"

    print "action == \"table\" && NR == 1 {"

    fields=""
    l=length(headers)
    for (i in headers) {
        c++
        field=headers[i]
        type=types[field]
        if (length(mappings) && mappings[field]) field=mappings[field]
        fields=fields field " " type
        if (c < l) fields=fields ","
    }

    if(options["pkey"]) {
        cols=options["pkey"]
        gsub(":", ",", cols)
        fields=fields ", PRIMARY KEY (" cols ") "
    }
    if(options["fkey"]) {
        split(options["fkey"], ref, " ")
        ftable=ref[1]
        fcols=ref[2]
        gsub(":", ",", fcols)
        fields=fields ", FOREIGN KEY (" fcols ") REFERENCES " ftable " (" fcols ") MATCH FULL "
    }

    print "     print \"CREATE TABLE IF NOT EXISTS " options["table"] " (" fields ");\""
    print "}"

    print "action == \"sanitize\" { print }" RS

    print "# la fin"
    print "END {"
    print "    if (action == \"insert\") print \"\\\\.\""
    print "    if (action == \"validate\" && options[\"summary\"] == \"true\") { print RS \"violation summary: \" RS \"   counts:   \" RS \"      total: \" err_count; print_cats(cats); }"
    print "}"
}

#!/usr/bin/awk -F, -f

BEGIN {
    FS=","
    print "#!/usr/bin/awk -F, -f" RS

    print "# generated by: awk-csvalid https://github.com/tesera/awk-csvalid" RS
    print "# awk-csvalid csv toolset generator: https://github.com/tesera/awk-csvalid"
    print "# usage:"
    print "#    validate:     awk -f action=validate validator.awk > violations.txt"
    print "#    create table: awk -v action=table -f validator.awk | psql afgo_dev"
    print "#    sanitize csv: awk -v action=sanitize -f validator.awk > sanitized.csv"
    print "#    insert sql:   awk -v action=insert -f validator.awk | psql afgo_dev" RS
    print "# awk is a simple unix text file parser: http://www.gnu.org/software/gawk/manual/gawk.html"
    print "# awk primer:"
    print "#    NR = number/index current record"
    print "#    RS = record seperator new line i.e. \\n"
    print "#    FS = field seperator i.e. ,"
    print "#    /pattern/ { expression } = if pattern is truthy run expression" RS

    print "BEGIN {"
    print "    FS=\",\"; OFS=\",\"; err_count=0; cats[\"na\"]=0;"
    print "    if(!action) action == \"validate\""
    print "}" RS

    print "# builtin helper functions"
    print "function eql(x,y) {v=1; for (i in x) v=(v&&x[i]==y[i]); return v;}"
    print "function are_headers_valid(valid_headers) { v=0; split($0, h, \",\"); split(valid_headers, vh, \"|\"); return eql(h, vh); }"
    print "function is_unique(i, val) { if (vals[i,val]) { return 0; } else { vals[i,val] = 1; return 1; } }"
    print "function is_numeric(x){ return(x==x+0) }"
    print "function print_cats(categories) { for (category in categories) { if (categories[category]) print \"      \" category \": \" categories[category]; } }"
    print "function log_err(cat) { cats[cat]++; err_count++; }"
    print RS
}

$1 == "option" {
    options[$2]=$3;
}

$1 == "headers" && $2 == "names" {
    split($3, headers, "|")
    print "# make header index/map"
    print "NR > 1 {"
    for (i in headers) {
        header_name = headers[i]
        header_index[header_name] = i
        print "    " headers[i]  "=$" i
    }

    print "}" RS
    print "# awk rules based on user csv ruleset"
    print "NR == 1 { headers=\"" $3 "\"; if (!are_headers_valid(headers)) print \"invalid headers\" }"
}

$1 == "field" {
    rule_type=$2
    split($3,params," ")
    field=params[1]
    cat=params[3]
    field_index=header_index[field]
    test=""
    msg=""

    if (rule_type == "type") {
        type=params[2]
        if (type == "numeric"){
            test=field " && !is_numeric(" field ")"
            msg="Field " field " in \" FILENAME \" line \" NR \" should be a numeric but was \" " field " \" "
        }
    } else if (rule_type == "required") {
        test=field " == \"\""
        msg="Field " field " in \" FILENAME \" line \" NR \" is required"
    } else if (rule_type == "unique") {
        test="!is_unique(" field ")"
        msg="Field " field " in \" FILENAME \" line \" NR \" is a duplicate and should be unique"
    } else if (rule_type ~ /^min|max$/) {
        comparator=$2 == "max" ? ">" : "<"
        limit=params[2]
        term=$2 == "max" ? "less" : "greater"

        test=field " " comparator " " limit
        msg=field " in line \" NR \" should be " term " than " limit " and was \" " field " \" "
    } else if (rule_type == "pattern") {
        pattern=params[2]

        test=field " != \"\" && " field " !~ " pattern
        msg=field " in line \" NR \" should match the following pattern " pattern " and was \" " field " \" "
    }

    if (!options["mode"]) options["mode"] = "text"
    if (!options["dcat"]) options["dcat"] = "na"
    if (!cat) cat = options["dcat"]
    handler_prefix="{ log_err(\"" cat "\"); "
    if (options["mode"] == "text") {
        err_handler= handler_prefix "print \"" msg "\" RS $0 RS; }"
    } else if (options["mode"] == "wrap") {
        acc="$" field_index
        err_handler= handler_prefix "FS=\",\";" acc "=\">>\" " acc " \"<<\"; print $0 }"
    } else if (options["mode"] == "append") {
        err_handler= handler_prefix "print $0 FS \"" msg "\" }"
    }

    if (rule_type !~ /^(none|colmap)$/) { print "action == \"validate\" && NR > 1 && " test " " err_handler " " }
}

$1 == "field" {
    rule_type=$2
    split($3,params," ")
    field=params[1]

    if (rule_type ~ /^(min|max)$/ || (rule_type == "type" && params[2] == "numeric")) {
        types[field] = "numeric"
    } else if (rule_type != "colmap") {
        types[field] = "text"
    }

    if(rule_type == "colmap") mappings[field]=params[2]
}

END {
    print RS "# sanitize rules"
    print "action ~ /^(sanitize|insert)$/ && NR > 1 {"
    for (field in types) {
        type=types[field]
        field_index=header_index[field]
        dval= type == "numeric" ? options["dvalnum"] : options["dvalstr"]
        print "    if (" field " == \"\") $" field_index " = \"" dval "\""
    }
    print "}"

    print RS "# action handlers"
    print "action == \"insert\" && NR == 1 {"
    print "    print \"SET client_encoding = 'UTF8';\""
    print "    gsub(\"Range\", \"rangeno\");"
    print "    print \"COPY " options["table"] " (\" $0 \") FROM stdin;\""
    print "}"

    print "action == \"insert\" && NR > 1 {"
    print "    gsub(\",\", \"\t\");"
    print "    print;"
    print "}"

    print "action == \"table\" && NR == 1 {"

    fields=""
    l=length(headers)
    for (i in headers) {
        c++
        field=headers[i]
        type=types[field]
        if (length(mappings) && mappings[field]) field=mappings[field]
        fields=fields field " " type
        if (c < l) fields=fields ","
    }

    if(options["pkey"]) {
        cols=options["pkey"]
        gsub(":", ",", cols)
        fields=fields ", PRIMARY KEY (" cols ") "
    }
    if(options["fkey"]) {
        split(options["fkey"], ref, " ")
        ftable=ref[1]
        fcols=ref[2]
        gsub(":", ",", fcols)
        fields=fields ", FOREIGN KEY (" fcols ") REFERENCES " ftable " (" fcols ") MATCH FULL "
    }

    print "     print \"CREATE TABLE IF NOT EXISTS " options["table"] " (" fields ");\""
    print "}"

    print "action == \"sanitize\" { print }" RS

    print "# la fin"
    print "END {"
    print "    if (action == \"insert\") print \"\\\\.\""
    print "    if (action == \"validate\" && options[\"summary\"] == \"true\") { print RS \"violation summary: \" RS \"   counts:   \" RS \"      total: \" err_count; print_cats(cats); }"
    print "}"
}