Using Extensions

Jawk extensions let Java code expose additional AWK-callable functions to a script. By default, Jawk enables the built-in GNU Awk compatibility extension, so gawk functions such as asort() and typeof() work out of the box. Every other extension is opt-in: the host application or CLI invocation decides exactly which extension instances are available.

Important

Apart from the default gawk compatibility extension, extensions are opt-in. Sandbox mode blocks dynamic extension loading during script execution, but preloading an extension through the CLI or the Java host remains an explicit host decision.

How Extensions Are Enabled

There are two supported loading paths:

  • CLI: -l <extension> or --load <extension>
  • Java API: pass extension instances to an Awk constructor

If you do neither, the default extension set applies: the gawk compatibility extension and nothing else. Specifying an explicit extension list — through -l on the CLI or an Awk constructor — replaces the default set, so add GawkExtension to the list when the script still needs the gawk functions.

List Available Extensions

From the CLI, print the currently registered extension identifiers:

$ java -jar jawk-7.0.01-standalone.jar --list-ext

From Java, inspect the registry directly:

Awk.listAvailableExtensions().forEach((name, extension) ->
        System.out.println(name + " -> " + extension.getClass().getName()));

The registry may expose multiple identifiers for the same implementation, for example a registered name, a simple class name, and a fully qualified class name.

Load Extensions from the CLI

Load an extension with any supported identifier:

$ java -jar jawk-7.0.01-standalone.jar -l stdin -f script.awk
$ java -jar jawk-7.0.01-standalone.jar -l io.jawk.ext.StdinExtension -f script.awk

If the extension class is not already registered, the CLI can still resolve it by fully qualified class name as long as the class is available on the JVM classpath.

Load Extensions from Java

Pass extension instances directly to Awk:

Awk awk = new Awk(StdinExtension.INSTANCE, new MyExtension());

That keeps extension availability explicit and local to the embedding code.

Built-In Extensions

GNU Awk Compatibility (Enabled by Default)

GawkExtension implements gawk-specific builtins and belongs to the default extension set, so its functions are available whenever no explicit extension list is supplied:

  • asort(source [, dest [, how]]) sorts an array by value and renumbers the result with integer indices starting at 1
  • asorti(source [, dest [, how]]) sorts an array by index instead of by value
  • typeof(x) returns the gawk type category of a value: "number", "string", "strnum", "array", "regexp", "number|bool", "unassigned", or "untyped"
  • isarray(x) returns 1 when the value is an array, 0 otherwise
  • mkbool(expression) creates a gawk-style boolean-typed number
  • gensub(regexp, replacement, how [, target]) returns the substituted text without modifying the target
  • patsplit(string, array [, fieldpat [, seps]]) splits by content: pieces matching fieldpat (default: the FPAT variable, or any non-whitespace run) become fields, and the text between them lands in seps[0]..seps[n]. Note that Java regular expressions pick the first matching alternative rather than the POSIX longest one, so order alternatives longest-first
  • strtonum(str) converts a string to a number, recognizing gawk's 0x hexadecimal and leading-zero octal notation
  • systime() returns the current time in seconds since the epoch
  • mktime(datespec [, utc-flag]) converts a "YYYY MM DD HH MM SS [DST]" specification into seconds since the epoch, normalizing out-of-range values, or returns -1 when the specification is invalid
  • strftime([format [, timestamp [, utc-flag]]]) formats a timestamp with the C strftime(3) conversion specifiers (C-locale English names), including the GNU padding, case, and field-width flags (%-d, %_d, %^a, %5d); the format defaults to PROCINFO["strftime"] or gawk's "%a %b %e %H:%M:%S %Z %Y"

mktime() and strftime() honor ENVIRON["TZ"] and follow the Java platform's time zone data and calendar rules; see the differences with traditional AWK[1] for the edge cases where this departs from gawk's C-library behavior.

  • bindtextdomain(directory [, domain]), dcgettext(string [, domain [, category]]), and dcngettext(string1, string2, number [, domain [, category]]) implement gawk's internationalization interface; since Jawk ships no message catalogs, they behave exactly like gawk without a matching .mo file: text is returned untranslated and dcngettext() applies the English plural rule

asort(), asorti(), and the for (index in array) statement honor PROCINFO["sorted_in"] with gawk's predefined comparison modes: @unsorted, @ind_str_asc, @ind_num_asc, @val_str_asc, @val_num_asc, @val_type_asc, and their _desc counterparts. String comparisons ignore case when IGNORECASE is non-zero.

Beyond the extension functions, the interpreter itself implements gawk's BEGINFILE / ENDFILE special patterns, the nextfile statement, and the ERRNO and ARGIND special variables (see the CLI guide[2]). Like the other gawk-specific syntax, BEGINFILE and ENDFILE are not special in POSIX mode.

Jawk also supports gawk's source-level @ syntax:

@include "library.awk"
@namespace "report"

function render(value) { return value }

BEGIN {
    callback = "report::render"
    print @callback(42)
}

@include resolves relative paths from the including source, then searches AWKPATH, and includes each resolved file at most once. An included file cannot include a top-level program source. An included source begins in the awk namespace; the including source's namespace is restored afterward. @namespace qualifies variables and functions except identifiers made entirely of uppercase letters, while awk::name refers to the default namespace. Namespaced indirect calls require a fully qualified function name in the selector variable; an unqualified value refers to the default awk namespace. Indirect calls can dispatch user-defined, built-in, or loaded extension functions. Typed regexp literals use the related @/re/ form. @load is recognized but intentionally reported as unsupported; load Java extensions with the CLI -l option or the Java API instead.

All gawk @ forms are rejected when POSIX mode is enabled.

Scripts that reference SYMTAB or FUNCTAB get honest, Jawk-shaped content, populated by the runtime itself (outside POSIX mode): SYMTAB holds the names of the program's globals, Jawk's special variables, and -v/host-supplied variables; FUNCTAB holds the names of the standard built-in functions (split, substr, …), the program's user-defined functions, and the loaded extensions' function keywords. Reads and writes through SYMTAB reflect declared globals and managed special variables live, but arbitrary elements cannot be added or deleted and writes must preserve each global's scalar or array type. FUNCTAB is read-only. As in gawk, assigning a scalar to SYMTAB or FUNCTAB is a runtime error.

Note

Because these functions are registered by default, gensub, typeof, isarray, asort, asorti, mkbool, patsplit, strtonum, systime, mktime, strftime, bindtextdomain, dcgettext, and dcngettext become reserved function names. A script that uses them as variable or function identifiers must be run with an explicit extension list that omits GawkExtension.

The registry exposes the extension through identifiers such as:

  • GawkExtension
  • io.jawk.ext.GawkExtension
  • GNU Awk Compatibility

Stdin Support

The built-in registry also includes the stdin extension, which is exposed through identifiers such as:

  • stdin
  • StdinExtension
  • io.jawk.ext.StdinExtension

That extension provides advanced helper functions including StdinHasInput(), StdinGetline(), and StdinBlock().

Sandbox Interaction

Sandboxing and extensions are separate concerns:

  • sandboxing restricts dangerous AWK runtime features
  • extension loading is still an explicit host choice
  • scripts do not get to expand their own capabilities automatically

If you need a sandboxed Java embedding, construct SandboxedAwk with the extension instances you want to allow. If you need a sandboxed CLI run, combine -S with the -l options you want to preload.

See Also

extensions plugins functions loading awk
Links:
  • [1] index.html#Differences_with_Traditional_AWK
  • [2] cli.html#BEGINFILE_and_ENDFILE_Rules
  • [3] extensions-writing.html
  • [4] java.html
  • [5] cli.html
Searching...
No results.