<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://unkrig.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin</id>
	<title>unkrig.de - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://unkrig.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin"/>
	<link rel="alternate" type="text/html" href="https://unkrig.de/w/Special:Contributions/Admin"/>
	<updated>2026-06-04T15:16:07Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://unkrig.de/w/index.php?title=CommandLineOptions_tutorial&amp;diff=42</id>
		<title>CommandLineOptions tutorial</title>
		<link rel="alternate" type="text/html" href="https://unkrig.de/w/index.php?title=CommandLineOptions_tutorial&amp;diff=42"/>
		<updated>2024-05-01T20:50:22Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;===Processing command line options is easy, so why do I need a helper?===  To illustrate the reason being, let&amp;#039;s develop a command line application to show the typical problems and how &amp;lt;code&amp;gt;CommandLineOptions&amp;lt;/code&amp;gt; can help you:  &amp;lt;pre&amp;gt; package com.acme.clo_demo;  public class Diff {      public static void main(String[] args) {          boolean brief                = false;         boolean reportIdenticalFiles = false;         int     context              = 3;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Processing command line options is easy, so why do I need a helper?===&lt;br /&gt;
&lt;br /&gt;
To illustrate the reason being, let&#039;s develop a command line application to show the typical problems and how &amp;lt;code&amp;gt;CommandLineOptions&amp;lt;/code&amp;gt; can help you:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
package com.acme.clo_demo;&lt;br /&gt;
&lt;br /&gt;
public class Diff {&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
        boolean brief                = false;&lt;br /&gt;
        boolean reportIdenticalFiles = false;&lt;br /&gt;
        int     context              = 3;&lt;br /&gt;
&lt;br /&gt;
        int idx = 0;&lt;br /&gt;
        while (idx &amp;lt; args.length) {&lt;br /&gt;
            String arg = args[idx];&lt;br /&gt;
            if (!arg.startsWith(&amp;quot;-&amp;quot;)) break;&lt;br /&gt;
            idx++;&lt;br /&gt;
            if (&amp;quot;-q&amp;quot;.equals(arg) || &amp;quot;--brief&amp;quot;.equals(arg)) {&lt;br /&gt;
                brief = true;&lt;br /&gt;
            } else&lt;br /&gt;
            if (&amp;quot;-s&amp;quot;.equals(arg) || &amp;quot;--report-identical-files&amp;quot;.equals(arg)) {&lt;br /&gt;
                reportIdenticalFiles = true;&lt;br /&gt;
            } else&lt;br /&gt;
            if (&amp;quot;-C&amp;quot;.equals(arg) || &amp;quot;--Context&amp;quot;.equals(arg)) {&lt;br /&gt;
                context = Integer.parseInt(args[idx++]);&lt;br /&gt;
            } else&lt;br /&gt;
            {&lt;br /&gt;
                System.err.println(&amp;quot;Unrecognized command line option \&amp;quot;&amp;quot; + arg + &amp;quot;\&amp;quot;&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Now process args[idx]... and do the &amp;quot;real work&amp;quot;.&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This implementation supports both &amp;quot;short&amp;quot; and &amp;quot;long&amp;quot; options, and detects invalid options. However there is room for improvement:&lt;br /&gt;
* You cannot have &amp;quot;compact&amp;quot; short options, e.g. &amp;quot;&amp;lt;tt&amp;gt;-qs&amp;lt;/tt&amp;gt;&amp;quot; for &amp;quot;&amp;lt;tt&amp;gt;-q -s&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
* You get an &amp;lt;code&amp;gt;ArrayIndexOutOfBoundsException&amp;lt;/code&amp;gt; when &amp;quot;&amp;lt;tt&amp;gt;-C&amp;lt;/tt&amp;gt;&amp;quot; is not followed by an argument.&lt;br /&gt;
* You get a &amp;lt;code&amp;gt;NumberFormatException&amp;lt;/code&amp;gt; when the argument of &amp;quot;&amp;lt;tt&amp;gt;-C&amp;lt;/tt&amp;gt;&amp;quot; cannot be converted to an integer.&lt;br /&gt;
* If the first argument after the options starts with a hyphen, it is identified as an invalid option.&lt;br /&gt;
* The code is not documented.&lt;br /&gt;
* The only support the user gets when it uses the tool is the &amp;quot;Unsupported command line option...&amp;quot; error message.&lt;br /&gt;
&lt;br /&gt;
So here&#039;s the second version that overcomes these deficits:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
package com.acme.clo_demo;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * A (rudimentary) re-implementation of the well-known DIFF command line utility.&lt;br /&gt;
 */&lt;br /&gt;
public class Diff {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Parses the command line options and arguments, then prints the differences between two files or two&lt;br /&gt;
     * directories.&lt;br /&gt;
     * &amp;lt;p&amp;gt;&lt;br /&gt;
     *   Supports the following command line options:&lt;br /&gt;
     * &amp;lt;/p&amp;gt;&lt;br /&gt;
     * &amp;lt;dl&amp;gt;&lt;br /&gt;
     *   &amp;lt;dt&amp;gt;--help&amp;lt;/dt&amp;gt;&lt;br /&gt;
     *   &amp;lt;dd&amp;gt;Print usage help and exit&amp;lt;/dd&amp;gt;&lt;br /&gt;
     *   &amp;lt;dt&amp;gt;-q, --brief&amp;lt;/dt&amp;gt;&lt;br /&gt;
     *   &amp;lt;dd&amp;gt;Don&#039;t report the differences, only which files have changed&amp;lt;/dd&amp;gt;&lt;br /&gt;
     *   &amp;lt;dt&amp;gt;-s, --report-identical-files&amp;lt;/dt&amp;gt;&lt;br /&gt;
     *   &amp;lt;dd&amp;gt;Also report about files that did NOT change&amp;lt;/dd&amp;gt;&lt;br /&gt;
     *   &amp;lt;dt&amp;gt;-C &amp;lt;var&amp;gt;NUM&amp;lt;/var&amp;gt;, --context &amp;lt;var&amp;gt;NUM&amp;lt;/var&amp;gt;&amp;lt;/dt&amp;gt;&lt;br /&gt;
     *   &amp;lt;dd&amp;gt;Report differences in &amp;quot;context diff&amp;quot; format, with &amp;lt;var&amp;gt;NUM&amp;lt;/var&amp;gt; lines of context&amp;lt;/dd&amp;gt;&lt;br /&gt;
     * &amp;lt;/dl&amp;gt;&lt;br /&gt;
     */&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
        boolean brief                = false;&lt;br /&gt;
        boolean reportIdenticalFiles = false;&lt;br /&gt;
        int     context              = 3;&lt;br /&gt;
&lt;br /&gt;
        int idx = 0;&lt;br /&gt;
        while (idx &amp;lt; args.length) {&lt;br /&gt;
&lt;br /&gt;
            String arg = args[idx];&lt;br /&gt;
&lt;br /&gt;
            if (!arg.startsWith(&amp;quot;-&amp;quot;)) break;&lt;br /&gt;
&lt;br /&gt;
            idx++;&lt;br /&gt;
&lt;br /&gt;
            if (&amp;quot;--&amp;quot;.equals(arg)) {&lt;br /&gt;
                break;&lt;br /&gt;
            } else&lt;br /&gt;
            if (&amp;quot;--help&amp;quot;.equals(arg)) {&lt;br /&gt;
                System.out.println(&amp;quot;Prints the differences between files.&amp;quot;);&lt;br /&gt;
                System.out.println();&lt;br /&gt;
                System.out.println(&amp;quot;Usage:&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;  diff [ &amp;lt;option&amp;gt; ] ... &amp;lt;file1&amp;gt; &amp;lt;file2&amp;gt;&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;      Prints the differences between &amp;lt;file1&amp;gt; and &amp;lt;file2&amp;gt;.&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;  diff [ &amp;lt;option&amp;gt; ] ... &amp;lt;dir1&amp;gt; &amp;lt;dir2&amp;gt;&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;      Prints the differences between the files under &amp;lt;dir1&amp;gt; and &amp;lt;dir2&amp;gt;.&amp;quot;);&lt;br /&gt;
                System.out.println();&lt;br /&gt;
                System.out.println(&amp;quot;Supports the following command line options:&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;  --help&amp;lt;/dt&amp;gt;&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;      Print usage help and exit&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;  -q, --brief&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;      Don&#039;t report the differences, only which files have changed&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;  -s, --report-identical-files&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;      Also report about files that did NOT change&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;  -C &amp;lt;NUM&amp;gt;, --context &amp;lt;NUM&amp;gt;&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;      Report differences in \&amp;quot;context diff\&amp;quot; format, with &amp;lt;NUM&amp;gt; lines of&amp;quot;);&lt;br /&gt;
                System.out.println(&amp;quot;      context&amp;quot;);&lt;br /&gt;
                System.exit(0);&lt;br /&gt;
            } else&lt;br /&gt;
            if (&amp;quot;-q&amp;quot;.equals(arg) || &amp;quot;--brief&amp;quot;.equals(arg)) {&lt;br /&gt;
                brief = true;&lt;br /&gt;
            } else&lt;br /&gt;
            if (&amp;quot;-s&amp;quot;.equals(arg) || &amp;quot;--report-identical-files&amp;quot;.equals(arg)) {&lt;br /&gt;
                reportIdenticalFiles = true;&lt;br /&gt;
            } else&lt;br /&gt;
            if (&amp;quot;-C&amp;quot;.equals(arg) || &amp;quot;--Context&amp;quot;.equals(arg)) {&lt;br /&gt;
                if (idx == args.length) {&lt;br /&gt;
                    System.err.println(&amp;quot;Count missing after \&amp;quot;-C\&amp;quot; or \&amp;quot;--context\&amp;quot;.&amp;quot;);&lt;br /&gt;
                    System.exit(1);&lt;br /&gt;
                }&lt;br /&gt;
                try {&lt;br /&gt;
                   context = Integer.parseInt(args[idx++]);&lt;br /&gt;
               } catch (NumberFormatException nfe) {&lt;br /&gt;
                   System.err.println(&amp;quot;Cannot convert \&amp;quot;&amp;quot; + args[idx - 1] + &amp;quot;\&amp;quot; to an integer&amp;quot;);&lt;br /&gt;
                   System.exit(1);&lt;br /&gt;
               }&lt;br /&gt;
            } else&lt;br /&gt;
            {&lt;br /&gt;
                System.err.println(&amp;quot;Unrecognized command line option \&amp;quot;&amp;quot; + arg + &amp;quot;\&amp;quot;; try \&amp;quot;--help\&amp;quot;.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        // Now process args[idx]... and do the &amp;quot;real work&amp;quot;.&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Well, that&#039;s a lot of boilerplate code! And it&#039;s just this trivial example...&lt;br /&gt;
&lt;br /&gt;
Also, people may want to read about the tool without installing or running it, so you fire up the word processor, or the HTML editor, or the Wiki...&lt;br /&gt;
&lt;br /&gt;
But after all, you have written and documented a professional command line tool, congratulations!&lt;br /&gt;
&lt;br /&gt;
But wait, now there is number of &#039;&#039;new&#039;&#039; problems:&lt;br /&gt;
* The code for processing the command line options is &#039;&#039;huge&#039;&#039;, and most of it deals with trivial error conditions.&lt;br /&gt;
* There is a lot of redundancy in the command line options: There&#039;s the CLO &#039;&#039;implementation&#039;&#039;, and the &#039;&#039;description&#039;&#039; appears in three places: The JAVADOC of the &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt; method, the &amp;lt;code&amp;gt;System.out.println()&amp;lt;/code&amp;gt; for the &amp;quot;&amp;lt;tt&amp;gt;--help&amp;lt;/tt&amp;gt;&amp;quot; option, and in the online/paper documentation.&lt;br /&gt;
&lt;br /&gt;
What a maintenance nightmare!&lt;br /&gt;
&lt;br /&gt;
==So how can &amp;lt;code&amp;gt;CommandLineOptions&amp;lt;/code&amp;gt; help?==&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how it works:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;First&#039;&#039;&#039;, you replace the command line option parsing with a call to [http://commons.unkrig.de/javadoc/de/unkrig/commons/util/CommandLineOptions.html#parse-java.lang.String:A-java.lang.Object- CommandLineOptions.parse()]. Also add a method for each command line option, annotate it with [http://commons.unkrig.de/javadoc/de/unkrig/commons/util/annotation/CommandLineOption.html @CommandLineOption] and add its description as JAVADOC. Put the usage text into the JAVADOC comment of the &amp;quot;&amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;&amp;quot; method, with a placeholder &amp;quot;&amp;lt;tt&amp;gt;{@command-line-options}&amp;lt;/tt&amp;gt; for the descriptions of the command line options.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Second&#039;&#039;&#039;, you generate HTML documentation with the [[Doclet#The_MAIN_Doclet|MAIN doclet]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;javadoc doclet=&amp;quot;de.unkrig.doclet.main.MainDoclet&amp;quot; docletpath=&amp;quot;de.unkrig.doclet.main.jar&amp;quot; destdir=&amp;quot;src&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;fileset file=&amp;quot;src/com/acme/clo_demo/Diff.java&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/javadoc&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Third&#039;&#039;&#039;, you convert the HTML documentation into plain text with the [http://html2txt.unkrig.de HTML2TXT] utility:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;taskdef classpath=&amp;quot;html2txt.jar&amp;quot; resource=&amp;quot;de/unkrig/html2txt/antlib.xml&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;html2txt&amp;gt;&lt;br /&gt;
     &amp;lt;fileset dir=&amp;quot;src&amp;quot; includes=&amp;quot;com/acme/clo_demo/Diff.main(String[]).html&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/html2txt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fourth&#039;&#039;&#039;, rewrite the &amp;quot;&amp;lt;tt&amp;gt;--help&amp;lt;/tt&amp;gt;&amp;quot; option to simply copy the plain text documentation to &amp;lt;code&amp;gt;System.out&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==So here&#039;s the code==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
package com.acme.clo_demo;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.io.InputStream;&lt;br /&gt;
import java.io.InputStreamReader;&lt;br /&gt;
import java.io.OutputStreamWriter;&lt;br /&gt;
import java.io.Writer;&lt;br /&gt;
import java.util.regex.Pattern;&lt;br /&gt;
&lt;br /&gt;
import de.unkrig.commons.text.pattern.PatternUtil;&lt;br /&gt;
import de.unkrig.commons.util.CommandLineOptions;&lt;br /&gt;
import de.unkrig.commons.util.annotation.CommandLineOption;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * A (rudimentary) re-implementation of the well-known DIFF command line utility.&lt;br /&gt;
 */&lt;br /&gt;
public class Diff {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Prints the differences between files.&lt;br /&gt;
     * &amp;lt;h2&amp;gt;Usage:&amp;lt;/h2&amp;gt;&lt;br /&gt;
     * &amp;lt;dl&amp;gt;&lt;br /&gt;
     *   &amp;lt;dt&amp;gt;diff [ &amp;lt;var&amp;gt;option&amp;lt;/var&amp;gt; ] ... &amp;lt;var&amp;gt;file1&amp;lt;/var&amp;gt; &amp;lt;var&amp;gt;file2&amp;lt;/var&amp;gt;&amp;lt;/dt&amp;gt;&lt;br /&gt;
     *   &amp;lt;dd&amp;gt;Prints the differences between &amp;lt;var&amp;gt;file1&amp;lt;/var&amp;gt; and &amp;lt;var&amp;gt;file2&amp;lt;/var&amp;gt;.&amp;lt;/dd&amp;gt;&lt;br /&gt;
     *   &amp;lt;dt&amp;gt;diff [ &amp;lt;var&amp;gt;option&amp;lt;/var&amp;gt; ] ... &amp;lt;var&amp;gt;dir1&amp;lt;/var&amp;gt; &amp;lt;var&amp;gt;dir2&amp;lt;/var&amp;gt;&amp;lt;/dt&amp;gt;&lt;br /&gt;
     *   &amp;lt;dd&amp;gt;Prints the differences between the files under &amp;lt;var&amp;gt;dir1&amp;lt;/var&amp;gt; and &amp;lt;var&amp;gt;dir2&amp;lt;/var&amp;gt;.&amp;lt;/dd&amp;gt;&lt;br /&gt;
     * &amp;lt;/dl&amp;gt;&lt;br /&gt;
     * &amp;lt;h2&amp;gt;Options:&amp;lt;/h2&amp;gt;&lt;br /&gt;
     * {@command-line-options}&lt;br /&gt;
     */&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
        Diff diff = new Diff();&lt;br /&gt;
&lt;br /&gt;
        args = CommandLineOptions.parse(args, diff);&lt;br /&gt;
&lt;br /&gt;
        // Now process args[idx]... and do the &amp;quot;real work&amp;quot;.&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private boolean brief                = false;&lt;br /&gt;
    private boolean reportIdenticalFiles = false;&lt;br /&gt;
    private int     context              = 3;&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Print usage help and exit.&lt;br /&gt;
     */&lt;br /&gt;
    @CommandLineOption public void&lt;br /&gt;
    help() throws IOException {&lt;br /&gt;
        CommandLineOptions.printResource(Diff.class, &amp;quot;main(String[]).txt&amp;quot;, null, System.out);&lt;br /&gt;
        System.exit(0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Don&#039;t report the differences, only which files have changed.&lt;br /&gt;
     */&lt;br /&gt;
    @CommandLineOption(name = { &amp;quot;-q&amp;quot;, &amp;quot;--brief&amp;quot; }) public void&lt;br /&gt;
    setBrief() { this.brief = true; }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Also report about files that did NOT change.&lt;br /&gt;
     */&lt;br /&gt;
    @CommandLineOption(name = { &amp;quot;-s&amp;quot;, &amp;quot;--report-identical-files&amp;quot;}) public void&lt;br /&gt;
    setReportIdenticalFiles() { this.reportIdenticalFiles = true; }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Report differences in &amp;quot;context diff&amp;quot; format, with &amp;lt;var&amp;gt;number-of-lines&amp;lt;/var&amp;gt; lines of context.&lt;br /&gt;
     */&lt;br /&gt;
    @CommandLineOption(name = { &amp;quot;-C&amp;quot;, &amp;quot;--Context&amp;quot; }) public void&lt;br /&gt;
    setContext(int numberOfLines) { this.context = numberOfLines; }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you run it with the &amp;quot;&amp;lt;tt&amp;gt;--help&amp;lt;/tt&amp;gt;&amp;quot; option, you get:&lt;br /&gt;
&lt;br /&gt;
 Prints the differences between files.&lt;br /&gt;
 &lt;br /&gt;
 Usage:&lt;br /&gt;
 ======&lt;br /&gt;
 &lt;br /&gt;
   diff [ &amp;lt;option&amp;gt; ] ... &amp;lt;file1&amp;gt; &amp;lt;file2&amp;gt;&lt;br /&gt;
       Prints the differences between &amp;lt;file1&amp;gt; and &amp;lt;file2&amp;gt;.&lt;br /&gt;
   diff [ &amp;lt;option&amp;gt; ] ... &amp;lt;dir1&amp;gt; &amp;lt;dir2&amp;gt;&lt;br /&gt;
       Prints the differences between the files under &amp;lt;dir1&amp;gt; and &amp;lt;dir2&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
 Options:&lt;br /&gt;
 ========&lt;br /&gt;
 &lt;br /&gt;
 --help&lt;br /&gt;
     Print usage help and exit.&lt;br /&gt;
 -q&lt;br /&gt;
 --brief&lt;br /&gt;
     Don&#039;t report the differences, only which files have changed.&lt;br /&gt;
 -s&lt;br /&gt;
 --report-identical-files&lt;br /&gt;
     Also report about files that did NOT change.&lt;br /&gt;
 -C &amp;lt;number-of-lines&amp;gt;&lt;br /&gt;
 --context &amp;lt;number-of-lines&amp;gt;&lt;br /&gt;
     Report differences in &amp;quot;context diff&amp;quot; format, with &amp;lt;number-of-lines&amp;gt; lines&lt;br /&gt;
     of context.&lt;br /&gt;
&lt;br /&gt;
And voila - you have zero redundancy, and HTML documentation for printing and/or online presentation for free!&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://unkrig.de/w/index.php?title=Using_Globs&amp;diff=41</id>
		<title>Using Globs</title>
		<link rel="alternate" type="text/html" href="https://unkrig.de/w/index.php?title=Using_Globs&amp;diff=41"/>
		<updated>2024-05-01T20:18:28Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;This article documents the &amp;quot;Globs&amp;quot; feature implemented in [http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/package-summary.html commons.unkrig.de].  === Introduction ===  Surely you have used globs before (maybe even without knowing that they call them &amp;quot;globs&amp;quot;):   *.txt  dir/*.doc  execut?r.txt  Globs are a widely spread concept that is used throughout the UNIX, MICROSOFT and other &amp;quot;worlds&amp;quot;.  All implementations support at least th...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article documents the &amp;quot;Globs&amp;quot; feature implemented in [http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/package-summary.html commons.unkrig.de].&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Surely you have used globs before (maybe even without knowing that they call them &amp;quot;globs&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
 *.txt&lt;br /&gt;
 dir/*.doc&lt;br /&gt;
 execut?r.txt&lt;br /&gt;
&lt;br /&gt;
Globs are a widely spread concept that is used throughout the UNIX, MICROSOFT and other &amp;quot;worlds&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
All implementations support at least the following elements:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct     !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;    ||Any character except the file separator (&amp;quot;&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&amp;quot; and/or &amp;quot;&amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt;&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;    ||Zero or more characters except the file separator&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&#039;&#039;x&#039;&#039;&amp;lt;/tt&amp;gt;||The character &amp;lt;tt&amp;gt;&#039;&#039;x&#039;&#039;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some implementations add more features:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct                                   !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[abc]&amp;lt;/tt&amp;gt;                              ||Exactly one of the characters &amp;quot;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&amp;quot;, &amp;quot;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[^abc]&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;or&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;[!abc]&amp;lt;/tt&amp;gt;||Any character &#039;&#039;except&#039;&#039; &amp;quot;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&amp;quot;, &amp;quot;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;&amp;quot; or &amp;quot;&amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[A-Za-z]&amp;lt;/tt&amp;gt;                           ||Any (latin) letter&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;**&amp;lt;/tt&amp;gt;                                 ||Zero or more characters (&#039;&#039;including&#039;&#039; the file separator)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\&#039;&#039;X&#039;&#039;&amp;lt;/tt&amp;gt;                             ||&amp;quot;&amp;lt;tt&amp;gt;&#039;&#039;X&#039;&#039;&amp;lt;/tt&amp;gt;&amp;quot;, even if &amp;quot;&amp;lt;tt&amp;gt;&#039;&#039;X&#039;&#039;&amp;lt;/tt&amp;gt;&amp;quot; is a meta character&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Since version 1.7 JAVA provides [http://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29 its own implementation] of &amp;quot;glob matching&amp;quot;, which adds another (quite uncommon) construct:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct                              !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;{&#039;&#039;alpha&#039;&#039;,&#039;&#039;beta&#039;&#039;,&#039;&#039;gamma&#039;&#039;}&amp;lt;/tt&amp;gt;||Any of &amp;quot;&amp;lt;tt&amp;gt;alpha&amp;lt;/tt&amp;gt;&amp;quot;, &amp;quot;&amp;lt;tt&amp;gt;beta&amp;lt;/tt&amp;gt;&amp;quot; or &amp;quot;&amp;lt;tt&amp;gt;gamma&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All in all, globs are very practical, though not very powerful. This is why &amp;lt;code&amp;gt;de.unkrig.commons&amp;lt;/code&amp;gt; provides yet another implementation, as follows:&lt;br /&gt;
&lt;br /&gt;
=== Regular expressions features ===&lt;br /&gt;
&lt;br /&gt;
First,&lt;br /&gt;
[http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/Pattern2.html &amp;lt;code&amp;gt;de.unkrig.commons.text.pattern.Pattern2&amp;lt;/code&amp;gt;]&lt;br /&gt;
combines the simplicity of globs with the full power of&lt;br /&gt;
[http://docs.oracle.com/javase/7/docs/api/index.html?java/util/regex/Pattern.html JAVA regular expressions].&lt;br /&gt;
It does so by modifying a few characters in the glob before feeding it to &amp;lt;code&amp;gt;java.util.text.pattern.Pattern.compile()&amp;lt;/code&amp;gt;, making that effectively a glob compiler:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Glob construct!!Regex construct  !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;    ||&amp;lt;tt&amp;gt;[^/\\!]*&amp;lt;/tt&amp;gt;||Any character except the file separator and &amp;quot;!&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;    ||&amp;lt;tt&amp;gt;[^/\\!]*&amp;lt;/tt&amp;gt;||Zero or more characters except the file separator and &amp;quot;!&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;**&amp;lt;/tt&amp;gt;   ||&amp;lt;tt&amp;gt;[^!]*&amp;lt;/tt&amp;gt;   ||Zero or more characters except &amp;quot;!&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;***&amp;lt;/tt&amp;gt;  ||&amp;lt;tt&amp;gt;.*&amp;lt;/tt&amp;gt;      ||Zero or more characters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;.&amp;lt;/tt&amp;gt;||&amp;lt;tt&amp;gt;\.&amp;lt;/tt&amp;gt;||The dot is a literal (not a character class as in a regular expression)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If you have not yet worked with regular expressions: JAVA regular expressions are very powerful and introduce many constructs and meta characters. Find the complete reference documentation [http://docs.oracle.com/javase/7/docs/api/index.html?java/util/regex/Pattern.html here].&lt;br /&gt;
&lt;br /&gt;
Since &amp;quot;&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&amp;quot; are not quantifiers as in regular expression (&amp;quot;&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;&amp;quot; == zero-or-one, &amp;quot;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&amp;quot; == zero-or-more), one has to use &amp;quot;&amp;lt;tt&amp;gt;{0,1}&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;{0,}&amp;lt;/tt&amp;gt;&amp;quot; instead. The alternative notation for &amp;quot;&amp;lt;tt&amp;gt;.&amp;lt;/tt&amp;gt;&amp;quot; (&amp;quot;any character&amp;quot;) is &amp;quot;&amp;lt;tt&amp;gt;[^]&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Find the reference documentation [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Pattern2.html here].&lt;br /&gt;
&lt;br /&gt;
The API of&lt;br /&gt;
[http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/Pattern2.html &amp;lt;code&amp;gt;de.unkrig.commons.text.pattern.Pattern2&amp;lt;/code&amp;gt;]&lt;br /&gt;
is totally compatible with that of&lt;br /&gt;
[http://docs.oracle.com/javase/7/docs/api/index.html?java/util/regex/Pattern.html &amp;lt;code&amp;gt;java.util.pattern.Pattern&amp;lt;/code&amp;gt;],&lt;br /&gt;
plus it adds a new compilation Flag &amp;lt;code&amp;gt;Pattern2.WILDCARD&amp;lt;/code&amp;gt; that modifies the expression syntax from regex to globs.&lt;br /&gt;
&lt;br /&gt;
=== Includes-Excludes ===&lt;br /&gt;
&lt;br /&gt;
Second, it adds &#039;&#039;includes-excludes&#039;&#039;. This involves two new meta characters, &amp;quot;&amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt;&amp;quot; and &amp;quot;&amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt;&amp;quot;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct                         !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&#039;&#039;pattern1&#039;&#039;,&#039;&#039;pattern2&#039;&#039;&amp;lt;/tt&amp;gt;||Any string that matches &#039;&#039;pattern1&#039;&#039; or &#039;&#039;pattern2&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&#039;&#039;pattern1&#039;&#039;~&#039;&#039;pattern2&#039;&#039;&amp;lt;/tt&amp;gt;||Any string that matches &#039;&#039;pattern1&#039;&#039;, but not &#039;&#039;pattern2&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~&#039;&#039;pattern1&#039;&#039;&amp;lt;/tt&amp;gt;            ||Any string that does &#039;&#039;not&#039;&#039; match &#039;&#039;pattern1&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&#039;&#039;pattern1&#039;&#039;,&#039;&#039;pattern2&#039;&#039;~&#039;&#039;pattern3&#039;&#039;~&#039;&#039;pattern4&#039;&#039;,&#039;&#039;pattern5&#039;&#039;&amp;lt;/tt&amp;gt;||Any string that matches &#039;&#039;pattern1&#039;&#039; or &#039;&#039;pattern2&#039;&#039;, but not &#039;&#039;pattern3&#039;&#039; nor &#039;&#039;pattern4&#039;&#039;; plus any string that matches &#039;&#039;pattern5&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This may sound complicated, but the very simple rule is: The patterns are applied &#039;&#039;right-to-left&#039;&#039;, and the first match determines the result.&lt;br /&gt;
&lt;br /&gt;
This comes with [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Glob.html &amp;lt;tt&amp;gt;de.unkrig.commons.text.pattern.Glob.compile()&amp;lt;/tt&amp;gt;] and the new [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Glob.html &amp;lt;tt&amp;gt;INCLUDES_EXCLUDES&amp;lt;/tt&amp;gt;] compilation flag.&lt;br /&gt;
&lt;br /&gt;
=== Replacements ===&lt;br /&gt;
&lt;br /&gt;
Third, it adds &#039;&#039;replacements&#039;&#039;. This involves one new meta character, &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct               !!Matches                             !!Replaces with&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;*.c=$0.bak&amp;lt;/tt&amp;gt;     ||Any string ending with &amp;quot;&amp;lt;tt&amp;gt;.c&amp;lt;/tt&amp;gt;&amp;quot;||The original string plus &amp;quot;&amp;lt;tt&amp;gt;.bak&amp;lt;/tt&amp;gt;&amp;quot; (&amp;quot;&amp;lt;tt&amp;gt;$0&amp;lt;/tt&amp;gt;&amp;quot; represents the &amp;quot;entire match&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;(*).(*)=$1.$2$2&amp;lt;/tt&amp;gt;||Any string containing a dot         ||The original string, with the file name extension doubled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This comes with the [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Glob.html &amp;lt;tt&amp;gt;Glob.replace()&amp;lt;/tt&amp;gt;] API.&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;quot;&amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;&amp;quot; is a meta character &#039;&#039;only in the replacement&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Also notice that when combining replacements with includes-excludes (see above), replacements are specific for &#039;&#039;each&#039;&#039; include (while it does not make any sense to use replacements with excludes, though).&lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
&lt;br /&gt;
All these features can be combined mercilessly, e.g.:&lt;br /&gt;
&lt;br /&gt;
 *=$0$0~*.bak&lt;br /&gt;
 (*).docx{0,1}=$1.txt~*blabla*&lt;br /&gt;
&lt;br /&gt;
Using it is simple:&lt;br /&gt;
&lt;br /&gt;
 import de.unkrig.commons.text.pattern.Glob;&lt;br /&gt;
 import de.unkrig.commons.text.pattern.Pattern2;&lt;br /&gt;
 &lt;br /&gt;
 Glob glob = Glob.compile(&amp;quot;*.c=$0.C,*.h=$0.H&amp;quot;, Pattern2.WILDCARD | Glob.INCLUDES_EXCLUDES | Glob.REPLACEMENT);&lt;br /&gt;
 glob.match(&amp;quot;foo.c&amp;quot;);     // returns true&lt;br /&gt;
 glob.replace(&amp;quot;foo.h&amp;quot;);   // returns &amp;quot;foo.H&amp;quot;&lt;br /&gt;
 glob.replace(&amp;quot;foo.cpp&amp;quot;); // returns null&lt;br /&gt;
&lt;br /&gt;
Remember: The &amp;lt;tt&amp;gt;Pattern2.WILDCARD&amp;lt;/tt&amp;gt; modifies the regex compilation to understand wildcard characters. &amp;lt;tt&amp;gt;Glob.INCLUDES_EXCLUDES&amp;lt;/tt&amp;gt; activates the recognition of &amp;quot;&amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;~&amp;lt;/tt&amp;gt;&amp;quot;. Finally, &amp;lt;tt&amp;gt;Glob.REPLACEMENT&amp;lt;/tt&amp;gt; activates the recognition of &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://unkrig.de/w/index.php?title=Unkrig.de&amp;diff=39</id>
		<title>Unkrig.de</title>
		<link rel="alternate" type="text/html" href="https://unkrig.de/w/index.php?title=Unkrig.de&amp;diff=39"/>
		<updated>2024-05-01T19:55:39Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page Unkrig.de:Unkrig.de to Unkrig.de&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;font size=&amp;quot;+6&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Welcome to unkrig.de!&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;font color=&amp;quot;#777&amp;quot;&amp;gt;&#039;&#039;Where the fine software grows&#039;&#039;&amp;lt;/font&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
[[image:Javawordcloud.png|right]]&lt;br /&gt;
&lt;br /&gt;
== Preamble ==&lt;br /&gt;
&lt;br /&gt;
Hello out there!&lt;br /&gt;
&lt;br /&gt;
I am a professional programmer, and when I have time I work on several cool open source projects. Find them useful, interesting, inspiring - or contribute! To contact me, send email to &#039;arno att unkrig dott de&#039;.&lt;br /&gt;
&lt;br /&gt;
Cheers, Arno&lt;br /&gt;
&lt;br /&gt;
== Larger Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [https://janino-compiler.github.io/janino/ Janino] ===&lt;br /&gt;
: A super-small, super-fast Java&amp;amp;trade; compiler for embedded applications where you want to compile code on-the-fly into byte code which is executed in the running JVM.&lt;br /&gt;
&lt;br /&gt;
=== [https://github.com/aunkrig/lfr LFR - Lightning-fast Regular Expressions for Java] ===&lt;br /&gt;
: A 99.9%-complete reimplementation of &amp;lt;code&amp;gt;java.util.regex&amp;lt;/code&amp;gt; (&amp;quot;JUR&amp;quot;) with better &amp;lt;code&amp;gt;match()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find()&amp;lt;/code&amp;gt; performance.&lt;br /&gt;
&lt;br /&gt;
=== [[Antology]] ===&lt;br /&gt;
: Some contributions to [http://ant.apache.org APACHE ANT], e.g. the &amp;lt;code&amp;gt;&amp;amp;lt;swingDialog&amp;gt;&amp;lt;/code&amp;gt; task which significantly enhances ANT&#039;s &amp;lt;code&amp;gt;&amp;amp;lt;input&amp;gt;&amp;lt;/code&amp;gt; task.&lt;br /&gt;
&lt;br /&gt;
=== [[Zz.unkrig.de|ZZ Tools]] ===&lt;br /&gt;
: Enhanced versions of the widely known DIFF, FIND, GREP and PATCH command-line tools, which handle not only directories and files, but also archive and compressed files, and even nested archive and compressed files. They can even disassemble Java &amp;lt;code&amp;gt;.class&amp;lt;/code&amp;gt; files on-the fly and operate on the disassembly.&lt;br /&gt;
&lt;br /&gt;
=== [[Cs-contrib.unkrig.de|CheckStyle Contributions]] ===&lt;br /&gt;
: Additional checks, filters and quickfixes for [http://checkstyle.sourceforge.net/ CheckStyle] and [http://eclipse-cs.sourceforge.net/ Eclipse-CS].&lt;br /&gt;
&lt;br /&gt;
=== [[Commons.unkrig.de]] ===&lt;br /&gt;
: A versatile Java&amp;amp;trade; library, including a highly flexible HTTP and FTP server.&lt;br /&gt;
&lt;br /&gt;
== Smaller Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [https://github.com/aunkrig/autoauth AUTOAUTH] ===&lt;br /&gt;
&lt;br /&gt;
An HTTP proxy that handles proxy authentication.&lt;br /&gt;
&lt;br /&gt;
=== [[Doclet|Doclets]] ===&lt;br /&gt;
&lt;br /&gt;
Doclets are a way to re-use the JAVADOC tool to do other things than just generate Java API documentation. I wrote a few of them for different purposes:&lt;br /&gt;
&lt;br /&gt;
===== [[ANT doclet|The ANT Doclet]] =====&lt;br /&gt;
: Generates JAVADOC-like HTML documentation for an ANTLIB, e.g. for [[Antology]] and the [[Zz.unkrig.de|ZZ tools]].&lt;br /&gt;
&lt;br /&gt;
===== [[Cs-doclet|The CheckStyle Doclet]] =====&lt;br /&gt;
: Generates the metadata files for CheckStyle and eclipse-cs from &#039;doc tags&#039; in the source code of your checks and filters. &lt;br /&gt;
&lt;br /&gt;
===== [[JAVADOC doclet|The JAVADOC Doclet]] =====&lt;br /&gt;
: A re-implementation of the JAVADOC standard doclet, basically a reference to show how to use the &amp;quot;[[No-template|no-template]]&amp;quot; framework.&lt;br /&gt;
&lt;br /&gt;
===== [[MAIN doclet|The MAIN Doclet]] =====&lt;br /&gt;
: Generates HTML documentation for a &amp;quot;main()&amp;quot; method - useful for command line tools with a set of command line options.&lt;br /&gt;
&lt;br /&gt;
=== [[Html2txt|html2txt]] ===&lt;br /&gt;
: A Java tool to convert HTML documents into plain text.&lt;br /&gt;
&lt;br /&gt;
=== [[JDisasm|jdisasm]] ===&lt;br /&gt;
: A disassembler for Java .class files.&lt;br /&gt;
&lt;br /&gt;
=== [[No-template|no-template]] ===&lt;br /&gt;
: A super-small Java library for templating, i.e. generating text files (HTML, XML, whatever) from a &amp;quot;template&amp;quot; text file.&lt;br /&gt;
&lt;br /&gt;
== Retired Projects ==&lt;br /&gt;
&lt;br /&gt;
These projects are no longer maintained and are only of limited use, e.g. because they work only with old Java versions.&lt;br /&gt;
&lt;br /&gt;
=== [[Loggifier.unkrig.de|Loggifier]] ===&lt;br /&gt;
: A tool for automatic injection of logging code into Java&amp;amp;trade; class files, making it unnecessary to mess up your code with hand-written logging.&lt;br /&gt;
&lt;br /&gt;
=== [[Cvstools.unkrig.de|Eclipse plug-in for extended CVS possibilities]] ===&lt;br /&gt;
&lt;br /&gt;
: An ECLIPSE plug-in that adds CVS functionality that is sometimes painfully missing from ECLIPSE&#039;s built-in CVS client.&lt;br /&gt;
&lt;br /&gt;
=== [[Subclipse.unkrig.de|Subclipse enhancements Eclipse plug-in]] ===&lt;br /&gt;
&lt;br /&gt;
: The often-missed &amp;lt;code&amp;gt;&amp;lt;de.unkrig.subclipse.svn&amp;gt;&amp;lt;/code&amp;gt; ANT task that uses the SUBCLIPSE client of the running ECLIPSE workbench.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://unkrig.de/w/index.php?title=Unkrig.de&amp;diff=38</id>
		<title>Unkrig.de</title>
		<link rel="alternate" type="text/html" href="https://unkrig.de/w/index.php?title=Unkrig.de&amp;diff=38"/>
		<updated>2024-05-01T19:52:20Z</updated>

		<summary type="html">&lt;p&gt;Admin: Admin moved page Main Page to Unkrig.de:Unkrig.de without leaving a redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;font size=&amp;quot;+6&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Welcome to unkrig.de!&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;font color=&amp;quot;#777&amp;quot;&amp;gt;&#039;&#039;Where the fine software grows&#039;&#039;&amp;lt;/font&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
[[image:Javawordcloud.png|right]]&lt;br /&gt;
&lt;br /&gt;
== Preamble ==&lt;br /&gt;
&lt;br /&gt;
Hello out there!&lt;br /&gt;
&lt;br /&gt;
I am a professional programmer, and when I have time I work on several cool open source projects. Find them useful, interesting, inspiring - or contribute! To contact me, send email to &#039;arno att unkrig dott de&#039;.&lt;br /&gt;
&lt;br /&gt;
Cheers, Arno&lt;br /&gt;
&lt;br /&gt;
== Larger Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [https://janino-compiler.github.io/janino/ Janino] ===&lt;br /&gt;
: A super-small, super-fast Java&amp;amp;trade; compiler for embedded applications where you want to compile code on-the-fly into byte code which is executed in the running JVM.&lt;br /&gt;
&lt;br /&gt;
=== [https://github.com/aunkrig/lfr LFR - Lightning-fast Regular Expressions for Java] ===&lt;br /&gt;
: A 99.9%-complete reimplementation of &amp;lt;code&amp;gt;java.util.regex&amp;lt;/code&amp;gt; (&amp;quot;JUR&amp;quot;) with better &amp;lt;code&amp;gt;match()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;find()&amp;lt;/code&amp;gt; performance.&lt;br /&gt;
&lt;br /&gt;
=== [[Antology]] ===&lt;br /&gt;
: Some contributions to [http://ant.apache.org APACHE ANT], e.g. the &amp;lt;code&amp;gt;&amp;amp;lt;swingDialog&amp;gt;&amp;lt;/code&amp;gt; task which significantly enhances ANT&#039;s &amp;lt;code&amp;gt;&amp;amp;lt;input&amp;gt;&amp;lt;/code&amp;gt; task.&lt;br /&gt;
&lt;br /&gt;
=== [[Zz.unkrig.de|ZZ Tools]] ===&lt;br /&gt;
: Enhanced versions of the widely known DIFF, FIND, GREP and PATCH command-line tools, which handle not only directories and files, but also archive and compressed files, and even nested archive and compressed files. They can even disassemble Java &amp;lt;code&amp;gt;.class&amp;lt;/code&amp;gt; files on-the fly and operate on the disassembly.&lt;br /&gt;
&lt;br /&gt;
=== [[Cs-contrib.unkrig.de|CheckStyle Contributions]] ===&lt;br /&gt;
: Additional checks, filters and quickfixes for [http://checkstyle.sourceforge.net/ CheckStyle] and [http://eclipse-cs.sourceforge.net/ Eclipse-CS].&lt;br /&gt;
&lt;br /&gt;
=== [[Commons.unkrig.de]] ===&lt;br /&gt;
: A versatile Java&amp;amp;trade; library, including a highly flexible HTTP and FTP server.&lt;br /&gt;
&lt;br /&gt;
== Smaller Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [https://github.com/aunkrig/autoauth AUTOAUTH] ===&lt;br /&gt;
&lt;br /&gt;
An HTTP proxy that handles proxy authentication.&lt;br /&gt;
&lt;br /&gt;
=== [[Doclet|Doclets]] ===&lt;br /&gt;
&lt;br /&gt;
Doclets are a way to re-use the JAVADOC tool to do other things than just generate Java API documentation. I wrote a few of them for different purposes:&lt;br /&gt;
&lt;br /&gt;
===== [[ANT doclet|The ANT Doclet]] =====&lt;br /&gt;
: Generates JAVADOC-like HTML documentation for an ANTLIB, e.g. for [[Antology]] and the [[Zz.unkrig.de|ZZ tools]].&lt;br /&gt;
&lt;br /&gt;
===== [[Cs-doclet|The CheckStyle Doclet]] =====&lt;br /&gt;
: Generates the metadata files for CheckStyle and eclipse-cs from &#039;doc tags&#039; in the source code of your checks and filters. &lt;br /&gt;
&lt;br /&gt;
===== [[JAVADOC doclet|The JAVADOC Doclet]] =====&lt;br /&gt;
: A re-implementation of the JAVADOC standard doclet, basically a reference to show how to use the &amp;quot;[[No-template|no-template]]&amp;quot; framework.&lt;br /&gt;
&lt;br /&gt;
===== [[MAIN doclet|The MAIN Doclet]] =====&lt;br /&gt;
: Generates HTML documentation for a &amp;quot;main()&amp;quot; method - useful for command line tools with a set of command line options.&lt;br /&gt;
&lt;br /&gt;
=== [[Html2txt|html2txt]] ===&lt;br /&gt;
: A Java tool to convert HTML documents into plain text.&lt;br /&gt;
&lt;br /&gt;
=== [[JDisasm|jdisasm]] ===&lt;br /&gt;
: A disassembler for Java .class files.&lt;br /&gt;
&lt;br /&gt;
=== [[No-template|no-template]] ===&lt;br /&gt;
: A super-small Java library for templating, i.e. generating text files (HTML, XML, whatever) from a &amp;quot;template&amp;quot; text file.&lt;br /&gt;
&lt;br /&gt;
== Retired Projects ==&lt;br /&gt;
&lt;br /&gt;
These projects are no longer maintained and are only of limited use, e.g. because they work only with old Java versions.&lt;br /&gt;
&lt;br /&gt;
=== [[Loggifier.unkrig.de|Loggifier]] ===&lt;br /&gt;
: A tool for automatic injection of logging code into Java&amp;amp;trade; class files, making it unnecessary to mess up your code with hand-written logging.&lt;br /&gt;
&lt;br /&gt;
=== [[Cvstools.unkrig.de|Eclipse plug-in for extended CVS possibilities]] ===&lt;br /&gt;
&lt;br /&gt;
: An ECLIPSE plug-in that adds CVS functionality that is sometimes painfully missing from ECLIPSE&#039;s built-in CVS client.&lt;br /&gt;
&lt;br /&gt;
=== [[Subclipse.unkrig.de|Subclipse enhancements Eclipse plug-in]] ===&lt;br /&gt;
&lt;br /&gt;
: The often-missed &amp;lt;code&amp;gt;&amp;lt;de.unkrig.subclipse.svn&amp;gt;&amp;lt;/code&amp;gt; ANT task that uses the SUBCLIPSE client of the running ECLIPSE workbench.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://unkrig.de/w/index.php?title=MediaWiki:Mainpage&amp;diff=37</id>
		<title>MediaWiki:Mainpage</title>
		<link rel="alternate" type="text/html" href="https://unkrig.de/w/index.php?title=MediaWiki:Mainpage&amp;diff=37"/>
		<updated>2024-05-01T19:50:49Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;Unkrig.de&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Unkrig.de&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>