tests: extend getdents to support all filesystems regardless of file order

* tests/getdents.awk: Include all 6 possible permutations of 3
direntries to regexps.

BEGIN {
  lines = 3
  fail = 0

  i = "[0-9]+"
  len = "[1-9]" i

  d_ino = "d_ino=" i
  d_off = "d_off=" i
  d_reclen = "d_reclen=" len
  d_name_1 = "d_name=\"\\.\""
  d_name_2 = "d_name=\"\\.\\.\""
  d_name_3 = "d_name=\"(A\\\\n){127}Z\""
  d_type_dir = "d_type=DT_DIR"
  d_type_reg = "d_type=DT_REG"

  dirent_1   = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_1 ", " d_type_dir "\\}"
  dirent_2   = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_2 ", " d_type_dir "\\}"
  dirent_3   = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_3 ", " d_type_reg "\\}"

  dirent64_1 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_dir ", " d_name_1 "\\}"
  dirent64_2 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_dir ", " d_name_2 "\\}"
  dirent64_3 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_reg ", " d_name_3 "\\}"

  dents   = "\\{(" dirent_1   " " dirent_2   "|" dirent_2   " " dirent_1   ") " dirent_3   "\\}"
  dents64 = "\\{(" dirent64_1 " " dirent64_2 "|" dirent64_2 " " dirent64_1 ") " dirent64_3 "\\}"

  getdents   =   "^getdents\\(" i ", " dents   ", " len "\\) += " len "$"
  getdents64 = "^getdents64\\(" i ", " dents64 ", " len "\\) += " len "$"
}

NR == 1 {if (match($0, getdents) || match($0, getdents64)) next}

NR == 2 && /^getdents(64)?\([0-9]+, \{\}, [1-9][0-9]+\) += 0$/ {next}

NR == lines && /^\+\+\+ exited with 0 \+\+\+$/ {next}

{
  print "Line " NR " does not match: " $0
  fail=1
}

END {
  if (NR != lines) {
    print "Expected " lines " lines, found " NR " line(s)."
    print ""
    exit 1
  }
  if (fail) {
    print ""
    exit 1
  }
}


Omit throw-away separators variables.

Omit throw-away separators variables.

function printUrlQueryString(queryString)
{
    split(queryString, pairs, "&", seps)
    len = length(pairs)
    for (j = 1; j < len; ++j) {
        split(pairs[j], keyValue, "=", seps2)
        k = keyValue[1]
        v = keyValue[2]
        printf "\t\t\"%s\": \"%s\",\n", k, urlDecode(urlDecode(v))
    }
}

function base64Decode(thing)
{
  "echo "$thing" | base64 --decode" | getline x
  return x
}

function urlDecode(url) {
    for (i = 0x20; i < 0x40; ++i) {
        repl = sprintf("%c", i);
        if ((repl == "&") || (repl == "\\")) {
            repl = "\\" repl;
        }
        url = gensub(sprintf("%%%02X", i), repl, "g", url);
        url = gensub(sprintf("%%%02x", i), repl, "g", url);
    }
    return url;
}

BEGIN {
    print "{";
}

END {
    print "}"
}

/^#Version: / {
    printf "\t\"version\": \"%s\",\n", substr($0, length("#Version: ") + 1)
}

/^#Fields: / {
    rest = substr($0, length("#Fields: ") + 1)
    split(rest, fields, " ")
    numFields = length(fields)
}

/^#/ {
    # ignore anything else starting with "#"
}

! /^#/ {
    split($0, fieldsThisLine, " ")
    if (NF == numFields) {
        print "\t{"
        for(i = 1; i < NF; i++)
        {
            printf "\t\t\"%s\": \"%s\",\n", fields[i], fieldsThisLine[i]
        }
        print "\t},"
    }
}

function printUrlQueryString(queryString)
{
    split(queryString, pairs, "&", seps)
    len = length(pairs)
    for (j = 1; j < len; ++j) {
        split(pairs[j], keyValue, "=", seps2)
        k = keyValue[1]
        v = keyValue[2]
        printf "\t\t\"%s\": \"%s\",\n", k, urlDecode(urlDecode(v))
    }
}

function base64Decode(thing)
{
  "echo "$thing" | base64 --decode" | getline x
  return x
}

function urlDecode(url) {
    for (i = 0x20; i < 0x40; ++i) {
        repl = sprintf("%c", i);
        if ((repl == "&") || (repl == "\\")) {
            repl = "\\" repl;
        }
        url = gensub(sprintf("%%%02X", i), repl, "g", url);
        url = gensub(sprintf("%%%02x", i), repl, "g", url);
    }
    return url;
}

BEGIN {
    print "{";
}

END {
    print "}"
}

/^#Version: / {
    printf "\t\"version\": \"%s\",\n", substr($0, length("#Version: ") + 1)
}

/^#Fields: / {
    rest = substr($0, length("#Fields: ") + 1)
    split(rest, fields, " ", seps)
    numFields = length(fields)
}

/^#/ {
    # ignore anything else starting with "#"
}

! /^#/ {
    split($0, fieldsThisLine, " ", sepsThrowAway)
    if (NF == numFields) {
        print "\t{"
        for(i = 1; i < NF; i++)
        {
            printf "\t\t\"%s\": \"%s\",\n", fields[i], fieldsThisLine[i]
        }
        print "\t},"
    }
}


Use the term "deprecated" instead of "old name" in order to be more explicit. (dm)

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

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

BEGIN {
  brlCommandValue = 0
  brlKeyValue = 0

  brlBlockDeprecations["CLIP_NEW"] = "CUTBEGIN"
  brlBlockDeprecations["CLIP_ADD"] = "CUTAPPEND"
  brlBlockDeprecations["COPY_LINE"] = "CUTLINE"
  brlBlockDeprecations["COPY_RECT"] = "CUTRECT"
  brlBlockDeprecations["CLIP_COPY"] = "COPYCHARS"
  brlBlockDeprecations["CLIP_APPEND"] = "APNDCHARS"
}

/^ *BRL_CMD_/ {
  brlCommand(substr($1, 9), $1, brlCommandValue++, getComment($0))
  next
}

/#define[ \t]*BRL_BLK_/ {
  prefix = substr($2, 1, 8)
  name = substr($2, 9)
  value = getDefineValue()
  help = getComment($0)
  brlBlock(name, $2, value, help)

  if (name in brlBlockDeprecations) {
    alias = brlBlockDeprecations[name]
    brlBlock(alias, prefix alias, value, "deprecated definition of " name " - " help)
  }

  next
}

/^ *BRL_KEY_/ {
  gsub(",", "", $1)
  key = tolower(substr($1, 9))
  gsub("_", "-", key)
  brlKey(substr($1, 9), $1, brlKeyValue++, key " key")
  next
}

/#define[ \t]*BRL_FLG_/ {
  brlFlag(substr($2, 9), $2, getDefineValue(), getComment($0))
  next
}

/#define[ \t]*BRL_DOT/ {
  value = getDefineValue()
  sub("^.*\\(", "", value)
  sub("\\).*$", "", value)
  brlDot(substr($2, 8), $2, value, getComment($0))
  next
}

function writeHeaderPrologue(symbol, copyrightFile) {
  writeCopyright(copyrightFile)

  headerSymbol = symbol
  print "#ifndef " headerSymbol
  writeMacroDefinition(headerSymbol)
  print ""

  print "#ifdef __cplusplus"
  print "extern \"C\" {"
  print "#endif /* __cplusplus */"
  print ""
}

function writeCopyright(file) {
  if (length(file) > 0) {
    while (getline line <file == 1) {
      if (match(line, "^ */\\* *$")) {
        print line

        while (getline line <file == 1) {
          print line
          if (match(line, "^ *\\*/ *$")) break
        }

        print ""
        break
      }
    }
  }
}

function writeHeaderEpilogue() {
  print ""
  print "#ifdef __cplusplus"
  print "}"
  print "#endif /* __cplusplus */"

  print ""
  print "#endif /* " headerSymbol " */"
}

function writeMacroDefinition(name, definition, help) {
  statement = "#define " name
  if (length(definition) > 0) statement = statement " " definition

  if (length(help) > 0) print makeDoxygenComment(help)
  print statement
}

function getComment(line) {
  if (!match(line, "/\\*.*\\*/")) return ""
  line = substr(line, RSTART+2, RLENGTH-4)

  match(line, "^\\** *")
  line = substr(line, RLENGTH+1)

  match(line, " *$")
  return substr(line, 1, RSTART-1)
}

function getDefineValue() {
  if ($3 !~ "^\\(") return getNormalizedConstant($3)
  if (match($0, "\\([^)]*\\)")) return substr($0, RSTART, RLENGTH)
  return ""
}

function getNormalizedConstant(value) {
   if (value ~ "^UINT64_C\\(.+\\)$") value = substr(value, 10, length(value)-10)
   return value
}

function makeDoxygenComment(text) {
  return "/** " text " */"
}

function beginDoxygenFile() {
  print "/** \\file"
  print " */"
  print ""
}

function getBrlapiKeyName(name) {
  if (name == "ENTER") return "LINEFEED"
  if (name ~ /^CURSOR_/) return substr(name, 8)
  return name
}

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

BEGIN {
  brlCommandValue = 0
  brlKeyValue = 0

  brlBlockAlias["CLIP_NEW"] = "CUTBEGIN"
  brlBlockAlias["CLIP_ADD"] = "CUTAPPEND"
  brlBlockAlias["COPY_LINE"] = "CUTLINE"
  brlBlockAlias["COPY_RECT"] = "CUTRECT"
  brlBlockAlias["CLIP_COPY"] = "COPYCHARS"
  brlBlockAlias["CLIP_APPEND"] = "APNDCHARS"
}

/^ *BRL_CMD_/ {
  brlCommand(substr($1, 9), $1, brlCommandValue++, getComment($0))
  next
}

/#define[ \t]*BRL_BLK_/ {
  prefix = substr($2, 1, 8)
  name = substr($2, 9)
  value = getDefineValue()
  help = getComment($0)
  brlBlock(name, $2, value, help)

  if (name in brlBlockAlias) {
    alias = brlBlockAlias[name]
    brlBlock(alias, prefix alias, value, "alias for " name " - " help)
  }

  next
}

/^ *BRL_KEY_/ {
  gsub(",", "", $1)
  key = tolower(substr($1, 9))
  gsub("_", "-", key)
  brlKey(substr($1, 9), $1, brlKeyValue++, key " key")
  next
}

/#define[ \t]*BRL_FLG_/ {
  brlFlag(substr($2, 9), $2, getDefineValue(), getComment($0))
  next
}

/#define[ \t]*BRL_DOT/ {
  value = getDefineValue()
  sub("^.*\\(", "", value)
  sub("\\).*$", "", value)
  brlDot(substr($2, 8), $2, value, getComment($0))
  next
}

function writeHeaderPrologue(symbol, copyrightFile) {
  writeCopyright(copyrightFile)

  headerSymbol = symbol
  print "#ifndef " headerSymbol
  writeMacroDefinition(headerSymbol)
  print ""

  print "#ifdef __cplusplus"
  print "extern \"C\" {"
  print "#endif /* __cplusplus */"
  print ""
}

function writeCopyright(file) {
  if (length(file) > 0) {
    while (getline line <file == 1) {
      if (match(line, "^ */\\* *$")) {
        print line

        while (getline line <file == 1) {
          print line
          if (match(line, "^ *\\*/ *$")) break
        }

        print ""
        break
      }
    }
  }
}

function writeHeaderEpilogue() {
  print ""
  print "#ifdef __cplusplus"
  print "}"
  print "#endif /* __cplusplus */"

  print ""
  print "#endif /* " headerSymbol " */"
}

function writeMacroDefinition(name, definition, help) {
  statement = "#define " name
  if (length(definition) > 0) statement = statement " " definition

  if (length(help) > 0) print makeDoxygenComment(help)
  print statement
}

function getComment(line) {
  if (!match(line, "/\\*.*\\*/")) return ""
  line = substr(line, RSTART+2, RLENGTH-4)

  match(line, "^\\** *")
  line = substr(line, RLENGTH+1)

  match(line, " *$")
  return substr(line, 1, RSTART-1)
}

function getDefineValue() {
  if ($3 !~ "^\\(") return getNormalizedConstant($3)
  if (match($0, "\\([^)]*\\)")) return substr($0, RSTART, RLENGTH)
  return ""
}

function getNormalizedConstant(value) {
   if (value ~ "^UINT64_C\\(.+\\)$") value = substr(value, 10, length(value)-10)
   return value
}

function makeDoxygenComment(text) {
  return "/** " text " */"
}

function beginDoxygenFile() {
  print "/** \\file"
  print " */"
  print ""
}

function getBrlapiKeyName(name) {
  if (name == "ENTER") return "LINEFEED"
  if (name ~ /^CURSOR_/) return substr(name, 8)
  return name
}


ctx: recognize surf url here

ctx: recognize surf url here

### gather context data

# note: attr aren't available yet! upside is, `req -a ctx.foo=bar` can override this files code:

BEGIN {
    # interactive terminal
    if(attr["term"])
	setCtx("term", ENVIRON["TERM"])

    # x11 display
    if(ENVIRON["DISPLAY"]) {
	setCtx("display", ENVIRON["DISPLAY"])
	# x11 selection
	setCtx("sel", trim(btick("xclip -o")))
	# current x11 win id
	setCtx("xwin", word(btick("xprop -root _NET_ACTIVE_WINDOW"), 5))
	split_xprop(btick("xprop -id " get("ctx.xwin")), ctx, "ctx.xprop")
    }

    # x11 applications
    if(get("ctx.xprop.wm_class_name") == "Emacs") {
	setCtx("app.exe", "emacs")
	f = get("ctx.xprop.wm_name")
	split_file(f, ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "XTerm" &&
    match(get("ctx.xprop.wm_name"), /^([^@]*)@([^:]*):(.*)$/, m)) {
	setCtx("app.exe", "xterm")
	setCtx("app.user", m[1])
	setCtx("app.host", m[2])
	setCtx("app.dir", m[3])
	split_file(m[3], ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "Rox" &&
    match(get("ctx.xprop.wm_name"), /^(.*) \+[ST]$/, m)) {
	setCtx("app.exe", "rox")
	f = gensub(/^~\//, HOME "/", 1, m[1])
	split_file(f, ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "Sonata" &&
    match(get("ctx.xprop.wm_name"), /^(.*)\/([^/]*)$/, m)) {
	setCtx("app.exe", "sonata")
	setCtx("audio_time", m[3])
	setCtx("audio_total", m[4])
	f = "/home/rfigura/mnt/wirsing/home/rfigura/pub/audio/" m[1] "/" m[2]
	split_file(f, ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "Hgtk" &&
    match(get("ctx.xprop.wm_name"), /^(.*) - (.*)$/, m)) {
	setCtx("app.exe", "hgtk")
	split_file(m[1], ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "Surf")
	setCtx("app.url", get("ctx.xprop.url"))

    # working directory
    setCtx("wdir", ENVIRON["PWD"])
    if(get("ctx.file.dirname"))
	setCtx("wdir", get("ctx.file.dirname"))

    # current wifi
    split(btick("wpa_cli status"), m, "\n")
    for(i = 1; i <= length(m); ++i)
	if(match(m[i], /^([^=]*)=(.*)$/, a))
	    setCtx("wifi_" a[1], a[2])
}

### gather context data

# note: attr aren't available yet! upside is, `req -a ctx.foo=bar` can override this files code:

BEGIN {
    # interactive terminal
    if(attr["term"])
	setCtx("term", ENVIRON["TERM"])

    # x11 display
    if(ENVIRON["DISPLAY"]) {
	setCtx("display", ENVIRON["DISPLAY"])
	# x11 selection
	setCtx("sel", trim(btick("xclip -o")))
	# current x11 win id
	setCtx("xwin", word(btick("xprop -root _NET_ACTIVE_WINDOW"), 5))
	split_xprop(btick("xprop -id " get("ctx.xwin")), ctx, "ctx.xprop")
    }

    # x11 applications
    if(get("ctx.xprop.wm_class_name") == "Emacs") {
	setCtx("app.exe", "emacs")
	f = get("ctx.xprop.wm_name")
	split_file(f, ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "XTerm" &&
    match(get("ctx.xprop.wm_name"), /^([^@]*)@([^:]*):(.*)$/, m)) {
	setCtx("app.exe", "xterm")
	setCtx("app.user", m[1])
	setCtx("app.host", m[2])
	setCtx("app.dir", m[3])
	split_file(m[3], ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "Rox" &&
    match(get("ctx.xprop.wm_name"), /^(.*) \+[ST]$/, m)) {
	setCtx("app.exe", "rox")
	f = gensub(/^~\//, HOME "/", 1, m[1])
	split_file(f, ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "Sonata" &&
    match(get("ctx.xprop.wm_name"), /^(.*)\/([^/]*)$/, m)) {
	setCtx("app.exe", "sonata")
	setCtx("audio_time", m[3])
	setCtx("audio_total", m[4])
	f = "/home/rfigura/mnt/wirsing/home/rfigura/pub/audio/" m[1] "/" m[2]
	split_file(f, ctx, "ctx.file")
    }
    if(get("ctx.xprop.wm_class_name") == "Hgtk" &&
    match(get("ctx.xprop.wm_name"), /^(.*) - (.*)$/, m)) {
	setCtx("app.exe", "hgtk")
	split_file(m[1], ctx, "ctx.file")
    }

    # working directory
    setCtx("wdir", ENVIRON["PWD"])
    if(get("ctx.file.dirname"))
	setCtx("wdir", get("ctx.file.dirname"))

    # current wifi
    split(btick("wpa_cli status"), m, "\n")
    for(i = 1; i <= length(m); ++i)
	if(match(m[i], /^([^=]*)=(.*)$/, a))
	    setCtx("wifi_" a[1], a[2])
}