Add Proxy-Authenticate as SIP tag

Add Proxy-Authenticate as SIP tag

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

BEGIN{
  first = 1;
}

/^Frame [0-9]+: (.*)/ {
  # New frame, closing
 and html> from previous frame before compute new filename
  if (first == 0) {
    printf "
\n" >filename
    printf " \n" >filename
    printf "\n" >filename
    printf "\n" >filename
  } else {
    first = 0
  }

  nbr = $2
  sub (":", "", nbr)
  filename = destDir "/frames/Frame" nbr ".html"
  printf "\n" >filename
  printf " \n" >filename
  printf "  <link rel=\"stylesheet\" type=\"text/css\" href=\"callflow.css\" />\n" >filename
  # The style tag is actually not desired, but it is needed as otherwise the
  # SIP messages are displayed incorrectly in dynamic presentation mode.
  # The java script used in the dynamic presentation mode does not read the stylesheet.
  printf "  \n" >filename
  printf "  <title>callflow - frame %s</title>\n", nbr >filename
  printf " \n" >filename
  printf " \n" >filename
  printf "
\n" >filename
  print $0 >filename
  # Print time
  getline
  gsub("^ *", "")
  print $0 >filename;
  discard = 1;
}
/^Internet Protocol,/ {
  print $0 >filename;
  discard = 1;
}
/^Internet Protocol$/ {
  discard = 0;
}
/^User Datagram Protocol,/ {
  print $0 >filename;
  discard = 1;
}
/^User Datagram Protocol$/ {
  discard = 0;
}
/^Transmission Control Protocol,/ {
  print $0 >filename;
  discard = 1;
}
/^Transmission Control Protocol$/ {
  discard = 0;
}
/^Internet Control Message Protocol/ {
  discard = 0;
}
/^Session Initiation Protocol/ {
  discard = 0;
}
/^Diameter Protocol/ {
  discard = 0;
}
/^WebSocket Protocol/ {
  discard = 0;
}
/^Hypertext Transfer Protocol/ {
  discard = 0;
}
/^Call Specification Language/ {
  discard = 0;
}
{
  if (discard==0)
    {

      gsub("&","\\&");
      gsub(">","\\>");
      gsub("<","\\<");

      MARK = "no"
      # Abbreviated SIP messages
      if ($1 == "c:" ) MARK = "sip"
      if ($1 == "f:" ) MARK = "sip"
      if ($1 == "i:" ) MARK = "sip"
      if ($1 == "k:" ) MARK = "sip"
      if ($1 == "l:" ) MARK = "sip"
      if ($1 == "m:" ) MARK = "sip"
      if ($1 == "t:" ) MARK = "sip"
      if ($1 == "v:" ) MARK = "sip"

      # SIP messages
      if ($0 ~ "Session Initiation Protocol" ) MARK = "sip"
      if ($1 ~ "Accept:" ) MARK = "sip"
      if ($1 ~ "Alert-Info:" ) MARK = "sip"
      if ($1 ~ "Allow:" ) MARK = "sip"
      if ($1 ~ "Allow-Events:" ) MARK = "sip"
      if ($0 ~ "Call-ID:" ) MARK = "sip"
      if ($1 ~ "Charge:" ) MARK = "sip"
      if ($1 ~ "Contact:" ) MARK = "sip"
      if ($1 ~ "Content-Disposition:" ) MARK = "sip"
      if ($1 ~ "Content-Length:" ) MARK = "sip"
      if ($1 ~ "Content-Type:" ) MARK = "sip"
      if ($1 ~ "CSeq:" ) MARK = "sip"
      if ($1 ~ "Date:" ) MARK = "sip"
      if ($1 ~ "Expires:" ) MARK = "sip"
      if ($1 ~ "From:" ) MARK = "sip"
      if ($1 ~ "Min-SE:" ) MARK = "sip"
      if ($1 ~ "P-[A-Z][a-z].*:" ) MARK = "sip"
      if ($1 ~ "Privacy:" ) MARK = "sip"
      if ($1 ~ "Proxy-Authenticate:" ) MARK = "sip"
      if ($1 ~ "RAck:" ) MARK = "sip"
      if ($1 ~ "Remote-Party-ID:" ) MARK = "sip"
      if ($1 ~ "Require:" ) MARK = "sip"
      if ($1 ~ "Request-Line:" ) MARK = "sip"
      if ($1 ~ "Request-Disposition:" ) MARK = "sip"
      if ($1 ~ "Route:" ) MARK = "sip"
      if ($1 ~ "RSeq:" ) MARK = "sip"
      if ($1 ~ "Server:" ) MARK = "sip"
      if ($1 ~ "Supported:" ) MARK = "sip"
      if ($1 ~ "Timestamp:" ) MARK = "sip"
      if ($1 ~ "To:" ) MARK = "sip"
      if ($1 ~ "User-Agent:" ) MARK = "sip"
      if ($1 ~ "Via:" ) MARK = "sip"

      # SDP part
      if ($0 ~ "Session Description Protocol") MARK = "media"
      if ($0 ~ "Connection Information") MARK = "media"
      # Use ... here.  Actually "(a)" should be used, but awk does not like the
      # parenthesis (), workaround it with the dots.
      if ($0 ~ "Media Attribute .a.:") MARK = "media"
      if ($0 ~ "Media Description, name and address") MARK = "media"
      if ($0 ~ "Owner/Creator, Session Id") MARK = "media"
      if ($0 ~ "Session Attribute .a.:") MARK = "media"
      if ($0 ~ "Session Description Protocol Version") MARK = "media"
      if ($0 ~ "Session Name") MARK = "media"
      if ($0 ~ "Time Description, active time") MARK = "media"

      if (MARK == "sip") {
        printf "
%s
\n", $0 > filename;

      } else if (MARK == "media") {
        printf "
%s
\n", $0 > filename;

      } else {
        print $0 > filename;
      }
    }
}
END {
  printf "
\n" >filename
  printf " \n" >filename
  printf "\n" >filename
  printf "\n" >filename
}

BEGIN{
  first = 1;
}

/^Frame [0-9]+: (.*)/ {
  # New frame, closing
 and html> from previous frame before compute new filename
  if (first == 0) {
    printf "
\n" >filename
    printf " \n" >filename
    printf "\n" >filename
    printf "\n" >filename
  } else {
    first = 0
  }

  nbr = $2
  sub (":", "", nbr)
  filename = destDir "/frames/Frame" nbr ".html"
  printf "\n" >filename
  printf " \n" >filename
  printf "  <link rel=\"stylesheet\" type=\"text/css\" href=\"callflow.css\" />\n" >filename
  # The style tag is actually not desired, but it is needed as otherwise the
  # SIP messages are displayed incorrectly in dynamic presentation mode.
  # The java script used in the dynamic presentation mode does not read the stylesheet.
  printf "  \n" >filename
  printf "  <title>callflow - frame %s</title>\n", nbr >filename
  printf " \n" >filename
  printf " \n" >filename
  printf "
\n" >filename
  print $0 >filename
  # Print time
  getline
  gsub("^ *", "")
  print $0 >filename;
  discard = 1;
}
/^Internet Protocol,/ {
  print $0 >filename;
  discard = 1;
}
/^Internet Protocol$/ {
  discard = 0;
}
/^User Datagram Protocol,/ {
  print $0 >filename;
  discard = 1;
}
/^User Datagram Protocol$/ {
  discard = 0;
}
/^Transmission Control Protocol,/ {
  print $0 >filename;
  discard = 1;
}
/^Transmission Control Protocol$/ {
  discard = 0;
}
/^Internet Control Message Protocol/ {
  discard = 0;
}
/^Session Initiation Protocol/ {
  discard = 0;
}
/^Diameter Protocol/ {
  discard = 0;
}
/^WebSocket Protocol/ {
  discard = 0;
}
/^Hypertext Transfer Protocol/ {
  discard = 0;
}
/^Call Specification Language/ {
  discard = 0;
}
{
  if (discard==0)
    {

      gsub("&","\\&");
      gsub(">","\\>");
      gsub("<","\\<");

      MARK = "no"
      # Abbreviated SIP messages
      if ($1 == "c:" ) MARK = "sip"
      if ($1 == "f:" ) MARK = "sip"
      if ($1 == "i:" ) MARK = "sip"
      if ($1 == "k:" ) MARK = "sip"
      if ($1 == "l:" ) MARK = "sip"
      if ($1 == "m:" ) MARK = "sip"
      if ($1 == "t:" ) MARK = "sip"
      if ($1 == "v:" ) MARK = "sip"

      # SIP messages
      if ($0 ~ "Session Initiation Protocol" ) MARK = "sip"
      if ($1 ~ "Accept:" ) MARK = "sip"
      if ($1 ~ "Alert-Info:" ) MARK = "sip"
      if ($1 ~ "Allow:" ) MARK = "sip"
      if ($1 ~ "Allow-Events:" ) MARK = "sip"
      if ($0 ~ "Call-ID:" ) MARK = "sip"
      if ($1 ~ "Charge:" ) MARK = "sip"
      if ($1 ~ "Contact:" ) MARK = "sip"
      if ($1 ~ "Content-Disposition:" ) MARK = "sip"
      if ($1 ~ "Content-Length:" ) MARK = "sip"
      if ($1 ~ "Content-Type:" ) MARK = "sip"
      if ($1 ~ "CSeq:" ) MARK = "sip"
      if ($1 ~ "Date:" ) MARK = "sip"
      if ($1 ~ "Expires:" ) MARK = "sip"
      if ($1 ~ "From:" ) MARK = "sip"
      if ($1 ~ "Min-SE:" ) MARK = "sip"
      if ($1 ~ "P-[A-Z][a-z].*:" ) MARK = "sip"
      if ($1 ~ "Privacy:" ) MARK = "sip"
      if ($1 ~ "RAck:" ) MARK = "sip"
      if ($1 ~ "Remote-Party-ID:" ) MARK = "sip"
      if ($1 ~ "Require:" ) MARK = "sip"
      if ($1 ~ "Request-Line:" ) MARK = "sip"
      if ($1 ~ "Request-Disposition:" ) MARK = "sip"
      if ($1 ~ "Route:" ) MARK = "sip"
      if ($1 ~ "RSeq:" ) MARK = "sip"
      if ($1 ~ "Server:" ) MARK = "sip"
      if ($1 ~ "Supported:" ) MARK = "sip"
      if ($1 ~ "Timestamp:" ) MARK = "sip"
      if ($1 ~ "To:" ) MARK = "sip"
      if ($1 ~ "User-Agent:" ) MARK = "sip"
      if ($1 ~ "Via:" ) MARK = "sip"

      # SDP part
      if ($0 ~ "Session Description Protocol") MARK = "media"
      if ($0 ~ "Connection Information") MARK = "media"
      # Use ... here.  Actually "(a)" should be used, but awk does not like the
      # parenthesis (), workaround it with the dots.
      if ($0 ~ "Media Attribute .a.:") MARK = "media"
      if ($0 ~ "Media Description, name and address") MARK = "media"
      if ($0 ~ "Owner/Creator, Session Id") MARK = "media"
      if ($0 ~ "Session Attribute .a.:") MARK = "media"
      if ($0 ~ "Session Description Protocol Version") MARK = "media"
      if ($0 ~ "Session Name") MARK = "media"
      if ($0 ~ "Time Description, active time") MARK = "media"

      if (MARK == "sip") {
        printf "
%s
\n", $0 > filename;

      } else if (MARK == "media") {
        printf "
%s
\n", $0 > filename;

      } else {
        print $0 > filename;
      }
    }
}
END {
  printf "
\n" >filename
  printf " \n" >filename
  printf "\n" >filename
  printf "\n" >filename
}


convert edge lables from quoted strings to 'html-like' to highlight losses

#! /usr/bin/gawk -f

# label_dot_edge.awk
# Augment ontological terms with their label
# example usage:
# ${DIPPER}/scripts/label_dot_edge.awk
#    ${DIPPER}/translationtable/GLOBAL_TERMS.yaml  in.dot > out.dot
#
# Arguments: two files
# Loads the first file as a map from  to curie to label :
# (expects: "label": "curie:term",)
# Reads the second Graphviz digraph dot format file:
# looks for <term> as edge-text
# and appends "! <label> (Iff curie:term is found in the translation table)
# note: This "<term> ! <label>" structure is a convention used by Ontologists.

BEGIN{
    FS="\""q
    # EDGE = /^[^ ]+ -> [^ ]+ [[]label=[<][^:]+:[^ ]+ [(][0-9]*[)]>[]];$/
}
# load label->curie:term  as curie:term -> label
FNR == NR && /^"/{
    label[$4]=$2
}

# output graphviz lines that do not get labels
FNR != NR && !/^[^ ]+ -> [^ ]+ [[]label=[<][^:]+:[^ ]+ [(][0-9]*[)]>[]];$/

# output lines w/labels if they are available
FNR != NR && /^[^ ]+ -> [^ ]+ [[]label=[<][^:]+:[^ ]+ [(][0-9]*[)]>[]];$/{
    line="";
    split($0, row, " ")
    split(row[4], term, /[><]/)
    split(term[2], lclid, ":")

    if(term[2] in label && lclid[2] != label[term[2]])
        row[4] = term[1] "<" term[2] " ! " label[term[2]]
    line = row[1]
    for(i=2;i<=length(row);i++)
        line = line " " row[i]
    print line
}

#! /usr/bin/gawk -f

# label_dot_edge.awk
# Augment ontological terms with their label
# example usage:
# ${DIPPER}/scripts/label_dot_edge.awk
#	${DIPPER}/translationtable/GLOBAL_TERMS.yaml  in.dot > out.dot
#
# Arguments: two files
# Loads the first file as a map from  to curie to label :
 # (expects: "label": "curie:term",)
# Reads the second Graphviz digraph dot format file:
# looks for <term> as edge-text
# and appends "! <label> (Iff curie:term is found in the translation table)
# note: This "<term> ! <label>" structure is a convention used by Ontologists.

BEGIN{FS="\""; OFS="\t"}
# load label->curie:term  as curie:term -> label
FNR == NR && /^"/{label[$4]=$2}

# output graphviz lines that do not get labels
FNR != NR && ! /.* -> .* [label=<.*>];/ {print}

# output lines w/labels if they are available
FNR != NR && /.* -> .* [label=<.*>];/ {
	line="";
	split($0, row, / /)
	split(row[4], term, /<>/)
	split(term[2], lclid, ":")

	if (term[2] in label && lclid[2] != label[term[2]])
		row[4] = term[1] "<" term[2] " ! " label[term[2]] ">" term[3]
	line = row[1]
	for(i=2;i<=length(row);i++)
		line = line " " row[i]
	print  line
}


better handling of locale * fix Debian#768217 (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=768217)

####################################################################
# Languages.awk                                                    #
####################################################################

# Initialize all supported locales.
# Mostly ISO 639-1 codes, with a few ISO 639-2 codes (alpha-3).
# See: <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>
#      <http://www.loc.gov/standards/iso639-2/php/code_list.php>
function initLocale() {

    #1 Afrikaans
    Locale["af"]["name"]       = "Afrikaans"
    Locale["af"]["endonym"]    = "Afrikaans"
    Locale["af"]["message"]    = "Vertalings van %s"

    #2 Albanian
    Locale["sq"]["name"]       = "Albanian"
    Locale["sq"]["endonym"]    = "Shqip"
    Locale["sq"]["message"]    = "Përkthimet e %s"

    #3 Arabic
    Locale["ar"]["name"]       = "Arabic"
    Locale["ar"]["endonym"]    = "العربية"
    Locale["ar"]["message"]    = "ترجمات %s"
    Locale["ar"]["rtl"]        = "true" # RTL language

    #4 Armenian
    Locale["hy"]["name"]       = "Armenian"
    Locale["hy"]["endonym"]    = "Հայերեն"
    Locale["hy"]["message"]    = "%s-ի թարգմանությունները"

    #5 Azerbaijani
    Locale["az"]["name"]       = "Azerbaijani"
    Locale["az"]["endonym"]    = "Azərbaycanca"
    Locale["az"]["message"]    = "%s sözünün tərcüməsi"

    #6 Basque
    Locale["eu"]["name"]       = "Basque"
    Locale["eu"]["endonym"]    = "Euskara"
    Locale["eu"]["message"]    = "%s esapidearen itzulpena"

    #7 Belarusian (Cyrillic alphabet)
    Locale["be"]["name"]       = "Belarusian"
    Locale["be"]["endonym"]    = "беларуская"
    Locale["be"]["message"]    = "Пераклады %s"

    #8 Bengali
    Locale["bn"]["name"]       = "Bengali"
    Locale["bn"]["endonym"]    = "বাংলা"
    Locale["bn"]["message"]    = "%s এর অনুবাদ"

    #9 Bosnian (Latin alphabet)
    Locale["bs"]["name"]       = "Bosnian"
    Locale["bs"]["endonym"]    = "Bosanski"
    Locale["bs"]["message"]    = "Prijevod za: %s"

    #10 Bulgarian
    Locale["bg"]["name"]       = "Bulgarian"
    Locale["bg"]["endonym"]    = "български"
    Locale["bg"]["message"]    = "Преводи на %s"

    #11 Catalan
    Locale["ca"]["name"]       = "Catalan"
    Locale["ca"]["endonym"]    = "Català"
    Locale["ca"]["message"]    = "Traduccions per a %s"

    #12 Cebuano
    Locale["ceb"]["name"]      = "Cebuano"
    Locale["ceb"]["endonym"]   = "Cebuano"
    Locale["ceb"]["message"]   = "%s Mga Paghubad sa PULONG_O_HUGPONG SA PAMULONG"

    #13a Chinese (Simplified)
    Locale["zh-CN"]["name"]    = "Chinese Simplified"
    Locale["zh-CN"]["endonym"] = "简体中文"
    Locale["zh-CN"]["message"] = "%s 的翻译"

    #13b Chinese (Traditional)
    Locale["zh-TW"]["name"]    = "Chinese Traditional"
    Locale["zh-TW"]["endonym"] = "正體中文"
    Locale["zh-TW"]["message"] = "「%s」的翻譯"

    #14 Croatian
    Locale["hr"]["name"]       = "Croatian"
    Locale["hr"]["endonym"]    = "Hrvatski"
    Locale["hr"]["message"]    = "Prijevodi riječi ili izraza %s"

    #15 Czech
    Locale["cs"]["name"]       = "Czech"
    Locale["cs"]["endonym"]    = "Čeština"
    Locale["cs"]["message"]    = "Překlad výrazu %s"

    #16 Danish
    Locale["da"]["name"]       = "Danish"
    Locale["da"]["endonym"]    = "Dansk"
    Locale["da"]["message"]    = "Oversættelser af %s"

    #17 Dutch
    Locale["nl"]["name"]       = "Dutch"
    Locale["nl"]["endonym"]    = "Nederlands"
    Locale["nl"]["message"]    = "Vertalingen van %s"

    #18 English
    Locale["en"]["name"]       = "English"
    Locale["en"]["endonym"]    = "English"
    Locale["en"]["message"]    = "Translations of %s"

    #19 Esperanto
    Locale["eo"]["name"]       = "Esperanto"
    Locale["eo"]["endonym"]    = "Esperanto"
    Locale["eo"]["message"]    = "Tradukoj de %s"

    #20 Estonian
    Locale["et"]["name"]       = "Estonian"
    Locale["et"]["endonym"]    = "Eesti"
    Locale["et"]["message"]    = "Sõna(de) %s tõlked"

    #21 Filipino
    Locale["tl"]["name"]       = "Filipino"
    Locale["tl"]["endonym"]    = "Tagalog"
    Locale["tl"]["message"]    = "Mga pagsasalin ng %s"

    #22 Finnish
    Locale["fi"]["name"]       = "Finnish"
    Locale["fi"]["endonym"]    = "Suomi"
    Locale["fi"]["message"]    = "Käännökset tekstille %s"

    #23 French
    Locale["fr"]["name"]       = "French"
    Locale["fr"]["endonym"]    = "Français"
    Locale["fr"]["message"]    = "Traductions de %s"

    #24 Galician
    Locale["gl"]["name"]       = "Galician"
    Locale["gl"]["endonym"]    = "Galego"
    Locale["gl"]["message"]    = "Traducións de %s"

    #25 Georgian
    Locale["ka"]["name"]       = "Georgian"
    Locale["ka"]["endonym"]    = "ქართული"
    Locale["ka"]["message"]    = "%s-ის თარგმანები"

    #26 German
    Locale["de"]["name"]       = "German"
    Locale["de"]["endonym"]    = "Deutsch"
    Locale["de"]["message"]    = "Übersetzungen für %s"

    #27 Greek
    Locale["el"]["name"]       = "Greek"
    Locale["el"]["endonym"]    = "Ελληνικά"
    Locale["el"]["message"]    = "Μεταφράσεις του %s"

    #28 Gujarati
    Locale["gu"]["name"]       = "Gujarati"
    Locale["gu"]["endonym"]    = "ગુજરાતી"
    Locale["gu"]["message"]    = "%s ના અનુવાદ"

    #29 Haitian Creole
    Locale["ht"]["name"]       = "Haitian Creole"
    Locale["ht"]["endonym"]    = "Kreyòl Ayisyen"
    Locale["ht"]["message"]    = "Tradiksyon %s"

    #30 Hausa (Latin / Boko alphabet)
    Locale["ha"]["name"]       = "Hausa"
    Locale["ha"]["endonym"]    = "Hausa"
    Locale["ha"]["message"]    = "Fassarar %s"

    #31 Hebrew
    Locale["he"]["name"]       = "Hebrew"
    Locale["he"]["endonym"]    = "עִבְרִית"
    Locale["he"]["message"]    = "תרגומים של %s"
    Locale["he"]["rtl"]        = "true" # RTL language

    #32 Hindi
    Locale["hi"]["name"]       = "Hindi"
    Locale["hi"]["endonym"]    = "हिन्दी"
    Locale["hi"]["message"]    = "%s के अनुवाद"

    #33 Hmong
    Locale["hmn"]["name"]      = "Hmong"
    Locale["hmn"]["endonym"]   = "Hmoob"
    Locale["hmn"]["message"]   = "Lus txhais: %s"

    #34 Hungarian
    Locale["hu"]["name"]       = "Hungarian"
    Locale["hu"]["endonym"]    = "Magyar"
    Locale["hu"]["message"]    = "%s fordításai"

    #35 Icelandic
    Locale["is"]["name"]       = "Icelandic"
    Locale["is"]["endonym"]    = "Íslenska"
    Locale["is"]["message"]    = "Þýðingar á %s"

    #36 Igbo
    Locale["ig"]["name"]       = "Igbo"
    Locale["ig"]["endonym"]    = "Igbo"
    Locale["ig"]["message"]    = "Ntụgharị asụsụ nke %s"

    #37 Indonesian
    Locale["id"]["name"]       = "Indonesian"
    Locale["id"]["endonym"]    = "Bahasa Indonesia"
    Locale["id"]["message"]    = "Terjemahan dari %s"

    #38 Irish
    Locale["ga"]["name"]       = "Irish"
    Locale["ga"]["endonym"]    = "Gaeilge"
    Locale["ga"]["message"]    = "Aistriúcháin ar %s"

    #39 Italian
    Locale["it"]["name"]       = "Italian"
    Locale["it"]["endonym"]    = "Italiano"
    Locale["it"]["message"]    = "Traduzioni di %s"

    #40 Japanese
    Locale["ja"]["name"]       = "Japanese"
    Locale["ja"]["endonym"]    = "日本語"
    Locale["ja"]["message"]    = "「%s」の翻訳"

    #41 Javanese (Latin alphabet)
    Locale["jv"]["name"]       = "Javanese"
    Locale["jv"]["endonym"]    = "Basa Jawa"
    Locale["jv"]["message"]    = "Terjemahan"

    #42 Kannada
    Locale["kn"]["name"]       = "Kannada"
    Locale["kn"]["endonym"]    = "ಕನ್ನಡ"
    Locale["kn"]["message"]    = "%s ನ ಅನುವಾದಗಳು"

    #43 Khmer (Central Khmer)
    Locale["km"]["name"]       = "Khmer"
    Locale["km"]["endonym"]    = "ភាសាខ្មែរ"
    Locale["km"]["message"]    = "ការបកប្រែនៃ %s"

    #44 Korean
    Locale["ko"]["name"]       = "Korean"
    Locale["ko"]["endonym"]    = "한국어"
    Locale["ko"]["message"]    = "%s의 번역"

    #45 Lao
    Locale["lo"]["name"]       = "Lao"
    Locale["lo"]["endonym"]    = "ລາວ"
    Locale["lo"]["message"]    = "ການແປພາສາຂອງ %s"

    #46 Latin
    Locale["la"]["name"]       = "Latin"
    Locale["la"]["endonym"]    = "Latina"
    Locale["la"]["message"]    = "Versio de %s"

    #47 Latvian
    Locale["lv"]["name"]       = "Latvian"
    Locale["lv"]["endonym"]    = "Latviešu"
    Locale["lv"]["message"]    = "%s tulkojumi"

    #48 Lithuanian
    Locale["lt"]["name"]       = "Lithuanian"
    Locale["lt"]["endonym"]    = "Lietuvių"
    Locale["lt"]["message"]    = "„%s“ vertimai"

    #49 Macedonian
    Locale["mk"]["name"]       = "Macedonian"
    Locale["mk"]["endonym"]    = "Македонски"
    Locale["mk"]["message"]    = "Преводи на %s"

    #50 Malay
    Locale["ms"]["name"]       = "Malay"
    Locale["ms"]["endonym"]    = "Bahasa Melayu"
    Locale["ms"]["message"]    = "Terjemahan %s"

    #51 Maltese
    Locale["mt"]["name"]       = "Maltese"
    Locale["mt"]["endonym"]    = "Malti"
    Locale["mt"]["message"]    = "Traduzzjonijiet ta' %s"

    #52 Maori
    Locale["mi"]["name"]       = "Maori"
    Locale["mi"]["endonym"]    = "Māori"
    Locale["mi"]["message"]    = "Ngā whakamāoritanga o %s"

    #53 Marathi
    Locale["mr"]["name"]       = "Marathi"
    Locale["mr"]["endonym"]    = "मराठी"
    Locale["mr"]["message"]    = "%s ची भाषांतरे"

    #54 Mongolian (Cyrillic alphabet)
    Locale["mn"]["name"]       = "Mongolian"
    Locale["mn"]["endonym"]    = "Монгол"
    Locale["mn"]["message"]    = "%s-н орчуулга"

    #55 Nepali
    Locale["ne"]["name"]       = "Nepali"
    Locale["ne"]["endonym"]    = "नेपाली"
    Locale["ne"]["message"]    = "%sका अनुवाद"

    #56 Norwegian
    Locale["no"]["name"]       = "Norwegian"
    Locale["no"]["endonym"]    = "Norsk"
    Locale["no"]["message"]    = "Oversettelser av %s"

    #57 Persian
    Locale["fa"]["name"]       = "Persian"
    Locale["fa"]["endonym"]    = "فارسی"
    Locale["fa"]["message"]    = "ترجمه‌های %s"
    Locale["fa"]["rtl"]        = "true" # RTL language

    #58 Punjabi (Brahmic / Gurmukhī alphabet)
    Locale["pa"]["name"]       = "Punjabi"
    Locale["pa"]["endonym"]    = "ਪੰਜਾਬੀ"
    Locale["pa"]["message"]    = "ਦੇ ਅਨੁਵਾਦ%s"

    #59 Polish
    Locale["pl"]["name"]       = "Polish"
    Locale["pl"]["endonym"]    = "Polski"
    Locale["pl"]["message"]    = "Tłumaczenia %s"

    #60 Portuguese
    Locale["pt"]["name"]       = "Portuguese"
    Locale["pt"]["endonym"]    = "Português"
    Locale["pt"]["message"]    = "Traduções de %s"

    #61 Romanian
    Locale["ro"]["name"]       = "Romanian"
    Locale["ro"]["endonym"]    = "Română"
    Locale["ro"]["message"]    = "Traduceri pentru %s"

    #62 Russian
    Locale["ru"]["name"]       = "Russian"
    Locale["ru"]["endonym"]    = "Русский"
    Locale["ru"]["message"]    = "%s: варианты перевода"

    #63 Serbian (Cyrillic alphabet)
    Locale["sr"]["name"]       = "Serbian"
    Locale["sr"]["endonym"]    = "српски"
    Locale["sr"]["message"]    = "Преводи за „%s“"

    #64 Slovak
    Locale["sk"]["name"]       = "Slovak"
    Locale["sk"]["endonym"]    = "Slovenčina"
    Locale["sk"]["message"]    = "Preklady výrazu: %s"

    #65 Slovenian
    Locale["sl"]["name"]       = "Slovenian"
    Locale["sl"]["endonym"]    = "Slovenščina"
    Locale["sl"]["message"]    = "Prevodi za %s"

    #66 Somali
    Locale["so"]["name"]       = "Somali"
    Locale["so"]["endonym"]    = "Soomaali"
    Locale["so"]["message"]    = "Turjumaada %s"

    #67 Spanish
    Locale["es"]["name"]       = "Spanish"
    Locale["es"]["endonym"]    = "Español"
    Locale["es"]["message"]    = "Traducciones de %s"

    #68 Swahili
    Locale["sw"]["name"]       = "Swahili"
    Locale["sw"]["endonym"]    = "Kiswahili"
    Locale["sw"]["message"]    = "Tafsiri ya %s"

    #69 Swedish
    Locale["sv"]["name"]       = "Swedish"
    Locale["sv"]["endonym"]    = "Svenska"
    Locale["sv"]["message"]    = "Översättningar av %s"

    #70 Tamil
    Locale["ta"]["name"]       = "Tamil"
    Locale["ta"]["endonym"]    = "தமிழ்"
    Locale["ta"]["message"]    = "%s இன் மொழிபெயர்ப்புகள்"

    #71 Telugu
    Locale["te"]["name"]       = "Telugu"
    Locale["te"]["endonym"]    = "తెలుగు"
    Locale["te"]["message"]    = "%s యొక్క అనువాదాలు"

    #72 Thai
    Locale["th"]["name"]       = "Thai"
    Locale["th"]["endonym"]    = "ไทย"
    Locale["th"]["message"]    = "คำแปลของ %s"

    #73 Turkish
    Locale["tr"]["name"]       = "Turkish"
    Locale["tr"]["endonym"]    = "Türkçe"
    Locale["tr"]["message"]    = "%s çevirileri"

    #74 Ukrainian
    Locale["uk"]["name"]       = "Ukrainian"
    Locale["uk"]["endonym"]    = "Українська"
    Locale["uk"]["message"]    = "Переклади слова або виразу \"%s\""

    #75 Urdu
    Locale["ur"]["name"]       = "Urdu"
    Locale["ur"]["endonym"]    = "اُردُو"
    Locale["ur"]["message"]    = "کے ترجمے %s"
    Locale["ur"]["rtl"]        = "true" # RTL language

    #76 Vietnamese
    Locale["vi"]["name"]       = "Vietnamese"
    Locale["vi"]["endonym"]    = "Tiếng Việt"
    Locale["vi"]["message"]    = "Bản dịch của %s"

    #77 Welsh
    Locale["cy"]["name"]       = "Welsh"
    Locale["cy"]["endonym"]    = "Cymraeg"
    Locale["cy"]["message"]    = "Cyfieithiadau %s"

    #78 Yiddish
    Locale["yi"]["name"]       = "Yiddish"
    Locale["yi"]["endonym"]    = "ייִדיש"
    Locale["yi"]["message"]    = "איבערזעצונגען פון %s"
    Locale["yi"]["rtl"]        = "true" # RTL language

    #79 Yoruba
    Locale["yo"]["name"]       = "Yoruba"
    Locale["yo"]["endonym"]    = "Yorùbá"
    Locale["yo"]["message"]    = "Awọn itumọ ti %s"

    #80 Zulu
    Locale["zu"]["name"]       = "Zulu"
    Locale["zu"]["endonym"]    = "isiZulu"
    Locale["zu"]["message"]    = "Ukuhumusha i-%s"

    # Aliases for some locales
    # See: <http://www.loc.gov/standards/iso639-2/php/code_changes.php>
    LocaleAlias["in"] = "id" # withdrawn language code for Indonesian
    LocaleAlias["iw"] = "he" # withdrawn language code for Hebrew
    LocaleAlias["ji"] = "yi" # withdrawn language code for Yiddish

    LocaleAlias["jw"] = "jv" # withdrawn language code for Javanese
    LocaleAlias["mo"] = "ro" # Moldavian or Moldovan considered a variant of the Romanian language
    LocaleAlias["sh"] = "sr" # Serbo-Croatian: prefer Serbian
    LocaleAlias["zh"] = "zh-CN" # Chinese: prefer Chinese Simplified
    LocaleAlias["zh-cn"] = "zh-CN" # lowercase
    LocaleAlias["zh-tw"] = "zh-TW" # lowercase
    # TODO: any more aliases supported by Google Translate?
}

# Get locale key by language code or alias.
function getCode(code) {
    code = tolower(code) # case-insensitive

    if (code in Locale || code == "auto")
        return code
    else if (code in LocaleAlias)
        return LocaleAlias[code]
    else
        return # return nothing if not found
}

# Detect external bidirectional algorithm utility (fribidi);
# Fallback to Unix `rev` if not found.
function initBiDi() {
    "fribidi --version 2>/dev/null" |& getline FriBidi
    BiDiNoPad = FriBidi ? "fribidi --nopad" : "rev"
    BiDi = FriBidi ? "fribidi --width %s" : "rev | sed \"s/'/\\\\\\'/\" | xargs printf '%%s '"
}

# Convert a logical string to visual; don't right justify RTL lines.
# Parameters:
#     code: ignore to apply bidirectional algorithm on every string
function show(text, code,    temp) {
    if (!code || Locale[getCode(code)]["rtl"]) {
        if (Cache[text][0])
            return Cache[text][0]
        else {
            if (FriBidi || (code && Locale[getCode(code)]["rtl"]))
                ("echo " parameterize(text) " | " BiDiNoPad) | getline temp
            else # non-RTL language, or FriBidi not installed
                temp = text
            return Cache[text][0] = temp
        }
    } else
        return text
}

# Convert a logical string to visual and right justify RTL lines.
# Parameters:
#     code: ignore to apply bidirectional algorithm on every string
#     width: ignore to use default width for padding
function s(text, code, width,    temp) {
    if (!code || Locale[getCode(code)]["rtl"]) {
        if (!width) width = Option["width"]
        if (Cache[text][width])
            return Cache[text][width]
        else {
            if (FriBidi || (code && Locale[getCode(code)]["rtl"]))
                ("echo " parameterize(text) " | " sprintf(BiDi, width)) | getline temp
            else # non-RTL language, or FriBidi not installed
                temp = text
            return Cache[text][width] = temp
        }
    } else
        return text
}

# Initialize strings for displaying endonyms of locales.
function initLocaleDisplay(    i) {
    for (i in Locale)
        Locale[i]["display"] = show(Locale[i]["endonym"], i)
}

# Parse a POSIX locale identifier and return the language code;
# Identified by both language identifier and region identifier.
# Parameters:
#     lang = [language[_territory][.codeset][@modifier]]
# See: <https://en.wikipedia.org/wiki/Locale>
function parseLang(lang,    code, group) {
    match(lang, /^([a-z][a-z][a-z]?)(_|$)/, group)
    code = getCode(group[1])

    # Detect region identifier
    ## Regions using Chinese Simplified: China, Singapore
    if (lang ~ /^zh_(CN|SG)/) code = "zh-CN"
    ## Regions using Chinese Traditional: Taiwan, Hong Kong
    else if (lang ~ /^zh_(TW|HK)/) code = "zh-TW"

    # FIXME: handle unrecognized language code
    if (!code) code = "en"

    return code
}

# Initialize `UserLang`.
function initUserLang() {
    UserLang = ENVIRON["LC_CTYPE"] ?
        parseLang(ENVIRON["LC_CTYPE"]) :
        (ENVIRON["LANG"] ?
         parseLang(ENVIRON["LANG"]) :
         "en")

    if (tolower(ENVIRON["LANG"]) !~ /utf-?8$/ && tolower(ENVIRON["LC_CTYPE"]) !~ /utf-?8$/)
        w("[WARNING] Your locale codeset (" ENVIRON["LANG"] ") is not UTF-8. You have been warned.")
}

####################################################################
# Languages.awk                                                    #
####################################################################

# Initialize all supported locales.
# Mostly ISO 639-1 codes, with a few ISO 639-2 codes (alpha-3).
# See: <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>
#      <http://www.loc.gov/standards/iso639-2/php/code_list.php>
function initLocale() {

    #1 Afrikaans
    Locale["af"]["name"]       = "Afrikaans"
    Locale["af"]["endonym"]    = "Afrikaans"
    Locale["af"]["message"]    = "Vertalings van %s"

    #2 Albanian
    Locale["sq"]["name"]       = "Albanian"
    Locale["sq"]["endonym"]    = "Shqip"
    Locale["sq"]["message"]    = "Përkthimet e %s"

    #3 Arabic
    Locale["ar"]["name"]       = "Arabic"
    Locale["ar"]["endonym"]    = "العربية"
    Locale["ar"]["message"]    = "ترجمات %s"
    Locale["ar"]["rtl"]        = "true" # RTL language

    #4 Armenian
    Locale["hy"]["name"]       = "Armenian"
    Locale["hy"]["endonym"]    = "Հայերեն"
    Locale["hy"]["message"]    = "%s-ի թարգմանությունները"

    #5 Azerbaijani
    Locale["az"]["name"]       = "Azerbaijani"
    Locale["az"]["endonym"]    = "Azərbaycanca"
    Locale["az"]["message"]    = "%s sözünün tərcüməsi"

    #6 Basque
    Locale["eu"]["name"]       = "Basque"
    Locale["eu"]["endonym"]    = "Euskara"
    Locale["eu"]["message"]    = "%s esapidearen itzulpena"

    #7 Belarusian (Cyrillic alphabet)
    Locale["be"]["name"]       = "Belarusian"
    Locale["be"]["endonym"]    = "беларуская"
    Locale["be"]["message"]    = "Пераклады %s"

    #8 Bengali
    Locale["bn"]["name"]       = "Bengali"
    Locale["bn"]["endonym"]    = "বাংলা"
    Locale["bn"]["message"]    = "%s এর অনুবাদ"

    #9 Bosnian (Latin alphabet)
    Locale["bs"]["name"]       = "Bosnian"
    Locale["bs"]["endonym"]    = "Bosanski"
    Locale["bs"]["message"]    = "Prijevod za: %s"

    #10 Bulgarian
    Locale["bg"]["name"]       = "Bulgarian"
    Locale["bg"]["endonym"]    = "български"
    Locale["bg"]["message"]    = "Преводи на %s"

    #11 Catalan
    Locale["ca"]["name"]       = "Catalan"
    Locale["ca"]["endonym"]    = "Català"
    Locale["ca"]["message"]    = "Traduccions per a %s"

    #12 Cebuano
    Locale["ceb"]["name"]      = "Cebuano"
    Locale["ceb"]["endonym"]   = "Cebuano"
    Locale["ceb"]["message"]   = "%s Mga Paghubad sa PULONG_O_HUGPONG SA PAMULONG"

    #13a Chinese (Simplified)
    Locale["zh-CN"]["name"]    = "Chinese Simplified"
    Locale["zh-CN"]["endonym"] = "简体中文"
    Locale["zh-CN"]["message"] = "%s 的翻译"

    #13b Chinese (Traditional)
    Locale["zh-TW"]["name"]    = "Chinese Traditional"
    Locale["zh-TW"]["endonym"] = "正體中文"
    Locale["zh-TW"]["message"] = "「%s」的翻譯"

    #14 Croatian
    Locale["hr"]["name"]       = "Croatian"
    Locale["hr"]["endonym"]    = "Hrvatski"
    Locale["hr"]["message"]    = "Prijevodi riječi ili izraza %s"

    #15 Czech
    Locale["cs"]["name"]       = "Czech"
    Locale["cs"]["endonym"]    = "Čeština"
    Locale["cs"]["message"]    = "Překlad výrazu %s"

    #16 Danish
    Locale["da"]["name"]       = "Danish"
    Locale["da"]["endonym"]    = "Dansk"
    Locale["da"]["message"]    = "Oversættelser af %s"

    #17 Dutch
    Locale["nl"]["name"]       = "Dutch"
    Locale["nl"]["endonym"]    = "Nederlands"
    Locale["nl"]["message"]    = "Vertalingen van %s"

    #18 English
    Locale["en"]["name"]       = "English"
    Locale["en"]["endonym"]    = "English"
    Locale["en"]["message"]    = "Translations of %s"

    #19 Esperanto
    Locale["eo"]["name"]       = "Esperanto"
    Locale["eo"]["endonym"]    = "Esperanto"
    Locale["eo"]["message"]    = "Tradukoj de %s"

    #20 Estonian
    Locale["et"]["name"]       = "Estonian"
    Locale["et"]["endonym"]    = "Eesti"
    Locale["et"]["message"]    = "Sõna(de) %s tõlked"

    #21 Filipino
    Locale["tl"]["name"]       = "Filipino"
    Locale["tl"]["endonym"]    = "Tagalog"
    Locale["tl"]["message"]    = "Mga pagsasalin ng %s"

    #22 Finnish
    Locale["fi"]["name"]       = "Finnish"
    Locale["fi"]["endonym"]    = "Suomi"
    Locale["fi"]["message"]    = "Käännökset tekstille %s"

    #23 French
    Locale["fr"]["name"]       = "French"
    Locale["fr"]["endonym"]    = "Français"
    Locale["fr"]["message"]    = "Traductions de %s"

    #24 Galician
    Locale["gl"]["name"]       = "Galician"
    Locale["gl"]["endonym"]    = "Galego"
    Locale["gl"]["message"]    = "Traducións de %s"

    #25 Georgian
    Locale["ka"]["name"]       = "Georgian"
    Locale["ka"]["endonym"]    = "ქართული"
    Locale["ka"]["message"]    = "%s-ის თარგმანები"

    #26 German
    Locale["de"]["name"]       = "German"
    Locale["de"]["endonym"]    = "Deutsch"
    Locale["de"]["message"]    = "Übersetzungen für %s"

    #27 Greek
    Locale["el"]["name"]       = "Greek"
    Locale["el"]["endonym"]    = "Ελληνικά"
    Locale["el"]["message"]    = "Μεταφράσεις του %s"

    #28 Gujarati
    Locale["gu"]["name"]       = "Gujarati"
    Locale["gu"]["endonym"]    = "ગુજરાતી"
    Locale["gu"]["message"]    = "%s ના અનુવાદ"

    #29 Haitian Creole
    Locale["ht"]["name"]       = "Haitian Creole"
    Locale["ht"]["endonym"]    = "Kreyòl Ayisyen"
    Locale["ht"]["message"]    = "Tradiksyon %s"

    #30 Hausa (Latin / Boko alphabet)
    Locale["ha"]["name"]       = "Hausa"
    Locale["ha"]["endonym"]    = "Hausa"
    Locale["ha"]["message"]    = "Fassarar %s"

    #31 Hebrew
    Locale["he"]["name"]       = "Hebrew"
    Locale["he"]["endonym"]    = "עִבְרִית"
    Locale["he"]["message"]    = "תרגומים של %s"
    Locale["he"]["rtl"]        = "true" # RTL language

    #32 Hindi
    Locale["hi"]["name"]       = "Hindi"
    Locale["hi"]["endonym"]    = "हिन्दी"
    Locale["hi"]["message"]    = "%s के अनुवाद"

    #33 Hmong
    Locale["hmn"]["name"]      = "Hmong"
    Locale["hmn"]["endonym"]   = "Hmoob"
    Locale["hmn"]["message"]   = "Lus txhais: %s"

    #34 Hungarian
    Locale["hu"]["name"]       = "Hungarian"
    Locale["hu"]["endonym"]    = "Magyar"
    Locale["hu"]["message"]    = "%s fordításai"

    #35 Icelandic
    Locale["is"]["name"]       = "Icelandic"
    Locale["is"]["endonym"]    = "Íslenska"
    Locale["is"]["message"]    = "Þýðingar á %s"

    #36 Igbo
    Locale["ig"]["name"]       = "Igbo"
    Locale["ig"]["endonym"]    = "Igbo"
    Locale["ig"]["message"]    = "Ntụgharị asụsụ nke %s"

    #37 Indonesian
    Locale["id"]["name"]       = "Indonesian"
    Locale["id"]["endonym"]    = "Bahasa Indonesia"
    Locale["id"]["message"]    = "Terjemahan dari %s"

    #38 Irish
    Locale["ga"]["name"]       = "Irish"
    Locale["ga"]["endonym"]    = "Gaeilge"
    Locale["ga"]["message"]    = "Aistriúcháin ar %s"

    #39 Italian
    Locale["it"]["name"]       = "Italian"
    Locale["it"]["endonym"]    = "Italiano"
    Locale["it"]["message"]    = "Traduzioni di %s"

    #40 Japanese
    Locale["ja"]["name"]       = "Japanese"
    Locale["ja"]["endonym"]    = "日本語"
    Locale["ja"]["message"]    = "「%s」の翻訳"

    #41 Javanese (Latin alphabet)
    Locale["jv"]["name"]       = "Javanese"
    Locale["jv"]["endonym"]    = "Basa Jawa"
    Locale["jv"]["message"]    = "Terjemahan"

    #42 Kannada
    Locale["kn"]["name"]       = "Kannada"
    Locale["kn"]["endonym"]    = "ಕನ್ನಡ"
    Locale["kn"]["message"]    = "%s ನ ಅನುವಾದಗಳು"

    #43 Khmer (Central Khmer)
    Locale["km"]["name"]       = "Khmer"
    Locale["km"]["endonym"]    = "ភាសាខ្មែរ"
    Locale["km"]["message"]    = "ការបកប្រែនៃ %s"

    #44 Korean
    Locale["ko"]["name"]       = "Korean"
    Locale["ko"]["endonym"]    = "한국어"
    Locale["ko"]["message"]    = "%s의 번역"

    #45 Lao
    Locale["lo"]["name"]       = "Lao"
    Locale["lo"]["endonym"]    = "ລາວ"
    Locale["lo"]["message"]    = "ການແປພາສາຂອງ %s"

    #46 Latin
    Locale["la"]["name"]       = "Latin"
    Locale["la"]["endonym"]    = "Latina"
    Locale["la"]["message"]    = "Versio de %s"

    #47 Latvian
    Locale["lv"]["name"]       = "Latvian"
    Locale["lv"]["endonym"]    = "Latviešu"
    Locale["lv"]["message"]    = "%s tulkojumi"

    #48 Lithuanian
    Locale["lt"]["name"]       = "Lithuanian"
    Locale["lt"]["endonym"]    = "Lietuvių"
    Locale["lt"]["message"]    = "„%s“ vertimai"

    #49 Macedonian
    Locale["mk"]["name"]       = "Macedonian"
    Locale["mk"]["endonym"]    = "Македонски"
    Locale["mk"]["message"]    = "Преводи на %s"

    #50 Malay
    Locale["ms"]["name"]       = "Malay"
    Locale["ms"]["endonym"]    = "Bahasa Melayu"
    Locale["ms"]["message"]    = "Terjemahan %s"

    #51 Maltese
    Locale["mt"]["name"]       = "Maltese"
    Locale["mt"]["endonym"]    = "Malti"
    Locale["mt"]["message"]    = "Traduzzjonijiet ta' %s"

    #52 Maori
    Locale["mi"]["name"]       = "Maori"
    Locale["mi"]["endonym"]    = "Māori"
    Locale["mi"]["message"]    = "Ngā whakamāoritanga o %s"

    #53 Marathi
    Locale["mr"]["name"]       = "Marathi"
    Locale["mr"]["endonym"]    = "मराठी"
    Locale["mr"]["message"]    = "%s ची भाषांतरे"

    #54 Mongolian (Cyrillic alphabet)
    Locale["mn"]["name"]       = "Mongolian"
    Locale["mn"]["endonym"]    = "Монгол"
    Locale["mn"]["message"]    = "%s-н орчуулга"

    #55 Nepali
    Locale["ne"]["name"]       = "Nepali"
    Locale["ne"]["endonym"]    = "नेपाली"
    Locale["ne"]["message"]    = "%sका अनुवाद"

    #56 Norwegian
    Locale["no"]["name"]       = "Norwegian"
    Locale["no"]["endonym"]    = "Norsk"
    Locale["no"]["message"]    = "Oversettelser av %s"

    #57 Persian
    Locale["fa"]["name"]       = "Persian"
    Locale["fa"]["endonym"]    = "فارسی"
    Locale["fa"]["message"]    = "ترجمه‌های %s"
    Locale["fa"]["rtl"]        = "true" # RTL language

    #58 Punjabi (Brahmic / Gurmukhī alphabet)
    Locale["pa"]["name"]       = "Punjabi"
    Locale["pa"]["endonym"]    = "ਪੰਜਾਬੀ"
    Locale["pa"]["message"]    = "ਦੇ ਅਨੁਵਾਦ%s"

    #59 Polish
    Locale["pl"]["name"]       = "Polish"
    Locale["pl"]["endonym"]    = "Polski"
    Locale["pl"]["message"]    = "Tłumaczenia %s"

    #60 Portuguese
    Locale["pt"]["name"]       = "Portuguese"
    Locale["pt"]["endonym"]    = "Português"
    Locale["pt"]["message"]    = "Traduções de %s"

    #61 Romanian
    Locale["ro"]["name"]       = "Romanian"
    Locale["ro"]["endonym"]    = "Română"
    Locale["ro"]["message"]    = "Traduceri pentru %s"

    #62 Russian
    Locale["ru"]["name"]       = "Russian"
    Locale["ru"]["endonym"]    = "Русский"
    Locale["ru"]["message"]    = "%s: варианты перевода"

    #63 Serbian (Cyrillic alphabet)
    Locale["sr"]["name"]       = "Serbian"
    Locale["sr"]["endonym"]    = "српски"
    Locale["sr"]["message"]    = "Преводи за „%s“"

    #64 Slovak
    Locale["sk"]["name"]       = "Slovak"
    Locale["sk"]["endonym"]    = "Slovenčina"
    Locale["sk"]["message"]    = "Preklady výrazu: %s"

    #65 Slovenian
    Locale["sl"]["name"]       = "Slovenian"
    Locale["sl"]["endonym"]    = "Slovenščina"
    Locale["sl"]["message"]    = "Prevodi za %s"

    #66 Somali
    Locale["so"]["name"]       = "Somali"
    Locale["so"]["endonym"]    = "Soomaali"
    Locale["so"]["message"]    = "Turjumaada %s"

    #67 Spanish
    Locale["es"]["name"]       = "Spanish"
    Locale["es"]["endonym"]    = "Español"
    Locale["es"]["message"]    = "Traducciones de %s"

    #68 Swahili
    Locale["sw"]["name"]       = "Swahili"
    Locale["sw"]["endonym"]    = "Kiswahili"
    Locale["sw"]["message"]    = "Tafsiri ya %s"

    #69 Swedish
    Locale["sv"]["name"]       = "Swedish"
    Locale["sv"]["endonym"]    = "Svenska"
    Locale["sv"]["message"]    = "Översättningar av %s"

    #70 Tamil
    Locale["ta"]["name"]       = "Tamil"
    Locale["ta"]["endonym"]    = "தமிழ்"
    Locale["ta"]["message"]    = "%s இன் மொழிபெயர்ப்புகள்"

    #71 Telugu
    Locale["te"]["name"]       = "Telugu"
    Locale["te"]["endonym"]    = "తెలుగు"
    Locale["te"]["message"]    = "%s యొక్క అనువాదాలు"

    #72 Thai
    Locale["th"]["name"]       = "Thai"
    Locale["th"]["endonym"]    = "ไทย"
    Locale["th"]["message"]    = "คำแปลของ %s"

    #73 Turkish
    Locale["tr"]["name"]       = "Turkish"
    Locale["tr"]["endonym"]    = "Türkçe"
    Locale["tr"]["message"]    = "%s çevirileri"

    #74 Ukrainian
    Locale["uk"]["name"]       = "Ukrainian"
    Locale["uk"]["endonym"]    = "Українська"
    Locale["uk"]["message"]    = "Переклади слова або виразу \"%s\""

    #75 Urdu
    Locale["ur"]["name"]       = "Urdu"
    Locale["ur"]["endonym"]    = "اُردُو"
    Locale["ur"]["message"]    = "کے ترجمے %s"
    Locale["ur"]["rtl"]        = "true" # RTL language

    #76 Vietnamese
    Locale["vi"]["name"]       = "Vietnamese"
    Locale["vi"]["endonym"]    = "Tiếng Việt"
    Locale["vi"]["message"]    = "Bản dịch của %s"

    #77 Welsh
    Locale["cy"]["name"]       = "Welsh"
    Locale["cy"]["endonym"]    = "Cymraeg"
    Locale["cy"]["message"]    = "Cyfieithiadau %s"

    #78 Yiddish
    Locale["yi"]["name"]       = "Yiddish"
    Locale["yi"]["endonym"]    = "ייִדיש"
    Locale["yi"]["message"]    = "איבערזעצונגען פון %s"
    Locale["yi"]["rtl"]        = "true" # RTL language

    #79 Yoruba
    Locale["yo"]["name"]       = "Yoruba"
    Locale["yo"]["endonym"]    = "Yorùbá"
    Locale["yo"]["message"]    = "Awọn itumọ ti %s"

    #80 Zulu
    Locale["zu"]["name"]       = "Zulu"
    Locale["zu"]["endonym"]    = "isiZulu"
    Locale["zu"]["message"]    = "Ukuhumusha i-%s"

    # Aliases for some locales
    # See: <http://www.loc.gov/standards/iso639-2/php/code_changes.php>
    LocaleAlias["in"] = "id" # withdrawn language code for Indonesian
    LocaleAlias["iw"] = "he" # withdrawn language code for Hebrew
    LocaleAlias["ji"] = "yi" # withdrawn language code for Yiddish

    LocaleAlias["jw"] = "jv" # withdrawn language code for Javanese
    LocaleAlias["mo"] = "ro" # Moldavian or Moldovan considered a variant of the Romanian language
    LocaleAlias["sh"] = "sr" # Serbo-Croatian: prefer Serbian
    LocaleAlias["zh"] = "zh-CN" # Chinese: prefer Chinese Simplified
    LocaleAlias["zh-cn"] = "zh-CN" # lowercase
    LocaleAlias["zh-tw"] = "zh-TW" # lowercase
    # TODO: any more aliases supported by Google Translate?
}

# Get locale key by language code or alias.
function getCode(code) {
    code = tolower(code) # case-insensitive

    if (code in Locale || code == "auto")
        return code
    else if (code in LocaleAlias)
        return LocaleAlias[code]
    else
        return # return nothing if not found
}

# Detect external bidirectional algorithm utility (fribidi);
# Fallback to Unix `rev` if not found.
function initBiDi() {
    "fribidi --version 2>/dev/null" |& getline FriBidi
    BiDiNoPad = FriBidi ? "fribidi --nopad" : "rev"
    BiDi = FriBidi ? "fribidi --width %s" : "rev | sed \"s/'/\\\\\\'/\" | xargs printf '%%s '"
}

# Convert a logical string to visual; don't right justify RTL lines.
# Parameters:
#     code: ignore to apply bidirectional algorithm on every string
function show(text, code,    temp) {
    if (!code || Locale[getCode(code)]["rtl"]) {
        if (Cache[text][0])
            return Cache[text][0]
        else {
            if (FriBidi || (code && Locale[getCode(code)]["rtl"]))
                ("echo " parameterize(text) " | " BiDiNoPad) | getline temp
            else # non-RTL language, or FriBidi not installed
                temp = text
            return Cache[text][0] = temp
        }
    } else
        return text
}

# Convert a logical string to visual and right justify RTL lines.
# Parameters:
#     code: ignore to apply bidirectional algorithm on every string
#     width: ignore to use default width for padding
function s(text, code, width,    temp) {
    if (!code || Locale[getCode(code)]["rtl"]) {
        if (!width) width = Option["width"]
        if (Cache[text][width])
            return Cache[text][width]
        else {
            if (FriBidi || (code && Locale[getCode(code)]["rtl"]))
                ("echo " parameterize(text) " | " sprintf(BiDi, width)) | getline temp
            else # non-RTL language, or FriBidi not installed
                temp = text
            return Cache[text][width] = temp
        }
    } else
        return text
}

# Initialize strings for displaying endonyms of locales.
function initLocaleDisplay(    i) {
    for (i in Locale)
        Locale[i]["display"] = show(Locale[i]["endonym"], i)
}

# Parse a POSIX locale identifier and return the language code;
# Identified by both language identifier and region identifier.
# Parameters:
#     lang = [language[_territory][.codeset][@modifier]]
# See: <https://en.wikipedia.org/wiki/Locale>
function parseLang(lang,    code, group) {
    match(lang, /^([a-z][a-z][a-z]?)(_|$)/, group)
    code = getCode(group[1])

    # Detect region identifier
    ## Regions using Chinese Simplified: China, Singapore
    if (lang ~ /^zh_(CN|SG)/) code = "zh-CN"
    ## Regions using Chinese Traditional: Taiwan, Hong Kong
    else if (lang ~ /^zh_(TW|HK)/) code = "zh-TW"

    # FIXME: handle unrecognized language code
    if (!code) code = "en"

    return code
}

# Initialize `UserLang`.
function initUserLang() {
    UserLang = ENVIRON["LC_CTYPE"] ?
        parseLang(ENVIRON["LC_CTYPE"]) :
        (ENVIRON["LANG"] ?
         parseLang(ENVIRON["LANG"]) :
         "en")

    if (ENVIRON["LANG"] !~ /UTF-8$/ && ENVIRON["LC_CTYPE"] !~ /UTF-8$/)
        w("[WARNING] Your locale codeset (" ENVIRON["LANG"] ") is not UTF-8. You have been warned.")
}


mpers.awk: remove unnecessary type attribute retrieval

* mpers.awk (what_is): Do not retrieve "type" attribute
for "enumeration_type".

#!/bin/gawk
#
# Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
# Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

function compare_indices(i1, v1, i2, v2) {
	c1 = strtonum(sprintf("%s", i1))
	c2 = strtonum(sprintf("%s", i2))
	if (c1 < c2)
		return -1
	return (c1 != c2)
}
function array_get(array_idx, array_member, array_return)
{
	array_return = array[array_idx][array_member]
	if ("" == array_return) {
		printf("%s: index [%s] without %s\n",
		       FILENAME, array_idx, array_member) > "/dev/stderr"
		exit 1
	}
	return array_return
}
function array_seq(array_idx)
{
	if ("seq" in array[array_idx])
		return array[array_idx]["seq"]
	index_seq++
	array[array_idx]["seq"] = index_seq
	return index_seq
}
function enter(array_idx)
{
	if (array_idx in called) {
		printf("%s: index loop detected:", FILENAME) > "/dev/stderr"
		for (item in called)
			printf(" %s", item) > "/dev/stderr"
		print "" > "/dev/stderr"
		exit 1
	}
	called[array_idx] = 1
}
function leave(array_idx, to_return)
{
	delete called[array_idx]
	return to_return
}
function what_is(what_idx, type_idx, special, item, \
		 location, prev_location, prev_returned_size)
{
	enter(what_idx)
	special = array_get(what_idx, "special")
	switch (special) {
	case "base_type":
		switch (array_get(what_idx, "encoding")) {
		case 5: # signed
			printf("int%s_t ",
			       8 * array_get(what_idx, "byte_size"))
			break
		case 7: # unsigned
			printf("uint%s_t ",
			       8 * array_get(what_idx, "byte_size"))
			break
		default: # float, signed/unsigned char
			printf("%s ", array_get(what_idx, "name"))
			break
		}
		returned_size = array_get(what_idx, "byte_size")
		break
	case "enumeration_type":
		returned_size = array_get(what_idx, "byte_size")
		printf("uint%s_t ", 8 * returned_size)
		break
	case "pointer_type":
		printf("mpers_ptr_t ")
		returned_size = array_get(what_idx, "byte_size")
		break
	case "array_type":
		type_idx = array_get(what_idx, "type")
		what_is(type_idx)
		to_return = array[what_idx]["upper_bound"]
		if ("" == to_return)
			to_return = 0
		returned_size = to_return * returned_size
		return leave(what_idx, to_return)
		break
	case "structure_type":
		print "struct {"
		prev_location = 0
		location = 0
		returned_size = 0
		prev_returned_size = 0
		for (item in array) {
			if ("parent" in array[item] && \
				array_get(item, "parent") == what_idx) {
				location = array_get(item, "location")
				loc_diff = location - prev_location - \
					prev_returned_size
				if (loc_diff != 0) {
					printf("unsigned char mpers_%s_%s[%s];\n",
					       "filler", array_seq(item), loc_diff)
				}
				prev_location = location
				returned = what_is(item)
				prev_returned_size = returned_size
				printf("%s", array[item]["name"])
				if ("" != returned) {
					printf("[%s]", returned)
				}
				print ";"
			}
		}
		returned_size = array_get(what_idx, "byte_size")
		loc_diff = returned_size - prev_location - prev_returned_size
		if (loc_diff != 0) {
			printf("unsigned char mpers_%s_%s[%s];\n",
			       "end_filler", array_seq(item), loc_diff)
		}
		printf("} ATTRIBUTE_PACKED ")
		break
	case "union_type":
		print "union {"
		for (item in array) {
			if ("parent" in array[item] && \
				array_get(item, "parent") == what_idx) {
				returned = what_is(item)
				printf("%s", array_get(item, "name"))
				if ("" != returned) {
					printf("[%s]", returned)
				}
				print ";"
			}
		}
		printf("} ")
		returned_size = array_get(what_idx, "byte_size")
		break
	case "typedef":
		type_idx = array_get(what_idx, "type")
		return leave(what_idx, what_is(type_idx))
		break
	case "member":
		type_idx = array_get(what_idx, "type")
		return leave(what_idx, what_is(type_idx))
		break
	default:
		type_idx = array_get(what_idx, "type")
		what_is(type_idx)
		break
	}
	return leave(what_idx, "")
}
BEGIN {
	match(ARCH_FLAG, /[[:digit:]]+/, temparray)
	default_pointer_size = temparray[0] / 8
	print "#include <inttypes.h>"
}
/^<[[:xdigit:]]+>/ {
	match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
	level = matches[1]
	idx = "0x" matches[2]
	array[idx]["idx"] = idx
	parent[level] = idx
}
/^DW_AT_data_member_location/ {
	if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
		match($0, /([[:digit:]]+)/, temparray)
	array[idx]["location"] = temparray[1]
}
/^DW_AT_name/ {
	match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
		temparray)
	array[idx]["name"] = temparray[1]
}
/^DW_AT_byte_size/ {
	match($0, /[[:digit:]]+/, temparray)
	array[idx]["byte_size"] = temparray[0]
}
/^DW_AT_encoding/ {
	match($0, /[[:digit:]]+/, temparray)
	array[idx]["encoding"] = temparray[0]
}
/^DW_AT_type/ {
	match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
	array[idx]["type"] = temparray[1]
}
/^DW_AT_upper_bound/ {
	match($0, /[[:digit:]]+/, temparray)
	array[parent[level-1]]["upper_bound"] = temparray[0] + 1
}
/^DW_AT_count/ {
	match($0, /[[:digit:]]+/, temparray)
	array[parent[level-1]]["upper_bound"] = temparray[0]
}
/^Abbrev Number:[^(]+\(DW_TAG_/ {
	if (match($0, /typedef|union_type|structure_type|pointer_type\
|enumeration_type|array_type|base_type|member/, temparray)) {
		array[idx]["special"] = temparray[0]
		if ("pointer_type" == temparray[0])
			array[idx]["byte_size"] = default_pointer_size
		if (level > 1 && "member" == temparray[0])
			array[idx]["parent"] = parent[level-1]
	}
}
END {
	PROCINFO["sorted_in"] = "compare_indices"
	for (item in array) {
		if (array[item]["special"] == "pointer_type") {
			print "typedef uint" \
				8 * array_get(item, "byte_size") "_t mpers_ptr_t;"
			break
		}
	}
	for (item in array) {
		if (array[item]["name"] == VAR_NAME) {
			type = array_get(item, "type")
			print "typedef"
			what_is(type)
			name = array_get(type, "name")
			print ARCH_FLAG "_" name ";"
			print "#define MPERS_" \
				ARCH_FLAG "_" name " " \
				ARCH_FLAG "_" name
			break
		}
	}
}

#!/bin/gawk
#
# Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
# Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

function compare_indices(i1, v1, i2, v2) {
	c1 = strtonum(sprintf("%s", i1))
	c2 = strtonum(sprintf("%s", i2))
	if (c1 < c2)
		return -1
	return (c1 != c2)
}
function array_get(array_idx, array_member, array_return)
{
	array_return = array[array_idx][array_member]
	if ("" == array_return) {
		printf("%s: index [%s] without %s\n",
		       FILENAME, array_idx, array_member) > "/dev/stderr"
		exit 1
	}
	return array_return
}
function array_seq(array_idx)
{
	if ("seq" in array[array_idx])
		return array[array_idx]["seq"]
	index_seq++
	array[array_idx]["seq"] = index_seq
	return index_seq
}
function enter(array_idx)
{
	if (array_idx in called) {
		printf("%s: index loop detected:", FILENAME) > "/dev/stderr"
		for (item in called)
			printf(" %s", item) > "/dev/stderr"
		print "" > "/dev/stderr"
		exit 1
	}
	called[array_idx] = 1
}
function leave(array_idx, to_return)
{
	delete called[array_idx]
	return to_return
}
function what_is(what_idx, type_idx, special, item, \
		 location, prev_location, prev_returned_size)
{
	enter(what_idx)
	special = array_get(what_idx, "special")
	switch (special) {
	case "base_type":
		switch (array_get(what_idx, "encoding")) {
		case 5: # signed
			printf("int%s_t ",
			       8 * array_get(what_idx, "byte_size"))
			break
		case 7: # unsigned
			printf("uint%s_t ",
			       8 * array_get(what_idx, "byte_size"))
			break
		default: # float, signed/unsigned char
			printf("%s ", array_get(what_idx, "name"))
			break
		}
		returned_size = array_get(what_idx, "byte_size")
		break
	case "enumeration_type":
		type_idx = array_get(what_idx, "type")
		returned_size = array_get(what_idx, "byte_size")
		printf("uint%s_t ", 8 * returned_size)
		break
	case "pointer_type":
		printf("mpers_ptr_t ")
		returned_size = array_get(what_idx, "byte_size")
		break
	case "array_type":
		type_idx = array_get(what_idx, "type")
		what_is(type_idx)
		to_return = array[what_idx]["upper_bound"]
		if ("" == to_return)
			to_return = 0
		returned_size = to_return * returned_size
		return leave(what_idx, to_return)
		break
	case "structure_type":
		print "struct {"
		prev_location = 0
		location = 0
		returned_size = 0
		prev_returned_size = 0
		for (item in array) {
			if ("parent" in array[item] && \
				array_get(item, "parent") == what_idx) {
				location = array_get(item, "location")
				loc_diff = location - prev_location - \
					prev_returned_size
				if (loc_diff != 0) {
					printf("unsigned char mpers_%s_%s[%s];\n",
					       "filler", array_seq(item), loc_diff)
				}
				prev_location = location
				returned = what_is(item)
				prev_returned_size = returned_size
				printf("%s", array[item]["name"])
				if ("" != returned) {
					printf("[%s]", returned)
				}
				print ";"
			}
		}
		returned_size = array_get(what_idx, "byte_size")
		loc_diff = returned_size - prev_location - prev_returned_size
		if (loc_diff != 0) {
			printf("unsigned char mpers_%s_%s[%s];\n",
			       "end_filler", array_seq(item), loc_diff)
		}
		printf("} ATTRIBUTE_PACKED ")
		break
	case "union_type":
		print "union {"
		for (item in array) {
			if ("parent" in array[item] && \
				array_get(item, "parent") == what_idx) {
				returned = what_is(item)
				printf("%s", array_get(item, "name"))
				if ("" != returned) {
					printf("[%s]", returned)
				}
				print ";"
			}
		}
		printf("} ")
		returned_size = array_get(what_idx, "byte_size")
		break
	case "typedef":
		type_idx = array_get(what_idx, "type")
		return leave(what_idx, what_is(type_idx))
		break
	case "member":
		type_idx = array_get(what_idx, "type")
		return leave(what_idx, what_is(type_idx))
		break
	default:
		type_idx = array_get(what_idx, "type")
		what_is(type_idx)
		break
	}
	return leave(what_idx, "")
}
BEGIN {
	match(ARCH_FLAG, /[[:digit:]]+/, temparray)
	default_pointer_size = temparray[0] / 8
	print "#include <inttypes.h>"
}
/^<[[:xdigit:]]+>/ {
	match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
	level = matches[1]
	idx = "0x" matches[2]
	array[idx]["idx"] = idx
	parent[level] = idx
}
/^DW_AT_data_member_location/ {
	if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
		match($0, /([[:digit:]]+)/, temparray)
	array[idx]["location"] = temparray[1]
}
/^DW_AT_name/ {
	match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
		temparray)
	array[idx]["name"] = temparray[1]
}
/^DW_AT_byte_size/ {
	match($0, /[[:digit:]]+/, temparray)
	array[idx]["byte_size"] = temparray[0]
}
/^DW_AT_encoding/ {
	match($0, /[[:digit:]]+/, temparray)
	array[idx]["encoding"] = temparray[0]
}
/^DW_AT_type/ {
	match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
	array[idx]["type"] = temparray[1]
}
/^DW_AT_upper_bound/ {
	match($0, /[[:digit:]]+/, temparray)
	array[parent[level-1]]["upper_bound"] = temparray[0] + 1
}
/^DW_AT_count/ {
	match($0, /[[:digit:]]+/, temparray)
	array[parent[level-1]]["upper_bound"] = temparray[0]
}
/^Abbrev Number:[^(]+\(DW_TAG_/ {
	if (match($0, /typedef|union_type|structure_type|pointer_type\
|enumeration_type|array_type|base_type|member/, temparray)) {
		array[idx]["special"] = temparray[0]
		if ("pointer_type" == temparray[0])
			array[idx]["byte_size"] = default_pointer_size
		if (level > 1 && "member" == temparray[0])
			array[idx]["parent"] = parent[level-1]
	}
}
END {
	PROCINFO["sorted_in"] = "compare_indices"
	for (item in array) {
		if (array[item]["special"] == "pointer_type") {
			print "typedef uint" \
				8 * array_get(item, "byte_size") "_t mpers_ptr_t;"
			break
		}
	}
	for (item in array) {
		if (array[item]["name"] == VAR_NAME) {
			type = array_get(item, "type")
			print "typedef"
			what_is(type)
			name = array_get(type, "name")
			print ARCH_FLAG "_" name ";"
			print "#define MPERS_" \
				ARCH_FLAG "_" name " " \
				ARCH_FLAG "_" name
			break
		}
	}
}


Tweak indentation in .awk

Tweak indentation in .awk

#!/usr/bin/awk -f

BEGIN {

for (i=1; i<=100; i++) {
	if (i % 15 == 0) {
		print "fizzbuzz"
	} else if (i % 3 == 0) {
		print "fizz"
	} else if (i % 5 == 0) {
		print "buzz"
	} else {
		print i
	}
}

}


(BEGIN): Fix regluar expression for extracting an English name. (/^[a-z][a-z][a-z]\|/): Don't modify English names extracted from "en.lnm".

# LANGUAGE.awk -- awk script to generate LANGUAGE.tbl	-*- coding: utf-8; -*-
# Copyright (C) 2007
#   National Institute of Advanced Industrial Science and Technology (AIST)
#   Registration Number H15PRO112

# This file is part of the m17n database; a sub-part of the m17n
# library.

# The m17n library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.

# The m17n library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.

# You should have received a copy of the GNU Lesser General Public
# License along with the m17n library; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.

BEGIN {
    print ";; LANGUAGE.tbl -- ISO639 Language Code		-*- mode:lisp; coding:utf-8; -*-";
    print ";; Copyright (C) 2007";
    print ";;   National Institute of Advanced Industrial Science and Technology (AIST)";
    print ";;   Registration Number H15PRO112";
    print "";
    print ";; This file is part of the m17n database; a sub-part of the m17n";
    print ";; library.";
    print "";
    print ";; The m17n library is free software; you can redistribute it and/or";
    print ";; modify it under the terms of the GNU Lesser General Public License";
    print ";; as published by the Free Software Foundation; either version 2.1 of";
    print ";; the License, or (at your option) any later version.";
    print "";
    print ";; The m17n library is distributed in the hope that it will be useful,";
    print ";; but WITHOUT ANY WARRANTY; without even the implied warranty of";
    print ";; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU";
    print ";; Lesser General Public License for more details.";
    print "";
    print ";; You should have received a copy of the GNU Lesser General Public";
    print ";; License along with the m17n library; if not, write to the Free";
    print ";; Software Foundation, Inc., 51 Franklin Street, Fifth Floor,";
    print ";; Boston, MA 02110-1301, USA.";
    print ";;";
    print ";; The file format is this:";
    print ";;    (ISO639-2 ISO639-1 \"ENGLISH-NAME\" [ \"NATIVE-NAME\" [ \"EXTRA-CHARS\" ]]) ...";
    print ";; ISO639-2: 3-letter language code of ISO639-2.";
    print ";; ISO639-1: 2-letter language code of ISO639-1, or nil if it doesn't exist.";
    print ";; ENGLISH-NAME: English name of the language.";
    print ";; NATIVE-NAME: Native name of the language.";
    print ";; EXTRA-CHARS: Extra characters that uniquifies the language.";
    print ";;";
    print ";; ISO639-2 and ISO639-1 are extracted from ISO-639-2.txt.";
    print ";; ENGLISH-NAME and NATIVE-NAME are mainly extracted from CLDR,";
    print ";;   but are also supplemented from these sites:";

    while (getline < "native.txt") {
	if ($0 ~ /^[a-z]/) {
	    NATIVE[$1] = $2;
	    if ($3 != "")
		CHARS[$1] = $3;
	} else if ($0 ~ /^;;/) {
	    print;
	}
    }
    while (getline < "native.ext") {
	if ($0 ~ /^[a-z]/) {
	    NATIVE[$1] = $2;
	}
    }
    while (getline < "en.lnm") {
	split($0, array, "[( ]");
	code = array[2];
	split($0, array, "\"");
	ENGLISH[code] = array[2];
    }
}

/^[a-z][a-z][a-z]\|/ {
    code3 = $1;
    code2 = $3;
    if (code2 == "" || code2 == "NULL")
	code2 = "nil";
    native = NATIVE[code2];
    if (! native)
	native = NATIVE[code3];
    chars = CHARS[code3];
    name = $4;
    name = ENGLISH[code2];
    if (! name)
	name = ENGLISH[code3];
#     if (name == "Greek, Modern (1453-)")
# 	name = "Greek";
#     else {
# 	gsub("; .*", "", name);
# 	gsub(" \\(Other\\)$", "", name);
# 	gsub(" languages$", "", name);
# 	gsub(" Languages$", "", name);
# 	if (name ~ /\(.*[0-9].*\)$/)
# 	    gsub(" \\([^)]*\\)$", "", name);
# 	if (name ~ ", ") {
# 	    split(name, array, ", ");
# 	    name = array[2] " " array[1];
# 	}
#     }
    printf "(%s %-3s \"%s\"", code3, code2, name;
    if (native != "")
	printf " \"%s\"", native;
    else if (chars != "")
	printf " nil";
    if (chars != "")
	printf " \"%s\"", chars;
    printf ")\n";
}

# LANGUAGE.awk -- awk script to generate LANGUAGE.tbl	-*- coding: utf-8; -*-
# Copyright (C) 2007
#   National Institute of Advanced Industrial Science and Technology (AIST)
#   Registration Number H15PRO112

# This file is part of the m17n database; a sub-part of the m17n
# library.

# The m17n library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.

# The m17n library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.

# You should have received a copy of the GNU Lesser General Public
# License along with the m17n library; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.

BEGIN {
    print ";; LANGUAGE.tbl -- ISO639 Language Code		-*- mode:lisp; coding:utf-8; -*-";
    print ";; Copyright (C) 2007";
    print ";;   National Institute of Advanced Industrial Science and Technology (AIST)";
    print ";;   Registration Number H15PRO112";
    print "";
    print ";; This file is part of the m17n database; a sub-part of the m17n";
    print ";; library.";
    print "";
    print ";; The m17n library is free software; you can redistribute it and/or";
    print ";; modify it under the terms of the GNU Lesser General Public License";
    print ";; as published by the Free Software Foundation; either version 2.1 of";
    print ";; the License, or (at your option) any later version.";
    print "";
    print ";; The m17n library is distributed in the hope that it will be useful,";
    print ";; but WITHOUT ANY WARRANTY; without even the implied warranty of";
    print ";; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU";
    print ";; Lesser General Public License for more details.";
    print "";
    print ";; You should have received a copy of the GNU Lesser General Public";
    print ";; License along with the m17n library; if not, write to the Free";
    print ";; Software Foundation, Inc., 51 Franklin Street, Fifth Floor,";
    print ";; Boston, MA 02110-1301, USA.";
    print ";;";
    print ";; The file format is this:";
    print ";;    (ISO639-2 ISO639-1 \"ENGLISH-NAME\" [ \"NATIVE-NAME\" [ \"EXTRA-CHARS\" ]]) ...";
    print ";; ISO639-2: 3-letter language code of ISO639-2.";
    print ";; ISO639-1: 2-letter language code of ISO639-1, or nil if it doesn't exist.";
    print ";; ENGLISH-NAME: English name of the language.";
    print ";; NATIVE-NAME: Native name of the language.";
    print ";; EXTRA-CHARS: Extra characters that uniquifies the language.";
    print ";;";
    print ";; ISO639-2 and ISO639-1 are extracted from ISO-639-2.txt.";
    print ";; ENGLISH-NAME and NATIVE-NAME are mainly extracted from CLDR,";
    print ";;   but are also supplemented from these sites:";

    while (getline < "native.txt") {
	if ($0 ~ /^[a-z]/) {
	    NATIVE[$1] = $2;
	    if ($3 != "")
		CHARS[$1] = $3;
	} else if ($0 ~ /^;;/) {
	    print;
	}
    }
    while (getline < "native.ext") {
	if ($0 ~ /^[a-z]/) {
	    NATIVE[$1] = $2;
	}
    }
    while (getline < "en.lnm") {
	split($0, array, "\(| \"|\" \"|\"\)")
	ENGLISH[array[2]] = array[3];
    }
}

/^[a-z][a-z][a-z]\|/ {
    code3 = $1;
    code2 = $3;
    if (code2 == "" || code2 == "NULL")
	code2 = "nil";
    native = NATIVE[code2];
    if (! native)
	native = NATIVE[code3];
    chars = CHARS[code3];
    name = $4;
    name = ENGLISH[code2];
    if (! name)
	name = ENGLISH[code3];
    if (name == "Greek, Modern (1453-)")
	name = "Greek";
    else {
	gsub("; .*", "", name);
	gsub(" \\(Other\\)$", "", name);
	gsub(" languages$", "", name);
	if (name ~ /\(.*[0-9].*\)$/)
	    gsub(" \\([^)]*\\)$", "", name);
	if (name ~ ", ") {
	    split(name, array, ", ");
	    name = array[2] " " array[1];
	}
    }
    printf "(%s %-3s \"%s\"", code3, code2, name;
    if (native != "")
	printf " \"%s\"", native;
    else if (chars != "")
	printf " nil";
    if (chars != "")
	printf " \"%s\"", chars;
    printf ")\n";
}


fix line endings hopefully

fix line endings hopefully

BEGIN {
	IN_BLOCK = 0;

	PRE_LINE = "^[ \t]*";
	POST_LINE = "[ \t]*$";

	# tmp variable
	X = "(\\* *)?";

	BLOCK[ 0] = "/\\* \\*\\*\\*\\*\\* BEGIN LICENSE BLOCK \\*\\*\\*\\*\\*";
	BLOCK[ 1] = X;
	BLOCK[ 2] = X "BBN Address and AS Number PKI Database/repository software";
	BLOCK[ 3] = X "Version [^ ]*";
	BLOCK[ 4] = X;
	BLOCK[ 5] = X "US government users are permitted unrestricted rights as";
	BLOCK[ 6] = X "defined in the FAR.";
	BLOCK[ 7] = X;
	BLOCK[ 8] = X "This software is distributed on an \"AS IS\" basis, WITHOUT";
	BLOCK[ 9] = X "WARRANTY OF ANY KIND, either express or implied.";
	BLOCK[10] = X;
	BLOCK[11] = X "Copyright .*";
	BLOCK[12] = X;
	BLOCK[13] = X "Contributor(\\(s\\)|s)?: .*";
	BLOCK[14] = X;
	BLOCK[15] = X "\\*\\*\\*\\*\\* END LICENSE BLOCK \\*\\*\\*\\*\\* \\*/";

	BLOCK_END = 15;
}

{
	if (!IN_BLOCK) {
		if ($0 ~ PRE_LINE BLOCK[0] POST_LINE) {
			IN_BLOCK = 1;
			BLOCK_LINENO = 0;
			SAVED_BLOCK = $0 RS;
		} else {
			print;
		}
	} else {
		if ($0 ~ PRE_LINE BLOCK[BLOCK_LINENO + 1] POST_LINE) {
			SAVED_BLOCK = SAVED_BLOCK $0 RS;
			BLOCK_LINENO += 1;
			if (BLOCK_LINENO == BLOCK_END) {
				IN_BLOCK = 0;
			}
		} else {
			print SAVED_BLOCK;
			print;
			IN_BLOCK = 0;
		}
	}
}

END {
	if (IN_BLOCK) {
		print SAVED_BLOCK;
	}
}

BEGIN {
	IN_BLOCK = 0;

	PRE_LINE = "^[ \t]*";
	POST_LINE = "[ \t]*$";

	# tmp variable
	X = "(\\* *)?";

	BLOCK[ 0] = "/\\* \\*\\*\\*\\*\\* BEGIN LICENSE BLOCK \\*\\*\\*\\*\\*";
	BLOCK[ 1] = X;
	BLOCK[ 2] = X "BBN Address and AS Number PKI Database/repository software";
	BLOCK[ 3] = X "Version [^ ]*";
	BLOCK[ 4] = X;
	BLOCK[ 5] = X "US government users are permitted unrestricted rights as";
	BLOCK[ 6] = X "defined in the FAR.";
	BLOCK[ 7] = X;
	BLOCK[ 8] = X "This software is distributed on an \"AS IS\" basis, WITHOUT";
	BLOCK[ 9] = X "WARRANTY OF ANY KIND, either express or implied.";
	BLOCK[10] = X;
	BLOCK[11] = X "Copyright .*";
	BLOCK[12] = X;
	BLOCK[13] = X "Contributor(\\(s\\)|s)?: .*";
	BLOCK[14] = X;
	BLOCK[15] = X "\\*\\*\\*\\*\\* END LICENSE BLOCK \\*\\*\\*\\*\\* \\*/";

	BLOCK_END = 15;
}

{
	if (!IN_BLOCK) {
		if ($0 ~ PRE_LINE BLOCK[0] POST_LINE) {
			IN_BLOCK = 1;
			BLOCK_LINENO = 0;
			SAVED_BLOCK = $0;
		} else {
			print;
		}
	} else {
		if ($0 ~ PRE_LINE BLOCK[BLOCK_LINENO + 1] POST_LINE) {
			SAVED_BLOCK = SAVED_BLOCK $0;
			BLOCK_LINENO += 1;
			if (BLOCK_LINENO == BLOCK_END) {
				IN_BLOCK = 0;
			}
		} else {
			print SAVED_BLOCK;
			print;
			IN_BLOCK = 0;
		}
	}
}

END {
	if (IN_BLOCK) {
		print SAVED_BLOCK;
	}
}


don't let the Mac/PPC linker complain when the symbol isn't used


size reducage and constify

size reducage and constify

#! /usr/bin/awk -f
#	$OpenBSD: devlist2h.awk,v 1.5 2001/01/29 05:47:03 mickey Exp $
#	$NetBSD: devlist2h.awk,v 1.2 1996/01/22 21:08:09 cgd Exp $
#
# Copyright (c) 1995, 1996 Christopher G. Demetriou
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#      This product includes software developed by Christopher G. Demetriou.
# 4. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
BEGIN {
	nproducts = 0
	dfile="pnpdevs.h"
}
NR == 1 {
	VERSION = $0
	gsub("\\$", "", VERSION)

	printf("/*\n") > dfile
	printf(" * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.\n") \
	    > dfile
	printf(" *\n") > dfile
	printf(" * generated from:\n") > dfile
	printf(" *\t%s\n", VERSION) > dfile
	printf(" */\n") > dfile

	next
}
{
	if ($1 == "")
		next
	if (substr($1,0,1) == "#")
		next
	if (substr($2,0,1) == "#")
		next
	do {
		nproducts++
		if ((x = index($1, "/")))
			products[nproducts, 1] = substr($1, 1, x - 1);
		else
			products[nproducts, 1] = $1;		# driver name
		products[nproducts, 2] = $2;		# pnp id
#		if ($3 && substr($3,0,1) == "#")
#			products[nproducts, 3] = substr($3, 1);
#		printf("%s %s %s\n", $1, $2, products[nproducts, 3]);
	} while (x && ($1 = substr($1, x + 1, length($1) - x)));

	next
}
END {
	# print out the match tables

	printf("\n") > dfile

	printf("const struct isapnp_knowndev isapnp_knowndevs[] = {\n") > dfile
	for (i = 1; i <= nproducts; i++) {
		printf("\t{ {\"%s\"}, {\"%s\"} },",
		    products[i, 2], products[i, 1]) \
		    > dfile
		if (products[i, 3])
			printf("\t/* %s */", products[i, 3]) > dfile
		printf("\n") > dfile
	}
	printf("\t{ {""}, {""}, }\n") > dfile
	printf("};\n") > dfile
}

#! /usr/bin/awk -f
#	$OpenBSD: devlist2h.awk,v 1.4 1998/12/28 09:15:16 hugh Exp $
#	$NetBSD: devlist2h.awk,v 1.2 1996/01/22 21:08:09 cgd Exp $
#
# Copyright (c) 1995, 1996 Christopher G. Demetriou
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#      This product includes software developed by Christopher G. Demetriou.
# 4. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
BEGIN {
	nproducts = 0
	dfile="pnpdevs.h"
}
NR == 1 {
	VERSION = $0
	gsub("\\$", "", VERSION)

	printf("/*\n") > dfile
	printf(" * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.\n") \
	    > dfile
	printf(" *\n") > dfile
	printf(" * generated from:\n") > dfile
	printf(" *\t%s\n", VERSION) > dfile
	printf(" */\n") > dfile

	next
}
{
	if ($1 == "")
		next
	if (substr($1,0,1) == "#")
		next
	if (substr($2,0,1) == "#")
		next
	do {
		nproducts++
		if ((x = index($1, "/")))
			products[nproducts, 1] = substr($1, 1, x - 1);
		else
			products[nproducts, 1] = $1;		# driver name
		products[nproducts, 2] = $2;		# pnp id
#		if ($3 && substr($3,0,1) == "#")
#			products[nproducts, 3] = substr($3, 1);
#		printf("%s %s %s\n", $1, $2, products[nproducts, 3]);
	} while (x && ($1 = substr($1, x + 1, length($1) - x)));

	next
}
END {
	# print out the match tables

	printf("\n") > dfile

	printf("struct isapnp_knowndev isapnp_knowndevs[] = {\n") > dfile
	for (i = 1; i <= nproducts; i++) {
		printf("\t{ \"%s\", \"%s\" },",
		    products[i, 2], products[i, 1]) \
		    > dfile
		if (products[i, 3])
			printf("\t/* %s */", products[i, 3]) > dfile
		printf("\n") > dfile
	}
	printf("\t{ NULL, NULL, }\n") > dfile
	printf("};\n") > dfile
}