Interface Model.ShellAdapter

All Known Implementing Classes:
Model.Pre20220613, Model.SeemsToWorkForLinuxAndSomeWindowsVersions20220613
Enclosing class:
Model<M extends Model>

static interface Model.ShellAdapter
Adapter for different shell behaviour when passing options by command line. Any Java application is called from a command line by executing a method . The array of strings args[] contains the user's input line, tokenized (=splitted the input sub-strings) by the shell. This is only historically relevant and an ennoying legacy. It is nowadaays only relevent for (a) encoding empty strings and (b) encoding strings which contain blanks.

Most shells act as follows: (1) All sequences of unescaped whitespace in the command line are translated into the break between arg[n] and arg[n+1].
(2) All characters enclosed in double quotes (whether whitespace or not) are put into one single arg[n].
(2b) The double quotes are not taken over into arg[n]. So the input yields .
(3) All whitespace charactes escaped by a preceding backslash are not translated according to (1) but appear as whitespace in the contents of an arg[n].
(4) It may be that these double quotes also limit the extension of the arg[n] (= the contained characters are the ONLY contents of arg[n]), or that rule (1) is applied independently after rule (2), which means that "a b"cd forms one single arg[n] containing »a bc«
(4) Rule (2) may also apply to single quotes. (5) Double quote characters to be included in a double-quoted string (=meant to appear in the contents of arg[n]) must be escaped by a preceding backslash character.

Serialization is employed for documentation, persistency, error messages, etc. Most uses cases are independent of any shell (e.g. documenting the parametrization of the tool in the generated text output; collecting different payload tasks by a list of serialized option models in a Gui). Nevertheless, a human reader is involved who possibly exprects a particular shell implmementation. Thus serialization must be pluggable in all use cases (except purely internal persistency).
In this implementation escaped strings are only allowed at argument positions. You can write "--option "-3" -2", but not " "--option" -3".

Use serialization for parsing is not necessary: An older version simply concatenated all arg[n] separated by one single blank, escaped each contained blank by a backslash and parsed two consecutive blanks as one empty string argument. But to make error messaging more sensible to the user, it is also employed for the contents of the arg[n]. Therefore the implementation of Model.getNextToken() is specific and must also be provided.

  • Method Summary

    Modifier and Type
    Method
    Description
    If the argument value contains whitespace or double quotes, it must be escaped when integrated into a serialization.
    int
    Delivers the start of the last successful match.
    testNextToken(Matcher matcher, int inputlen)
    Parse and return the next argument value.
  • Method Details

    • serializeToArgsString

      String serializeToArgsString(String s)
      If the argument value contains whitespace or double quotes, it must be escaped when integrated into a serialization. It is only assumed that this function is only called (and only necessary) for argument values of String type.
    • testNextToken

      @Opt @Opt String testNextToken(Matcher matcher, int inputlen)
      Parse and return the next argument value. The serialized input, the Model.matcher is looking at, will be translated into the internal form (ie. blanks will be unescaped, empty strings stripped from quotation marks, etc.) Internal matcher registers will be advanced (thus no more reflecting this match!) and the translated character data is copied inot Model.nextToken. The realization by the sub-classes must use a regex-Pattern which accepts ALL non-whitespace input and returns null only when the end of the input stream (discarding whitespace) is reached.
      Parameters:
      matcher - is prepared and looking at the current parsing position of the input string.
    • startOfLastMatch

      int startOfLastMatch()
      Delivers the start of the last successful match. May only be called immediately after a call to testNextToken(Matcher,int) with result != null.