Work around a Linux bug on Unsafe*Pointer<va_list>

#!/usr/bin/awk
#
# Patch the generated wrapper Swift code to handle special cases
#
BEGIN { etpInit = 0 ; vaptrptr = 0 }
/public convenience init.T: ErrorTypeProtocol./ {
	etpInit = 1
	print "    /// Convenience copy constructor, creating a unique copy"
	print "    /// of the passed in Error.  Needs to be freed using free()"
	print "    /// (automatically done in deinit if you use ErrorType)."
}
/self.init.other.ptr./ {
	if (etpInit) {
		print "	self.init(g_error_copy(other.ptr))"
		etpInit = 0
		next
	}
}
/no reference counting for GError, cannot ref/ { next }
/no reference counting for GError, cannot unref/ {
	print "	    g_error_free(error_ptr)"
	next
}
/ -> GIConv {/, /^}/ {
	sub(/GIConv {/,"GIConv? {")
	sub(/return rv/,"return rv == GIConv(bitPattern: -1) ? nil : rv")
}
/UnsafeMutablePointer.CVaListPointer/ {
	vaptrptr = 1
	print "#if !os(Linux)"
}
/Pointer<va_list>/ {
	vaptrptr = 1
	print "#if !os(Linux)"
}
/^$/ {
	if (vaptrptr) {
		print "#endif"
		vaptrptr = 0
	}
}
/\/\/\// {
	if (vaptrptr) {
		print "#endif"
		vaptrptr = 0
	}
}
// { print }

#!/usr/bin/awk
#
# Patch the generated wrapper Swift code to handle special cases
#
BEGIN { etpInit = 0 ; vaptrptr = 0 }
/public convenience init.T: ErrorTypeProtocol./ {
	etpInit = 1
	print "    /// Convenience copy constructor, creating a unique copy"
	print "    /// of the passed in Error.  Needs to be freed using free()"
	print "    /// (automatically done in deinit if you use ErrorType)."
}
/self.init.other.ptr./ {
	if (etpInit) {
		print "	self.init(g_error_copy(other.ptr))"
		etpInit = 0
		next
	}
}
/no reference counting for GError, cannot ref/ { next }
/no reference counting for GError, cannot unref/ {
	print "	    g_error_free(error_ptr)"
	next
}
/ -> GIConv {/, /^}/ {
	sub(/GIConv {/,"GIConv? {")
	sub(/return rv/,"return rv == GIConv(bitPattern: -1) ? nil : rv")
}
/UnsafeMutablePointer.CVaListPointer/ {
	vaptrptr = 1
	print "#if !os(Linux)"
}
/^$/ {
	if (vaptrptr) {
		print "#endif"
		vaptrptr = 0
	}
}
/\/\/\// {
	if (vaptrptr) {
		print "#endif"
		vaptrptr = 0
	}
}
// { print }


replace old slidy stylesheet with current one; .oO we could just use a constant html header now

BEGIN {
    interesting = 1
}

skipScript && /<\/script>/ {
  skipScript = 0
  next
}

skipScript {
  next
}

/<script type="text\/javascript" charset="utf-8">/ {
  print "  <script src='http://www.w3.org/Talks/Tools/Slidy2/scripts/slidy.js' charset='utf-8' type='text/javascript'></script>"
  skipScript = 1
  next
}

/<style type="text\/css">/ {
  styleEncountered++
}

styleEncountered == 2 && /<\/style>/ {
  print "  <link rel='stylesheet' type='text/css' media='screen, projection, print' href='http://www.w3.org/Talks/Tools/Slidy2/styles/slidy.css' />"
  styleEncountered = 3
}

styleEncountered == 2 {
  next
}

{
    sub(/<title>Haskell: Functional Programming, Solid Code, Big Data<\/title>/, "<title>Intro \\“Functional Programming\\”</title>")
    sub(/<meta name="date" content="2011-09-18" \/>/, "<meta name='date' content='2011-10-19' />")
    sub(/<meta name="author" content="Bryan O'Sullivan" \/>/, "<meta name='author' content='Gabor Greif' />\n  <meta name='duration' content='45' />\n  <link type='text/css' rel='stylesheet' href='http://www.gstatic.com/codesite/ph/13841197563397998716/css/ph_detail.css' />")
}

/^<body>/ {
    interesting = 0
    print
    next
}

interesting {
    print
    next
}

BEGIN {
    interesting = 1
}

skipScript && /<\/script>/ {
  skipScript = 0
  next
}

skipScript {
  next
}

### TODO:
#  <link rel="stylesheet" type="text/css" media="screen, projection, print" href="http://www.w3.org/Talks/Tools/Slidy2/styles/slidy.css" />

/<script type="text\/javascript" charset="utf-8">/ {
  print "  <script src='http://www.w3.org/Talks/Tools/Slidy2/scripts/slidy.js' charset='utf-8' type='text/javascript'></script>"
  skipScript = 1
  next
}

{
    sub(/<title>Haskell: Functional Programming, Solid Code, Big Data<\/title>/, "<title>Intro \\“Functional Programming\\”</title>")
    sub(/<meta name="date" content="2011-09-18" \/>/, "<meta name='date' content='2011-10-19' />")
    sub(/<meta name="author" content="Bryan O'Sullivan" \/>/, "<meta name='author' content='Gabor Greif' />\n  <meta name='duration' content='45' />\n  <link type='text/css' rel='stylesheet' href='http://www.gstatic.com/codesite/ph/13841197563397998716/css/ph_detail.css' />")
}

/^<body>/ {
    interesting = 0
    print
    next
}

interesting {
    print
    next
}


syscall: Remove a couple more 3-parameter match's in mksyscall.awk.

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

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

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

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

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

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

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

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

    line = $0

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

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

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

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

    getline
    line = $0

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

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

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

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

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

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

    loc = gofnname "/" cfnname ":"

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

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

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

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

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

	ctype = a[2]

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

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

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

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

	carg++
    }

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

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

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

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

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

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

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

    print "}"

    print ""

    next
}

{ next }

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

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

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

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

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

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

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

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

    line = $0

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

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

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

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

    getline
    line = $0

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

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

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

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

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

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

    loc = gofnname "/" cfnname ":"

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

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

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

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

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

	ctype = a[2]

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

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

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

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

	carg++
    }

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

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

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

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

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

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

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

    print "}"

    print ""

    next
}

{ next }

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


Delete postbanken.awk

Delete postbanken.awk

es funktioniert nicht wie beschrieben und wird jetzt doch nicht mehr gebraucht

#
# Quelle (2014-12-07):
# http://wiki.gnucash.org/wiki/FAQ#Q:_How_do_I_convert_from_CSV.2C_TSV.2C_XLS_.28Excel.29.2C_or_SXC_.28OpenOffice.org_Calc.29_to_a_QIF.3F
# Anwendung:
# awk -f postbanken.awk kontoutskrift.csv > import.qif
#
# awk convert fra Postbankens CSV til QIF(Gnucash, quicken, osv)
# CSV fra Postbanken er ikke en kommaseparert fil, men en tekstfil med feltene på fast plass.
# Bruker derfor fieldwidths i awk. Det går også ant å bruke substr().
# Kilder:
# http://wiki.gnucash.org/wiki/FAQ
# http://www.ibm.com/developerworks/library/l-awk1.html
# http://www.ibm.com/developerworks/library/l-awk2.html
# http://www.grymoire.com/Unix/Awk.html#uh-67
# Samt manualen til awk og egrep.
#
# Bruk filen slik:
# $ awk -f postbanken.awk kontoutskrift.csv > import.qif
#
#
# Arve Seljebu - juni 2010

# Del opp filen i felter og skriv "!Type:Bank" bare en gang i toppen av filen
BEGIN {FIELDWIDTHS="8 5 17 35 31 11 1 11"; print "!Type:Bank";}
# Bare bruk linjen hvis den inneholder dato
{ if ($0 ~ /[0-9][0-9].[0-9][0-9].[0-9][0-9]/) {
# Dato
  print "D" $1;
# Avkommenter neste linje for å bruke BETALING, BETALING UTLAND osv som konto/kategori
# print "L" $3;
# Beskrivelse/memo
  print "M" $4;
# Debit eller kredit
  if ($6 == 0) { print "T-" $8; }
  else { print "T" $6; }
  print "^";
  }
}


MFp4:

MFp4:

- Check for duplicated symbols and suggest moving them to ObsoleteVersions.
- Improve and unify error handling.
- Make the regular expressions more uniform, robust, and less sensitive
  to harmless variations in the input such as those to whitespace amount.

Reviewed by:	deischen
Tested with:	md5 (Version.map files in /usr/obj stay the same)

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

#
# Make a list of all the library versions listed in the master file.
#
#   versions[] - array indexed by version name, contains number
#                of symbols (+ 1) found for each version.
#   successors[] - array index by version name, contains successor
#                  version name.
#   symbols[][] - array index by [version name, symbol index], contains
#                 names of symbols defined for each version.
#   names[] - array index is symbol name and value is count,
#	      used to check for duplicate symbols and warn about them.
#
BEGIN {
	brackets = 0;
	errors = 0;
	version_count = 0;
	current_version = "";
	stderr = "/dev/stderr";
	while (getline < vfile) {
		# Strip comments.
		sub("#.*$", "", $0);

		# Strip leading and trailing whitespace.
		sub("^[ \t]+", "", $0);
		sub("[ \t]+$", "", $0);

		if (/^[a-zA-Z0-9._]+[ \t]*{$/) {
			# Strip brace.
			sub("{", "", $1);
			brackets++;
			symver = $1;
			versions[symver] = 1;
			successors[symver] = "";
			generated[symver] = 0;
			version_count++;
		}
		else if (/^}[ \t]*[a-zA-Z0-9._]+[ \t]*;$/) {
			v = $1 != "}" ? $1 : $2;
			# Strip brace.
			sub("}", "", v);
			# Strip semicolon.
			sub(";", "", v);
			if (symver == "") {
				printf("File %s: Unmatched bracket.\n",
				vfile) > stderr;
				errors++;
			}
			else if (versions[v] != 1) {
				printf("File %s: `%s' has unknown " \
				    "successor `%s'.\n",
				    vfile, symver, v) > stderr;
				errors++;
			}
			else
				successors[symver] = v;
			brackets--;
		}
		else if (/^}[ \t]*;$/) {
			if (symver == "") {
				printf("File %s: Unmatched bracket.\n",
				    vfile) > stderr;
				errors++;
			}
			# No successor
			brackets--;
		}
		else if (/^}$/) {
			printf("File %s: Missing final semicolon.\n",
			    vfile) > stderr;
			errors++;
		}
		else if (/^$/)
			;  # Ignore blank lines.
		else {
			printf("File %s: Unknown directive: `%s'.\n",
			    vfile, $0) > stderr;
			errors++;
		}
	}
	brackets = 0;
}

{
	# Set meaningful filename for diagnostics.
	filename = FILENAME != "" ? FILENAME : "<stdin>";

	# Delete comments, preceding and trailing whitespace, then
	# consume blank lines.
	sub("#.*$", "", $0);
	sub("^[ \t]+", "", $0);
	sub("[ \t]+$", "", $0);
	if ($0 == "")
		next;
}

/^[a-zA-Z0-9._]+[ \t]*{$/ {
	# Strip bracket from version name.
	sub("{", "", $1);
	if (current_version != "") {
		printf("File %s, line %d: Illegal nesting detected.\n",
		    filename, FNR) > stderr;
		errors++;
	}
	else if (versions[$1] == 0) {
		printf("File %s, line %d: Undefined " \
		    "library version `%s'.\n", filename, FNR, $1) > stderr;
		errors++;
		# Remove this entry from the versions.
		delete versions[$1];
	}
	else
		current_version = $1;
	brackets++;
	next;
}

/^[a-zA-Z0-9._]+[ \t]*;$/ {
	# Strip semicolon.
	sub(";", "", $1);
	if (current_version != "") {
		count = versions[current_version];
		versions[current_version]++;
		symbols[current_version, count] = $1;
		if (names[$1]++) {
			printf("File %s, line %d: Duplicated symbol `%s'. " \
			    "Did you forget to move it to ObsoleteVersions?\n",
			    filename, FNR, $1) > stderr;
			errors++;
		}
	}
	else {
		printf("File %s, line %d: Symbol `%s' outside version scope.\n",
		    filename, FNR, $1) > stderr;
		errors++;
	}
	next;
}

/^}[ \t]*;$/ {
	brackets--;
	if (brackets < 0) {
		printf("File %s, line %d: Unmatched bracket.\n",
		    filename, FNR, $1) > stderr;
		errors++;
		brackets = 0;	# Reset
	}
	current_version = "";
	next;
}

{
	printf("File %s, line %d: Unknown directive: `%s'.\n",
	    filename, FNR, $0) > stderr;
	errors++;
}

function print_version(v)
{
	# This function is recursive, so return if this version
	# has already been printed.  Otherwise, if there is an
	# ancestral version, recursively print its symbols before
	# printing the symbols for this version.
	#
	if (generated[v] == 1)
		return;
	if (successors[v] != "")
		print_version(successors[v]);

	printf("%s {\n", v);

	# The version count is always one more that actual,
	# so the loop ranges from 1 to n-1.
	#
	for (i = 1; i < versions[v]; i++) {
		if (i == 1)
			printf("global:\n");
		printf("\t%s;\n", symbols[v, i]);
	}

	version_count--;
	if (version_count == 0) {
		printf("local:\n");
		printf("\t*;\n");
	}
	if (successors[v] == "")
		printf("};\n");
	else
		printf("} %s;\n", successors[v]);
	printf("\n");

	generated[v] = 1;
    }

END {
	if (errors) {
		printf("%d errors total.\n", errors) > stderr;
		exit(1);
	}
	# OK, no errors.
	for (v in versions) {
		print_version(v);
	}
}

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

#
# Make a list of all the library versions listed in the master file.
#
#   versions[] - array indexed by version name, contains number
#                of symbols (+ 1) found for each version.
#   successors[] - array index by version name, contains successor
#                  version name.
#   symbols[][] - array index by [version name, symbol index], contains
#                 names of symbols defined for each version.
#
BEGIN {
	brackets = 0;
	errors = 0;
	version_count = 0;
	current_version = "";
	stderr = "/dev/stderr";
	while (getline < vfile) {
		# Strip comments.
		sub("#.*$", "", $0);

		# Strip trailing spaces.
		sub(" *$", "", $0);

		if (/^[ \t]*[a-zA-Z0-9._]+ *{/) {
			brackets++;
			symver = $1;
			versions[symver] = 1;
			successors[symver] = "";
			generated[symver] = 0;
			version_count++;
		}
		else if (/^[ \t]*} *[a-zA-Z0-9._]+ *;/) {
			# Strip semicolon.
			gsub(";", "", $2);
			if (symver == "")
				printf("Unmatched bracket.\n");
			else if (versions[$2] != 1)
				printf("File %s: %s has unknown " \
				    "successor %s\n", vfile, symver, $2);
			else
				successors[symver] = $2;
			brackets--;
		}
		else if (/^[ \t]*};/) {
			if (symver == "")
				printf("File %s: Unmatched bracket.\n",
				    vfile) > stderr;
			# No successor
			brackets--;
		}
		else if (/^[ \t]*}/) {
			printf("File %s: Missing ending semi-colon.\n",
			    vfile) > stderr;
		}
		else if (/^$/)
			;  # Ignore blank lines.
		else
			printf("File %s: Unknown directive: %s\n",
			    vfile, $0) > stderr;
	}
	brackets = 0;
}

/.*/ {
	# Delete comments, preceding and trailing whitespace, then
	# consume blank lines.
	sub("#.*$", "", $0);
	sub("^[ \t]+", "", $0);
	sub("[ \t]+$", "", $0);
	if ($0 == "")
		next;
}

/^[a-zA-Z0-9._]+ +{$/ {
	# Strip bracket from version name.
	sub("{", "", $1);
	if (current_version != "")
		printf("File %s, line %d: Illegal nesting detected.\n",
		    FILENAME, FNR) > stderr;
	else if (versions[$1] == 0) {
		printf("File %s, line %d: Undefined " \
		    "library version %s\n", FILENAME, FNR, $1) > stderr;
		# Remove this entry from the versions.
		delete versions[$1];
	}
	else
		current_version = $1;
	brackets++;
	next;
}

/^[a-zA-Z0-9._]+ *;$/ {
	if (current_version != "") {
		count = versions[current_version];
		versions[current_version]++;
		symbols[current_version, count] = $1;
	}
	next;
}

/^} *;$/ {
	brackets--;
	if (brackets < 0) {
		printf("File %s, line %d: Unmatched bracket.\n",
		    FILENAME, FNR, $1) > stderr;
		brackets = 0;	# Reset
	}
	current_version = "";
	next;
}

/.*/ {
	printf("File %s, line %d: Unknown directive: '%s'\n",
	    FILENAME, FNR, $0) > stderr;
}

function print_version(v)
{
	# This function is recursive, so return if this version
	# has already been printed.  Otherwise, if there is an
	# ancestral version, recursively print its symbols before
	# printing the symbols for this version.
	#
	if (generated[v] == 1)
		return;
	if (successors[v] != "")
		print_version(successors[v]);

	printf("%s {\n", v);

	# The version count is always one more that actual,
	# so the loop ranges from 1 to n-1.
	#
	for (i = 1; i < versions[v]; i++) {
		if (i == 1)
			printf("global:\n");
		printf("\t%s\n", symbols[v, i]);
	}

	version_count--;
	if (version_count == 0) {
		printf("local:\n");
		printf("\t*;\n");
	}
	if (successors[v] == "")
		printf("};\n");
	else
		printf("} %s;\n", successors[v]);
	printf("\n");

	generated[v] = 1;
    }
END {
	for (v in versions) {
		print_version(v);
	}
}


program update

program update

#!/bin/awk -f
#encoding:utf-8
#
# Author : Yoshihiro Tanaka
# Date   : 2014-11-04
# Version: 0.1.3

function output(chrom, header, seq) {
    filename = "db/Canis_familiaris.CanFam3.1.dna.chromosome." chrom ".fa";
    printf header >  filename;
    print  seq    >> filename;
    close(filename);
    print "Successful output: " filename;
}
BEGIN {
    c  = 0
}
{
    if (">" == substr($1, 1, 1)) {
        if (c != 0) {
            if (chrom ~ /^([0-9][0-9]?|MT|X)/) {
                output(chrom, header, seq)
            }
        }
        chrom  = substr($1, 2);
        header = $0;
        seq = "";
    } else {
        seq = seq "\n" $0
    }
    c++;
    printf("progress: %d\r\b", c)
}
END {
    output(chrom, header, seq)
}

#!/bin/awk -f
#encoding:utf-8
#
# Author : Yoshihiro Tanaka
# Date   : 2014-11-04
# Version: 0.1.2

function output(chrom, header, seq) {
    filename = "db/Canis_familiaris.CanFam3.1.dna.chromosome." chrom ".fa";
    printf header >  filename;
    print  seq    >> filename;
    close(filename);
    print "Successful output: " filename;
}
BEGIN {
    "wc -l " ARGV[1] " | xargs -n 1 | head -n 1" | getline wc;
    wc = wc ".0"
    c  = 0
}
{
    if (">" == substr($1, 1, 1)) {
        if (c != 0) {
            if (chrom ~ /^([0-9][0-9]?|MT|X)/) {
                output(chrom, header, seq)
            }
        }
        chrom  = substr($1, 2);
        header = $0;
        seq = "";
    } else {
        seq = seq "\n" $0
    }
    c++;
    printf("progress: %f%%\r\b", (c / wc)*100)
}
END {
    output(chrom, header, seq)
}


Add method to generate temp bed for single end

BEGIN{
  FS="\t";
  OFS="\t";
  alignments=0;
  if ("" == base) {
    print "Missing output base via -v base=";
    exit 1;
  }
  if ("" == endness) {
    print "Missing endness style (se|pe) via -v endness=";
    exit 1;
  } else if ( ("se" == endness) && (""==size) ) {
    print "Missing fragment size since single end via -v size=";
    exit 1;
  }
}

function pe_bedder(path) {
  start=($4-1)
  if ( (($2==83) || ($2==147)) && ($9>0) ) {
    print $3,start,(start+$9),".","1","-" > path;
  } else if ( ((2==83) || ($2==147)) && ($9<0) ) {
    print $3,start,(start-$9),".","1","-" > path;
  } else if ( (($2==99) || ($2==163)) && ($9>0) ) {
    print $3,start,(start+$9),".","1","+" > path;
  } else if ( (($2==99) || ($2==163)) && ($9<0) ) {
    print $3,start,(start-$9),".","1","+" > path;
  }
}

function se_bedder(path,size) {
  if ($2==16) {
    start = ($4+length($10) - size);
    if (start <=0) {
      start = 1;
    }
    print $3,start,($4-1+length($10)),".","1","-" > path;
  } else if ($2==0) {
    start=$4;
    if (start<=0) {
      start=1;
    }
    print $3,start,($4-1+size),".","1","+" > path;
  }
}

{
  alignments++;
  if ("pe" == endness) {
    sub(/-/,"",$9);
    tlens[$9]++;
    pe_bedder(base"_tmp.bed");
  } else if ("se" == endness) {
    se_bedder(base"_tmp.bed",size);
  }
}

END {
  print alignments > base"_num_alignments.txt";
  if ("pe" == endness) {
    output = " sort -k 2 -n -r|head -n 1|cut -f 1 >" base"_estimated_size.txt";
    for(tlen in tlens) {
      print tlen,tlens[tlen] | output;
    }
  }
}

BEGIN{
  FS="\t";
  OFS="\t";
  alignments=0;
  if ("" == base) {
    print "Missing output base via -v base=";
    exit 1;
  }
  if ("" == endness) {
    print "Missing endness style (se|pe) via -v endness=";
    exit 1;
  } else if ( ("se" == endness) && (""==size) ) {
    print "Missing fragment size since single end via -v size=";
    exit 1;
  }
}

function pe_bedder(path) {
  start=($4-1)
  if ( (($2==83) || ($2==147)) && ($9>0) ) {
    print $3,start,(start+$9),".","1","-" > path;
  } else if ( ((2==83) || ($2==147)) && ($9<0) ) {
    print $3,start,(start-$9),".","1","-" > path;
  } else if ( (($2==99) || ($2==163)) && ($9>0) ) {
    print $3,start,(start+$9),".","1","+" > path;
  } else if ( (($2==99) || ($2==163)) && ($9<0) ) {
    print $3,start,(start-$9),".","1","+" > path;
  }
}

function se_bedder(path,size) {
}

{
  alignments++;
  if ("pe" == endness) {
    sub(/-/,"",$9);
    tlens[$9]++;
    pe_bedder(base"_tmp.bed");
  } else if ("se" == endness) {
  }
}

END {
  print alignments > base"_num_alignments.txt";
  if ("pe" == endness) {
    output = " sort -k 2 -n -r|head -n 1|cut -f 1 >" base"_estimated_size.txt";
    for(tlen in tlens) {
      print tlen,tlens[tlen] | output;
    }
  }
}


Main: set default indentation to 4

Main: set default indentation to 4

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

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

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

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

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

    RS = "\n"
    I  = "    "

    ExitCode = 0

    Option["debug"] = 0

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

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

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

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

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

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

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

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

# Main entry point.
BEGIN {
    preInit()

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

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

        # -H, -h, -help
        match(ARGV[pos], /^--?(h(e(lp?)?)?|H)$/)
        if (RSTART) {
            print getHelp()
            exit
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        break # no more option from here
    }

    # Option parsing finished
    postInit()

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

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

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

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

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

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

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

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

    if (Option["interactive"]) {
        print AnsiCode["bold"] AnsiCode[tolower(Option["prompt-color"])] getVersion() AnsiCode[0] > "/dev/stderr"
        print AnsiCode[tolower(Option["prompt-color"])] "(:q to quit)" AnsiCode[0] > "/dev/stderr"
    }

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

    # Disable ANSI SGR (Select Graphic Rendition) codes if required
    if (Option["no-ansi"])
        delete AnsiCode

    if (pos < ARGC) {
        # More parameters

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

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

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

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

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

    exit ExitCode
}


more edits to match2tpl script

more edits to match2tpl script

#!/bin/gawk -f

BEGIN{
  FS = "|";
  OFS= "|";

  # CONFIG
  PL = "../theplantlist/data/tpl.csv" ;
  # Column order
  PL_code = 1; PL_f = 3   ; PL_xg = 4 ; PL_g = 5  ; PL_xs = 6 ; PL_s = 7;
  PL_st = 8;   PL_ssp = 9 ; PL_a = 10 ; PL_status = 11 ; PL_syn = 12

  IN = "./names.csv" ;
  # Column order
  IN_code = 1; IN_xg = 2 ; IN_g = 3  ; IN_xs = 4 ; IN_s = 5;
  IN_st = 6;   IN_ssp = 7 ; IN_a = 8 ;

  # STEP 0. Read data

  print "Reading ThePlantList..." > "/dev/stderr";
  while ((getline < PL) > 0) {
    PLdata[$PL_code] = $0;
    PLg[$PL_code] = $PL_g ;
    PLglist[$PL_g] = 1;
    PLgsaStr[$PL_code] = $PL_xg " " $PL_g " " $PL_xs " " $PL_s " "  \
      $PL_st " " $PL_ssp " " $PL_a ;
    gsub(/\ \ */," ",PLgsaStr[$PL_code]);
    gsub(/\ *$/,"",PLgsaStr[$PL_code]);
    gsub(/^\ */,"",PLgsaStr[$PL_code]);
    gsakey = $PL_xg $PL_g $PL_xs $PL_s   \
      gensub(/\./,"","G",$PL_st) $PL_ssp        \
      tolower(gensub(/[ .]/,"","G",$PL_a));
    PLgsakey[$PL_code] = gsakey;
    PLcode[gsakey] = $PL_code;
    PLsyn[$PL_code] = $PL_syn;
  }
  print "Done.\n"> "/dev/stderr";

  print "Reading your names list..." > "/dev/stderr";
  while ((getline < IN) > 0) {
    INdata[++inputorder] = $0;
    INcode[inputorder] = $IN_code ;
    INg[inputorder] = $IN_g ;
    INgsaStr[inputorder] = $IN_xg " " $IN_g " " $IN_xs " " $IN_s " " \
      $IN_st " " $IN_ssp " " $IN_a ;
    gsub(/\ \ */," ", INgsaStr[inputorder]);
    gsub(/\ *$/,"",INgsaStr[inputorder]);
    gsub(/^\ */,"",INgsaStr[inputorder]);
    INglist[$IN_g] = 1;
    INgsakey[inputorder] = $IN_xg $IN_g $IN_xs $IN_s \
      gensub(/\./,"","G",$IN_st) $IN_ssp \
      tolower(gensub(/[ .]/,"","G",$IN_a));
    # INcode[gsakey] = $IN_code;
  }
  print "  Done.\n" > "/dev/stderr";

  # STEP 1. checking genera

  print "Checking genera..." > "/dev/stderr";
  for (i in INglist) {
    if (!PLglist[i])                                                    \
      print "Genus missing (no further matching):" i > "/dev/stderr";
    INgNotPL[i] = 1;
  }
  print "  Done.\n" > "/dev/stderr";

  # --------------------------------------------------------------

  # STEP 6.

  cmd = "test -e names.manual.EDITED.csv ; echo $?";
  cmd | getline test1;
  close(cmd);
  cmd = "test -e names.simplematch.csv ; echo $?";
  cmd | getline test2;
  close(cmd);
  if ((test1 == "0") && (test2 == "0")) {

    while ((getline < "names.simplematch.csv") > 0) {
      resultPL[$1] = $2;
      status[$1] = "gsa";
    }
    while ((getline < "names.manual.EDITED.csv") > 0) {
      if ($5 == 1) {
        resultPL[$1] = $4;
        status[$1] = "manual";
      }
    }

    for (i = 1 ; i <= inputorder ; i++) {

      if (PLsyn[resultPL[INcode[i]]]) final[i] = PLsyn[resultPL[INcode[i]]];
      else final[i] = resultPL[INcode[i]];

      print INdata[i], status[INcode[i]], PLdata[resultPL[INcode[i]]], PLdata[final[i]];
    }
    exit;
  }

  # --------------------------------------------------------------

  # STEP 2. try simple matching
  print "Simple matching..." > "/dev/stderr";
  for (i = 1 ; i <= inputorder ; i++) {
    if (PLcode[INgsakey[i]]) {
      INmatched[i] = 1;
      print INcode[i] , PLdata[PLcode[INgsakey[i]]] > "names.simplematch.csv"
    }
    else {
      # prepare the genus sublists for agrep matching
      makegenus[INg[i]] = 1;
    }
  }
  print "  Done.\n" > "/dev/stderr";

  # STEP 3. make sublists, for agrep
  system("mkdir tmp_genera");
  for (i in PLdata) {
    if (makegenus[PLg[i]]) {  # note: this does not find taxa not in PL!
      print i " " PLgsakey[i]  >> "tmp_genera/" PLg[i] ".csv" ;
      close("tmp_genera/" PLg[i] ".csv");
    }
  }

  # STEP 4. try agrep matching on species name
  for (i = 1 ; i <= inputorder ; i++) {
    if (!INmatched[i] && (!INgNotPL[INg[i]])) {
      cmd = "agrep -k -2 '" INgsakey[i] "' tmp_genera/" INg[i] ".csv";
      agreps = "";
      RS = "\x04";
      cmd | getline agreps;
      close(cmd);
      RS = "\n";
      if (length(agreps) > 1) {
        na = split(agreps, a, "\n");
        for (j = 1; j < na; j++) {
          split(a[j],b," ");
          print INcode[i], INgsaStr[i], PLgsaStr[b[1]], b[1] > "names.manual.csv";
        }

      }
    }
  }

  # STEP 5. Manually edit "names.manual.csv"

  exit;
}

#   while ((getline < IN) > 0) INglist[$IN_g] = 1;
#   for (i in INglist) {
#     if (!PLglist[i]) print "Genera

#   FS="|";
#   # read in the plant list
#   while ((getline < \
#           "/home/cam/public_html/xabi/tools/theplantlist/data/tpl.csv") > 0) {
#     data[$1] = $0;
#     gs[$5 "|" $7] = gs[$5 "|" $7] "|" $1;
#   }

#   # make agrep list
#   #for (i in gs) print i > "_agreplist" ;
#   #close("_agreplist");

#   # read in lookup list
#   while ((getline < ARGV[1]) > 0) {
#     found = 0;
#     gsub(/NULL/,"",$0);
#     gsub(/\ /,"",$2); # fix spaces
#     gsub(/cf[ .]/,"",$3);
#     gsub(/\ /,"",$3);
#     gsub(/\ /,"",$5);
#     print $2 " " $3 " " $4 " " $5 " " $6;

#     # does the genus and species not match?
#     if (!gs[$2 "|" $3]) {
#       # print "  not found";
#       print "  trying spelling...";
#       cmd = "agrep -k -2 '" $2 "|" $3 "' _agreplist";
#       agreps = "";
#       RS = "\x04";
#       cmd | getline agreps;
#       close(cmd);
#       RS = "\n";
#       if (length(agreps) > 1) {
#         print "  choose one:" ;
#         na = split(agreps, a, "\n");
#         for (i = 1; i < na; i++) print "  " i ". " a[i];
#         getline answer < "/dev/tty";
#         close("/dev/tty");
#         gsub(/\n/,"",answer);
#         if ((answer > 0) && (answer < na)) {
#           split(a[answer], a2, "|");
#           $2 = a2[1]; $3 = a2[2]; # replace
#         }
#         else found = 1;
#         # and move on
#       }
#       else found = 1;
#     }
#     if (!found) {
#       n = split(gs[$2 "|" $3], x, "|");
#       for (i = 2; i <= n; i++) {
#         split(data[x[i]], d, "|");
#         # do g+s+a match with no ssp?
#         # with fuzzy author
#         if (($2 == d[5]) &&   \
#             ($3 == d[7]) &&   \
#             ($4 == d[8]) &&   \
#             ($5 == d[9]) &&                  \
#             (tolower(gensub(/[(). ]/,"","G",$6)) == \
#              tolower(gensub(/[(). ]/,"","G",d[10])))) {
#           print "  g+s+a: " d[1];
#           print $1 "|" $2 "|" $3 "|" $6 "|tpl_gsa|" d[1] >> "out"; close("out");
#           found =1;
#           break;
#         }
#       }
#       if (!found) {
#         for (i = 2; i <= n; i++) {
#           split(data[x[i]], d, "|");
#           print "    " i-1 ". " d[5] " " d[7] " " d[8] " " d[9] " " \
#             d[10] " ["  substr(d[11],1,1) "]";
#         }
#         getline answer < "/dev/tty";
#         close("/dev/tty");
#         gsub(/\n/,"",answer);
#         type = "tpl_man+";
#         if (answer == "x") {
#           type = "tpl_man-";
#           getline answer < "/dev/tty";
#           close("/dev/tty");
#           gsub(/\n/,"",answer);
#         }
#         if ((answer > 0) && (answer < n)) {
#           # add test **
#           split(data[x[answer+1]], d, "|");
#           print "  choice: " d[1];
#           print $1 "|" $2 "|" $3 "|" $6 "|" type "|" d[1] >> \
#             "out"; close("out");
#           found =1;
#         }
#         else {
#           print "  skipping...";
#           print $1 "|" $2 "|" $3 "|" $6 "|not_found|" >> "out"; close("out");
#         }
#       }
#     }
#     print "";
#   }
# }

#!/bin/gawk -f

BEGIN{
  FS = "|";
  OFS= "|";

  # CONFIG
  PL = "../theplantlist/data/tpl.csv" ;
  # Column order
  PL_code = 1; PL_f = 3   ; PL_xg = 4 ; PL_g = 5  ; PL_xs = 6 ; PL_s = 7;
  PL_st = 8;   PL_ssp = 9 ; PL_a = 10 ; PL_status = 11 ; PL_syn = 12

  IN = "./names.csv" ;
  # Column order
  IN_code = 1; IN_xg = 2 ; IN_g = 3  ; IN_xs = 4 ; IN_s = 5;
  IN_st = 6;   IN_ssp = 7 ; IN_a = 8 ;

  # STEP 0. Read data

  print "Reading ThePlantList..." > "/dev/stderr";
  while ((getline < PL) > 0) {
    PLdata[$PL_code] = $0;
    PLg[$PL_code] = $PL_g ;
    PLglist[$PL_g] = 1;
    PLgsaStr[$PL_code] = $PL_xg " " $PL_g " " $PL_xs " " $PL_s " "  \
      $PL_st " " $PL_ssp " " $PL_a ;
    gsub(/\ \ */," ",PLgsaStr[$PL_code]);
    gsub(/\ *$/,"",PLgsaStr[$PL_code]);
    gsub(/^\ */,"",PLgsaStr[$PL_code]);
    gsakey = $PL_xg $PL_g $PL_xs $PL_s   \
      gensub(/\./,"","G",$PL_st) $PL_ssp        \
      tolower(gensub(/[ .]/,"","G",$PL_a));
    PLgsakey[$PL_code] = gsakey;
    PLcode[gsakey] = $PL_code;
    PLsyn[$PL_code] = $PL_syn;
  }
  print "Done.\n"> "/dev/stderr";

  print "Reading your names list..." > "/dev/stderr";
  while ((getline < IN) > 0) {
    # INdata[++inputorder] = $0;
    INcode[++inputorder] = $IN_code ;
    INg[inputorder] = $IN_g ;
    INgsaStr[inputorder] = $IN_xg " " $IN_g " " $IN_xs " " $IN_s " " \
      $IN_st " " $IN_ssp " " $IN_a ;
    gsub(/\ \ */," ", INgsaStr[inputorder]);
    gsub(/\ *$/,"",INgsaStr[inputorder]);
    gsub(/^\ */,"",INgsaStr[inputorder]);
    INglist[$IN_g] = 1;
    INgsakey[inputorder] = $IN_xg $IN_g $IN_xs $IN_s \
      gensub(/\./,"","G",$IN_st) $IN_ssp \
      tolower(gensub(/[ .]/,"","G",$IN_a));
    # INcode[gsakey] = $IN_code;
  }
  print "  Done.\n" > "/dev/stderr";

  # STEP 1. checking genera

  print "Checking genera..." > "/dev/stderr";
  for (i in INglist) {
    if (!PLglist[i])                                                    \
      print "Genus missing (no further matching):" i > "/dev/stderr";
    INgNotPL[i] = 1;
  }
  print "  Done.\n" > "/dev/stderr";

  # STEP 2. try simple matching
  print "Simple matching..." > "/dev/stderr";
  for (i = 1 ; i <= inputorder ; i++) {
    if (PLcode[INgsakey[i]]) {
      INmatched[i] = 1;
      print INcode[i] , PLdata[PLcode[INgsakey[i]]] > "names.simplematch.csv"
    }
    else {
      # prepare the genus sublists for agrep matching
      makegenus[INg[i]] = 1;
    }
  }
  print "  Done.\n" > "/dev/stderr";

  # STEP 3. make sublists, for agrep
  system("mkdir tmp_genera");
  for (i in PLdata) {
    if (makegenus[PLg[i]]) {  # note: this does not find taxa not in PL!
      print i " " PLgsakey[i]  >> "tmp_genera/" PLg[i] ".csv" ;
      close("tmp_genera/" PLg[i] ".csv");
    }
  }

  # STEP 4. try agrep matching on species name
  for (i = 1 ; i <= inputorder ; i++) {
    if (!INmatched[i]) {
      cmd = "agrep -k -2 '" INgsakey[i] "' tmp_genera/" INg[i] ".csv";
      agreps = "";
      RS = "\x04";
      cmd | getline agreps;
      close(cmd);
      RS = "\n";
      if (length(agreps) > 1) {
        na = split(agreps, a, "\n");
        for (j = 1; j < na; j++) {
          split(a[j],b," ");
          print INcode[i], INgsaStr[i], PLgsaStr[b[1]], b[1] > "names.manual.csv";
        }

      }
    }
  }

  exit;
}

#   while ((getline < IN) > 0) INglist[$IN_g] = 1;
#   for (i in INglist) {
#     if (!PLglist[i]) print "Genera

#   FS="|";
#   # read in the plant list
#   while ((getline < \
#           "/home/cam/public_html/xabi/tools/theplantlist/data/tpl.csv") > 0) {
#     data[$1] = $0;
#     gs[$5 "|" $7] = gs[$5 "|" $7] "|" $1;
#   }

#   # make agrep list
#   #for (i in gs) print i > "_agreplist" ;
#   #close("_agreplist");

#   # read in lookup list
#   while ((getline < ARGV[1]) > 0) {
#     found = 0;
#     gsub(/NULL/,"",$0);
#     gsub(/\ /,"",$2); # fix spaces
#     gsub(/cf[ .]/,"",$3);
#     gsub(/\ /,"",$3);
#     gsub(/\ /,"",$5);
#     print $2 " " $3 " " $4 " " $5 " " $6;

#     # does the genus and species not match?
#     if (!gs[$2 "|" $3]) {
#       # print "  not found";
#       print "  trying spelling...";
#       cmd = "agrep -k -2 '" $2 "|" $3 "' _agreplist";
#       agreps = "";
#       RS = "\x04";
#       cmd | getline agreps;
#       close(cmd);
#       RS = "\n";
#       if (length(agreps) > 1) {
#         print "  choose one:" ;
#         na = split(agreps, a, "\n");
#         for (i = 1; i < na; i++) print "  " i ". " a[i];
#         getline answer < "/dev/tty";
#         close("/dev/tty");
#         gsub(/\n/,"",answer);
#         if ((answer > 0) && (answer < na)) {
#           split(a[answer], a2, "|");
#           $2 = a2[1]; $3 = a2[2]; # replace
#         }
#         else found = 1;
#         # and move on
#       }
#       else found = 1;
#     }
#     if (!found) {
#       n = split(gs[$2 "|" $3], x, "|");
#       for (i = 2; i <= n; i++) {
#         split(data[x[i]], d, "|");
#         # do g+s+a match with no ssp?
#         # with fuzzy author
#         if (($2 == d[5]) &&   \
#             ($3 == d[7]) &&   \
#             ($4 == d[8]) &&   \
#             ($5 == d[9]) &&                  \
#             (tolower(gensub(/[(). ]/,"","G",$6)) == \
#              tolower(gensub(/[(). ]/,"","G",d[10])))) {
#           print "  g+s+a: " d[1];
#           print $1 "|" $2 "|" $3 "|" $6 "|tpl_gsa|" d[1] >> "out"; close("out");
#           found =1;
#           break;
#         }
#       }
#       if (!found) {
#         for (i = 2; i <= n; i++) {
#           split(data[x[i]], d, "|");
#           print "    " i-1 ". " d[5] " " d[7] " " d[8] " " d[9] " " \
#             d[10] " ["  substr(d[11],1,1) "]";
#         }
#         getline answer < "/dev/tty";
#         close("/dev/tty");
#         gsub(/\n/,"",answer);
#         type = "tpl_man+";
#         if (answer == "x") {
#           type = "tpl_man-";
#           getline answer < "/dev/tty";
#           close("/dev/tty");
#           gsub(/\n/,"",answer);
#         }
#         if ((answer > 0) && (answer < n)) {
#           # add test **
#           split(data[x[answer+1]], d, "|");
#           print "  choice: " d[1];
#           print $1 "|" $2 "|" $3 "|" $6 "|" type "|" d[1] >> \
#             "out"; close("out");
#           found =1;
#         }
#         else {
#           print "  skipping...";
#           print $1 "|" $2 "|" $3 "|" $6 "|not_found|" >> "out"; close("out");
#         }
#       }
#     }
#     print "";
#   }
# }


ahrf.awk: Delete old comments

ahrf.awk: Delete old comments

#!/usr/bin/awk -f

BEGIN { FS = "\n"; RS = "" }

# Common shell symbols to HTML
{
	# Two backslashes for nawk(1) and OpenBSD awk(1)
	gsub(/\&/,"\\&")
	gsub(/</,"\\<")
	gsub(/>/,"\\>")
}

# h1, h2, h3, h4, h5, h6
/^[\t ]*:/ {
	match($0,":+")
	cnt = RLENGTH
	gsub(/^[\t ]*:+[\t ]*|[\t ]*:+[\t ]*$/,"")
	# length($0) would also work
	if (cnt <= 6 && $0 != "") {
		printf("<h%s>%s</h%s>\n", cnt, $0, cnt)
	}
	next
}

# Paragraph
/^[A-Za-z0-9_("]+/ {
	printf("
")
	for (p=1; p<NF; p++) {
		if ($p ~ / +$/) {
			gsub(/ +$/,"",$p)
			printf("%s
\n", $p)
		} else {
			printf("%s\n", $p)
		}
	}
	printf("%s
\n\n", $p)
	next
}

# Code
/^====+/ {
	if (NF > 2 && $NF ~ /====+/) {
		gsub(/^[\t ]*====+[\t ]*\n|\n[\t ]*====+[\t ]*$/,"")
		printf("
")
		for (c=1; c<NF; c++) {
			gsub(/^ +$/,"",$c)
			printf("%s\n", $c)
		}
		printf("%s
\n", $NF)
	}
	next
}

# List
/^[\t ]*\* +/ {
	printf("
\n")
	for (l=1; l<=NF; l++) {
		gsub(/^[\t ]*/,"",$l)
		if ($l ~ /\* +/) {
			match($l,"\\* +")
			str = substr($l,RSTART+RLENGTH)
			printf("\t
%s
\n", str)
		}
	}
	printf("
\n")
	next
}

# End links
/^[\t ]*\[[01]/ {
	printf("
\n")
	for (u=1; u<=NF; u++) {
		gsub(/^[\t ]*/,"",$u)
		if (match($u,"\\[[0-9]+\\]")) {
			# RSTART can be replaced by 1, because we removed useless tabs/spaces
			num = substr($u,RSTART,RLENGTH)
			url = substr($u,RSTART+RLENGTH+1)
			if (length(url) >= 60) {
				printf("\t
%s %.60s...
\n", num, url, url)
			} else {
				printf("\t
%s %s
\n", num, url, url)
			}
		}
	}
	printf("
\n")
	next
}

#!/usr/bin/awk -f

BEGIN { FS = "\n"; RS = "" }

# Common shell symbols to HTML
{
	# Two backslashes for nawk(1) and OpenBSD awk(1)
	gsub(/\&/,"\\&")
	gsub(/</,"\\<")
	gsub(/>/,"\\>")
}

# h1, h2, h3, h4, h5, h6
/^[\t ]*:/ {
	match($0,":+")
	cnt = RLENGTH
	gsub(/^[\t ]*:+[\t ]*|[\t ]*:+[\t ]*$/,"")
	# length($0) would also work
	if (cnt <= 6 && $0 != "") {
		printf("<h%s>%s</h%s>\n", cnt, $0, cnt)
	}
	next
}

# Paragraph
/^[A-Za-z0-9_("]+/ {
	printf("
")
	for (p=1; p<NF; p++) {
		if ($p ~ / +$/) {
			gsub(/ +$/,"",$p)
			printf("%s
\n", $p)
		} else {
			printf("%s\n", $p)
		}
	}
	printf("%s
\n\n", $p)
	next
}

# Code
/^====+/ {
	if (NF > 2 && $NF ~ /====+/) {
		gsub(/^[\t ]*====+[\t ]*\n|\n[\t ]*====+[\t ]*$/,"")
		printf("
")
		for (c=1; c<NF; c++) {
			gsub(/^ +$/,"",$c)
			printf("%s\n", $c)
		}
		# Solve "space" bug! Less crado (gsub).
		#gsub(/^ +/,"",$NF)
		printf("%s
\n", $NF)
	}
	next
}

# List
/^[\t ]*\* +/ {
	printf("
\n")
	for (l=1; l<=NF; l++) {
		gsub(/^[\t ]*/,"",$l)
		if ($l ~ /\* +/) {
			match($l,"\\* +")
			str = substr($l,RSTART+RLENGTH)
			printf("\t
%s
\n", str)
		}
	}
	printf("
\n")
	next
}

# End links
/^[\t ]*\[[01]/ {
	printf("
\n")
	for (u=1; u<=NF; u++) {
		gsub(/^[\t ]*/,"",$u)
		if (match($u,"\\[[0-9]+\\]")) {
			# RSTART can be replaced by 1, because we removed useless tabs/spaces
			num = substr($u,RSTART,RLENGTH)
			url = substr($u,RSTART+RLENGTH+1)
			if (length(url) >= 60) {
				printf("\t
%s %.60s...
\n", num, url, url)
			} else {
				printf("\t
%s %s
\n", num, url, url)
			}
		}
	}
	printf("
\n")
	next
}


Prevent that comments are changed

Prevent that comments are changed

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

BEGIN {
  session_count = 0;
  FS="|"
  OFS="|"
}

{
  if ($3 ~ "[0-9]+") {
    # See if the current line is already in the table
    frame_file = destDir "/frames/Frame"$3".html"
    session_line = ""
    "grep -i \"" session_token "\" " frame_file | getline session_line

    if (session_line == "" ) {
      $6 = "{0}"
      print $0

    } else {
      found = 0;
      split(session_line, array, " ")
      session = array[2]
      for (i=0; i < session_count; i++) {
        if (sessions[i] == session) {
          found = 1
          $6 = "{" i+1 "}"
          print $0
          break
        }
      }

      if (found == 0) {
        $6 = "{" session_count+1 "}"
        sessions[session_count++] = session
        print $0
        s = sprintf("echo '%2d: new session in frame %4s: %s' >&2", session_count, $3, session)
        system(s)
      }
    }

  } else {
    # Comment line, line starting with "#".
    # Requires no processing, just print it
    print $0
  }
}

BEGIN {
  session_count = 0;
  FS="|"
  OFS="|"
}

{
  if ($1 ~ "[0-9]+") {
    # See if the current line is already in the table
    frame_file = destDir "/frames/Frame"$3".html"
    session_line = ""
    "grep -i \"" session_token "\" " frame_file | getline session_line

    if (session_line == "" ) {
      $6 = "{0}"
      print $0

    } else {
      found = 0;
      split(session_line, array, " ")
      session = array[2]
      for (i=0; i < session_count; i++) {
        if (sessions[i] == session) {
          found = 1
          $6 = "{" i+1 "}"
          print $0
          break
        }
      }

      if (found == 0) {
        $6 = "{" session_count+1 "}"
        sessions[session_count++] = session
        print $0
        s = sprintf("echo '%2d: new session in frame %4s: %s' >&2", session_count, $3, session)
        system(s)
      }
    }

  } else {
    # Comment line, line starting with "#".
    # Requires no processing, just print it
    print $0
  }
}


Now toloka.awk can process multiple inputs

#!/usr/bin/awk -f
BEGIN {
    FS = OFS = "\t";
    print "INPUT:hyponym", "INPUT:hypernym", "INPUT:genitive", "GOLDEN:judgement", "HINT:text";
}
FNR == 1 {
    for (i=1; i<=NF; i++) ix[$i] = i;
    next;
}
{
    print $ix["hyponym"], $ix["hypernym"], $ix["genitive"], "", "" | "sort -t \"\t\" -k1,1 -k2,2 -k3,3 -u";
}

#!/usr/bin/awk -f
BEGIN {
    FS = OFS = "\t";
    print "INPUT:hyponym", "INPUT:hypernym", "INPUT:genitive", "GOLDEN:judgement", "HINT:text";
}
NR == 1 {
    for (i=1; i<=NF; i++) ix[$i] = i;
    next;
}
$ix["found"] {
    print $ix["hyponym"], $ix["hypernym"], $ix["genitive"], "", "" | "sort -t \"\t\" -k1,1 -k2,2 -k3,3 -u";
}


build.awk: export TRANS_DIR when rebuilding EntryScript

#!/usr/bin/gawk -f

# Not all 4.x versions of gawk can handle @include without ".awk" extension
# But the build.awk script and the single build should support gawk 4.0+.
@include "include/Commons.awk"
@include "include/Utils.awk"
@include "include/Languages.awk"
@include "metainfo.awk"

function init() {
    BuildPath            = "build/"
    Trans                = BuildPath Command
    TransAwk             = Trans ".awk"

    ManPath              = "man/"
    Man                  = ManPath Command ".1"
    ManTemplate          = Man ".template.md"
    ManMarkdown          = Man ".md"
    ManHtmlTemplate      = Man ".template.html"
    ManHtml              = Man ".html"

    PagesPath            = "gh-pages/"
    BadgeDownload        = PagesPath "images/badge-download"
    BadgeRelease         = PagesPath "images/badge-release"
    Index                = PagesPath "index.md"

    ReadmePath           = "./"
    ReadmeTemplate       = ReadmePath "README.template.md"
    Readme               = ReadmePath "README.md"

    WikiPath             = "wiki/"
    WikiHome             = WikiPath "Home.md"
    WikiLanguages        = WikiPath "Languages.md"
    WikiLanguagesHtml    = WikiLanguages ".html"

    RegistryPath         = "registry/"
    MainRegistryTemplate = RegistryPath "index.template.trans"
    MainRegistry         = RegistryPath "index.trans"
}

function man(    text) {
    text = readFrom(ManTemplate)
    gsub(/\$Version\$/, Version, text)
    gsub(/\$ReleaseDate\$/, ReleaseDate, text)
    writeTo(text, ManMarkdown)

    if (fileExists(ManHtmlTemplate))
        system("pandoc -s -t html --toc --toc-depth 1 --template " ManHtmlTemplate " " ManMarkdown " -o " ManHtml)
    return system("pandoc -s -t man " ManMarkdown " -o " Man)
}

function readme(    code, col, cols, content, group, i, j, num, language, r, rows, text) {
    text = readFrom(ReadmeTemplate)

    content = getOutput("gawk -f translate.awk -- -no-ansi -h")
    gsub(/\$usage\$/, content, text)

    initBiDi(); initLocale()
    # number of language codes with stable support
    num = 0
    for (code in Locale)
        if (Locale[code]["support"] != "unstable")
            num++
    rows = int(num / 3) + (num % 3 ? 1 : 0)
    cols[0][0] = cols[1][0] = cols[2][0] = NULLSTR
    i = 0
    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "compName"
    for (code in Locale) {
        # Ignore unstable languages
        if (Locale[code]["support"] == "unstable") continue

        col = int(i / rows)
        append(cols[col], code)
        i++
    }
    PROCINFO["sorted_in"] = saveSortedIn
    r = "| Language | Code | Language | Code | Language | Code |" RS \
        "| :------: | :--: | :------: | :--: | :------: | :--: |" RS
    for (i = 0; i < rows; i++) {
        r = r "| "
        for (j = 0; j < 3; j++)
            if (cols[j][i]) {
                split(getName(cols[j][i]), group, " ")
                language = length(group) == 1 ? group[1] "_language" : join(group, "_")
                r = r "**[" getName(cols[j][i]) "](" "http://en.wikipedia.org/wiki/" language ")**
 **" getEndonym(cols[j][i]) "** | **`" cols[j][i] "`** | "
            }
        r = r RS
    }
    gsub(/\$code-list\$/, r, text)

    content = readFrom(WikiHome)
    gsub(/\$wiki-home\$/, content, text)

    writeTo(text, Readme)
    return 0
}

function wiki(    code, group, iso, language, saveSortedIn) {
    initBiDi(); initLocale()

    #print "***" length(Locale) "*** *languages in total. "
    print "*Generated from the source code of Translate Shell " Version ".*\n" > WikiLanguages
    print "*Version: [English](https://github.com/soimort/translate-shell/wiki/Languages) " \
        "| [Chinese Simplified](https://github.com/soimort/translate-shell/wiki/Languages-%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%29)*\n" > WikiLanguages
    print "| Code | Name | Family | [Writing system](https://github.com/soimort/translate-shell/wiki/Writing-Systems-and-Fonts) | Is [RTL](http://en.wikipedia.org/wiki/Right-to-left)? | Has dictionary? |" > WikiLanguages
    print "| :--: | ---: | -----: | :------------: | :---------------------------------------------------: | :-------------: |" > WikiLanguages
    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (code in Locale) {
        # Ignore unstable languages
        if (Locale[code]["support"] == "unstable") continue

        split(getISO(code), group, "-")
        iso = group[1]
        split(getName(code), group, " ")
        language = length(group) == 1 ? group[1] "_language" :
            group[2] ~ /^\(.*\)$/ ? group[1] "_language" : join(group, "_")
        print sprintf("| **`%s`**
 [`%s`](%s) | **[%s](%s)**
 **%s** | %s | `%s` | %s | %s |",
                      getCode(code), iso, "http://www.ethnologue.com/language/" iso,
                      getName(code), "http://en.wikipedia.org/wiki/" language, getEndonym(code),
                      getFamily(code), getScript(code),
                      isRTL(code) ? "✓" : NULLSTR,
                      hasDictionary(code) ? "✓" : NULLSTR) > WikiLanguages
    }
    PROCINFO["sorted_in"] = saveSortedIn

    return system("pandoc -s -t html " WikiLanguages " -o " WikiLanguagesHtml)
}

function doc() {
    man()
    readme()
    wiki()
    return 0
}

function readSqueezed(fileName, squeezed,    group, line, ret) {
    if (fileName ~ /\*$/) # glob simulation
        return readSqueezed(fileName ".awk", squeezed)

    ret = NULLSTR
    if (fileExists(fileName))
        while (getline line < fileName) {
            match(line, /^[[:space:]]*@include[[:space:]]*"(.*)"$/, group)
            if (RSTART) { # @include
                if (group[1] ~ /\.awk$/)
                    append(Includes, group[1])

                if (ret) ret = ret RS
                ret = ret readSqueezed(group[1], squeezed)
            } else if (!squeezed || line = squeeze(line)) { # effective LOC
                if (ret) ret = ret RS
                ret = ret line
            }
        }
    return ret
}

function build(target, type,    i, group, inline, line, temp) {
    # Default target: bash
    if (!target) target = "bash"

    ("mkdir -p " parameterize(BuildPath)) | getline

    if (target == "bash" || target == "zsh") {

        print "#!/usr/bin/env " target > Trans

        if (fileExists("DISCLAIMER")) {
            print "#" > Trans
            while (getline line < "DISCLAIMER")
                print "# " line > Trans
            print "#" > Trans
        }

        print "export TRANS_ENTRY=\"$0\"" > Trans
        print "if [[ ! $LANG =~ (UTF|utf)-?8$ ]]; then export LANG=en_US.UTF-8; fi" > Trans

        print "read -r -d '' TRANS_PROGRAM << 'EOF'" > Trans
        print readSqueezed(EntryPoint, TRUE) > Trans
        print "EOF" > Trans

        print "read -r -d '' TRANS_MANPAGE << 'EOF'" > Trans
        if (fileExists(Man))
            while (getline line < Man)
                print line > Trans
        print "EOF" > Trans
        print "export TRANS_MANPAGE" > Trans

        if (type == "release")
            print "export TRANS_BUILD=release" temp > Trans
        else {
            temp = getGitHead()
            if (temp)
                print "export TRANS_BUILD=git:" temp > Trans
        }

        print "gawk -f <(echo -E \"$TRANS_PROGRAM\") - \"$@\"" > Trans

        ("chmod +x " parameterize(Trans)) | getline

        # Rebuild EntryScript
        print "#!/bin/sh" > EntryScript
        print "export TRANS_DIR=`dirname $0`" > EntryScript
        print "gawk \\" > EntryScript
        for (i = 0; i < length(Includes) - 1; i++)
            print "-i \"${TRANS_DIR}/" Includes[i] "\" \\" > EntryScript
        print "-f \"${TRANS_DIR}/" Includes[i] "\" -- \"$@\"" > EntryScript
        ("chmod +x " parameterize(EntryScript)) | getline
        return 0

    } else if (target == "awk" || target == "gawk") {

        "uname -s" | getline temp
        print (temp == "Darwin" ?
               "#!/usr/bin/env gawk -f" : # macOS
               "#!/usr/bin/gawk -f") > TransAwk

        print readSqueezed(EntryPoint, TRUE) > TransAwk

        ("chmod +x " parameterize(TransAwk)) | getline
        return 0

    } else {

        w("[FAILED] Unknown target: " ansi("underline", target))
        w("         Supported targets: "                                \
          ansi("underline", "bash") ", "                                \
          ansi("underline", "zsh") ", "                                 \
          ansi("underline", "gawk"))
        return 1

    }
}

function clean() {
    ("rm -f " BuildPath Command "*") | getline
    return 0
}

function release(    content, group, sha1, size, temp, text) {
    d("Updating registry ...")
    # Update registry
    text = readFrom(MainRegistryTemplate)
    gsub(/\$Version\$/, Version, text)
    writeTo(text, MainRegistry)

    d("Updating gh-pages/images ...")
    # Update gh-pages/images/badge-release
    text = readFrom(BadgeRelease ".temp")
    gsub(/\$Version\$/, Version, text)
    writeTo(text, BadgeRelease)
    system("save-to-png " BadgeRelease)
    # Update gh-pages/images/badge-download
    ("wc -c " Trans) | getline temp
    split(temp, group)
    size = int(group[1] / 1000)
    text = readFrom(BadgeDownload ".temp")
    gsub(/\$Size\$/, size, text)
    writeTo(text, BadgeDownload)
    system("save-to-png " BadgeDownload)

    d("Updating gh-pages/index.md ...")
    # Update gh-pages/index.md
    ("sha1sum " Trans) | getline temp
    split(temp, group)
    sha1 = group[1]
    content = readFrom(Readme)
    text = readFrom(Index ".temp")
    gsub(/\$sha1\$/, sha1, text)
    gsub(/\$Version\$/, Version, text)
    gsub(/\$readme\$/, content, text)
    writeTo(text, Index)

    return 0
}

function test() {
    return 0
}

BEGIN {
    init()

    pos = 0
    while (ARGV[++pos]) {
        # -target TARGET
        match(ARGV[pos], /^--?target(=(.*)?)?$/, group)
        if (RSTART) {
            target = tolower(group[2] ? group[2] : ARGV[++pos])
            continue
        }

        # -type TYPE
        match(ARGV[pos], /^--?type(=(.*)?)?$/, group)
        if (RSTART) {
            type = tolower(group[2] ? group[2] : ARGV[++pos])
            continue
        }

        # TASK
        match(ARGV[pos], /^[^\-]/, group)
        if (RSTART) {
            append(tasks, ARGV[pos])
            continue
        }
    }

    # Default task: build
    if (!anything(tasks)) tasks[0] = "build"

    for (i = 0; i < length(tasks); i++) {
        task = tasks[i]
        status = 0
        switch (task) {

        case "man":
            status = man()
            break

        case "readme":
            status = readme()
            break

        case "wiki":
            status = wiki()
            break

        case "doc":
            status = doc()
            break

        case "build":
            status = build(target, type)
            break

        case "clean":
            status = clean()
            break

        case "release":
            status = release()
            break

        case "test":
            status = test()
            break

        default: # unknown task
            status = -1
        }

        if (status == 0) {
            d("[OK] Task " ansi("bold", task) " completed.")
        } else if (status < 0) {
            w("[FAILED] Unknown task: " ansi("bold", task))
            exit 1
        } else {
            w("[FAILED] Task " ansi("bold", task) " failed.")
            exit 1
        }
    }
}

#!/usr/bin/gawk -f

# Not all 4.x versions of gawk can handle @include without ".awk" extension
# But the build.awk script and the single build should support gawk 4.0+.
@include "include/Commons.awk"
@include "include/Utils.awk"
@include "include/Languages.awk"
@include "metainfo.awk"

function init() {
    BuildPath            = "build/"
    Trans                = BuildPath Command
    TransAwk             = Trans ".awk"

    ManPath              = "man/"
    Man                  = ManPath Command ".1"
    ManTemplate          = Man ".template.md"
    ManMarkdown          = Man ".md"
    ManHtmlTemplate      = Man ".template.html"
    ManHtml              = Man ".html"

    PagesPath            = "gh-pages/"
    BadgeDownload        = PagesPath "images/badge-download"
    BadgeRelease         = PagesPath "images/badge-release"
    Index                = PagesPath "index.md"

    ReadmePath           = "./"
    ReadmeTemplate       = ReadmePath "README.template.md"
    Readme               = ReadmePath "README.md"

    WikiPath             = "wiki/"
    WikiHome             = WikiPath "Home.md"
    WikiLanguages        = WikiPath "Languages.md"
    WikiLanguagesHtml    = WikiLanguages ".html"

    RegistryPath         = "registry/"
    MainRegistryTemplate = RegistryPath "index.template.trans"
    MainRegistry         = RegistryPath "index.trans"
}

function man(    text) {
    text = readFrom(ManTemplate)
    gsub(/\$Version\$/, Version, text)
    gsub(/\$ReleaseDate\$/, ReleaseDate, text)
    writeTo(text, ManMarkdown)

    if (fileExists(ManHtmlTemplate))
        system("pandoc -s -t html --toc --toc-depth 1 --template " ManHtmlTemplate " " ManMarkdown " -o " ManHtml)
    return system("pandoc -s -t man " ManMarkdown " -o " Man)
}

function readme(    code, col, cols, content, group, i, j, num, language, r, rows, text) {
    text = readFrom(ReadmeTemplate)

    content = getOutput("gawk -f translate.awk -- -no-ansi -h")
    gsub(/\$usage\$/, content, text)

    initBiDi(); initLocale()
    # number of language codes with stable support
    num = 0
    for (code in Locale)
        if (Locale[code]["support"] != "unstable")
            num++
    rows = int(num / 3) + (num % 3 ? 1 : 0)
    cols[0][0] = cols[1][0] = cols[2][0] = NULLSTR
    i = 0
    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "compName"
    for (code in Locale) {
        # Ignore unstable languages
        if (Locale[code]["support"] == "unstable") continue

        col = int(i / rows)
        append(cols[col], code)
        i++
    }
    PROCINFO["sorted_in"] = saveSortedIn
    r = "| Language | Code | Language | Code | Language | Code |" RS \
        "| :------: | :--: | :------: | :--: | :------: | :--: |" RS
    for (i = 0; i < rows; i++) {
        r = r "| "
        for (j = 0; j < 3; j++)
            if (cols[j][i]) {
                split(getName(cols[j][i]), group, " ")
                language = length(group) == 1 ? group[1] "_language" : join(group, "_")
                r = r "**[" getName(cols[j][i]) "](" "http://en.wikipedia.org/wiki/" language ")**
 **" getEndonym(cols[j][i]) "** | **`" cols[j][i] "`** | "
            }
        r = r RS
    }
    gsub(/\$code-list\$/, r, text)

    content = readFrom(WikiHome)
    gsub(/\$wiki-home\$/, content, text)

    writeTo(text, Readme)
    return 0
}

function wiki(    code, group, iso, language, saveSortedIn) {
    initBiDi(); initLocale()

    #print "***" length(Locale) "*** *languages in total. "
    print "*Generated from the source code of Translate Shell " Version ".*\n" > WikiLanguages
    print "*Version: [English](https://github.com/soimort/translate-shell/wiki/Languages) " \
        "| [Chinese Simplified](https://github.com/soimort/translate-shell/wiki/Languages-%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%29)*\n" > WikiLanguages
    print "| Code | Name | Family | [Writing system](https://github.com/soimort/translate-shell/wiki/Writing-Systems-and-Fonts) | Is [RTL](http://en.wikipedia.org/wiki/Right-to-left)? | Has dictionary? |" > WikiLanguages
    print "| :--: | ---: | -----: | :------------: | :---------------------------------------------------: | :-------------: |" > WikiLanguages
    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (code in Locale) {
        # Ignore unstable languages
        if (Locale[code]["support"] == "unstable") continue

        split(getISO(code), group, "-")
        iso = group[1]
        split(getName(code), group, " ")
        language = length(group) == 1 ? group[1] "_language" :
            group[2] ~ /^\(.*\)$/ ? group[1] "_language" : join(group, "_")
        print sprintf("| **`%s`**
 [`%s`](%s) | **[%s](%s)**
 **%s** | %s | `%s` | %s | %s |",
                      getCode(code), iso, "http://www.ethnologue.com/language/" iso,
                      getName(code), "http://en.wikipedia.org/wiki/" language, getEndonym(code),
                      getFamily(code), getScript(code),
                      isRTL(code) ? "✓" : NULLSTR,
                      hasDictionary(code) ? "✓" : NULLSTR) > WikiLanguages
    }
    PROCINFO["sorted_in"] = saveSortedIn

    return system("pandoc -s -t html " WikiLanguages " -o " WikiLanguagesHtml)
}

function doc() {
    man()
    readme()
    wiki()
    return 0
}

function readSqueezed(fileName, squeezed,    group, line, ret) {
    if (fileName ~ /\*$/) # glob simulation
        return readSqueezed(fileName ".awk", squeezed)

    ret = NULLSTR
    if (fileExists(fileName))
        while (getline line < fileName) {
            match(line, /^[[:space:]]*@include[[:space:]]*"(.*)"$/, group)
            if (RSTART) { # @include
                if (group[1] ~ /\.awk$/)
                    append(Includes, group[1])

                if (ret) ret = ret RS
                ret = ret readSqueezed(group[1], squeezed)
            } else if (!squeezed || line = squeeze(line)) { # effective LOC
                if (ret) ret = ret RS
                ret = ret line
            }
        }
    return ret
}

function build(target, type,    i, group, inline, line, temp) {
    # Default target: bash
    if (!target) target = "bash"

    ("mkdir -p " parameterize(BuildPath)) | getline

    if (target == "bash" || target == "zsh") {

        print "#!/usr/bin/env " target > Trans

        if (fileExists("DISCLAIMER")) {
            print "#" > Trans
            while (getline line < "DISCLAIMER")
                print "# " line > Trans
            print "#" > Trans
        }

        print "export TRANS_ENTRY=\"$0\"" > Trans
        print "if [[ ! $LANG =~ (UTF|utf)-?8$ ]]; then export LANG=en_US.UTF-8; fi" > Trans

        print "read -r -d '' TRANS_PROGRAM << 'EOF'" > Trans
        print readSqueezed(EntryPoint, TRUE) > Trans
        print "EOF" > Trans

        print "read -r -d '' TRANS_MANPAGE << 'EOF'" > Trans
        if (fileExists(Man))
            while (getline line < Man)
                print line > Trans
        print "EOF" > Trans
        print "export TRANS_MANPAGE" > Trans

        if (type == "release")
            print "export TRANS_BUILD=release" temp > Trans
        else {
            temp = getGitHead()
            if (temp)
                print "export TRANS_BUILD=git:" temp > Trans
        }

        print "gawk -f <(echo -E \"$TRANS_PROGRAM\") - \"$@\"" > Trans

        ("chmod +x " parameterize(Trans)) | getline

        # Rebuild EntryScript
        print "#!/bin/sh" > EntryScript
        print "TRANS_DIR=`dirname $0`" > EntryScript
        print "gawk \\" > EntryScript
        for (i = 0; i < length(Includes) - 1; i++)
            print "-i \"${TRANS_DIR}/" Includes[i] "\" \\" > EntryScript
        print "-f \"${TRANS_DIR}/" Includes[i] "\" -- \"$@\"" > EntryScript
        ("chmod +x " parameterize(EntryScript)) | getline
        return 0

    } else if (target == "awk" || target == "gawk") {

        "uname -s" | getline temp
        print (temp == "Darwin" ?
               "#!/usr/bin/env gawk -f" : # macOS
               "#!/usr/bin/gawk -f") > TransAwk

        print readSqueezed(EntryPoint, TRUE) > TransAwk

        ("chmod +x " parameterize(TransAwk)) | getline
        return 0

    } else {

        w("[FAILED] Unknown target: " ansi("underline", target))
        w("         Supported targets: "                                \
          ansi("underline", "bash") ", "                                \
          ansi("underline", "zsh") ", "                                 \
          ansi("underline", "gawk"))
        return 1

    }
}

function clean() {
    ("rm -f " BuildPath Command "*") | getline
    return 0
}

function release(    content, group, sha1, size, temp, text) {
    d("Updating registry ...")
    # Update registry
    text = readFrom(MainRegistryTemplate)
    gsub(/\$Version\$/, Version, text)
    writeTo(text, MainRegistry)

    d("Updating gh-pages/images ...")
    # Update gh-pages/images/badge-release
    text = readFrom(BadgeRelease ".temp")
    gsub(/\$Version\$/, Version, text)
    writeTo(text, BadgeRelease)
    system("save-to-png " BadgeRelease)
    # Update gh-pages/images/badge-download
    ("wc -c " Trans) | getline temp
    split(temp, group)
    size = int(group[1] / 1000)
    text = readFrom(BadgeDownload ".temp")
    gsub(/\$Size\$/, size, text)
    writeTo(text, BadgeDownload)
    system("save-to-png " BadgeDownload)

    d("Updating gh-pages/index.md ...")
    # Update gh-pages/index.md
    ("sha1sum " Trans) | getline temp
    split(temp, group)
    sha1 = group[1]
    content = readFrom(Readme)
    text = readFrom(Index ".temp")
    gsub(/\$sha1\$/, sha1, text)
    gsub(/\$Version\$/, Version, text)
    gsub(/\$readme\$/, content, text)
    writeTo(text, Index)

    return 0
}

function test() {
    return 0
}

BEGIN {
    init()

    pos = 0
    while (ARGV[++pos]) {
        # -target TARGET
        match(ARGV[pos], /^--?target(=(.*)?)?$/, group)
        if (RSTART) {
            target = tolower(group[2] ? group[2] : ARGV[++pos])
            continue
        }

        # -type TYPE
        match(ARGV[pos], /^--?type(=(.*)?)?$/, group)
        if (RSTART) {
            type = tolower(group[2] ? group[2] : ARGV[++pos])
            continue
        }

        # TASK
        match(ARGV[pos], /^[^\-]/, group)
        if (RSTART) {
            append(tasks, ARGV[pos])
            continue
        }
    }

    # Default task: build
    if (!anything(tasks)) tasks[0] = "build"

    for (i = 0; i < length(tasks); i++) {
        task = tasks[i]
        status = 0
        switch (task) {

        case "man":
            status = man()
            break

        case "readme":
            status = readme()
            break

        case "wiki":
            status = wiki()
            break

        case "doc":
            status = doc()
            break

        case "build":
            status = build(target, type)
            break

        case "clean":
            status = clean()
            break

        case "release":
            status = release()
            break

        case "test":
            status = test()
            break

        default: # unknown task
            status = -1
        }

        if (status == 0) {
            d("[OK] Task " ansi("bold", task) " completed.")
        } else if (status < 0) {
            w("[FAILED] Unknown task: " ansi("bold", task))
            exit 1
        } else {
            w("[FAILED] Task " ansi("bold", task) " failed.")
            exit 1
        }
    }
}


2.13.awk