All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax0.jamal.tools.param.Escape Maven / Gradle / Ivy

package javax0.jamal.tools.param;

import javax0.jamal.api.BadSyntax;
import javax0.jamal.api.Input;

class Escape {
    private static char octal(Input input, int maxLen) {
        int i = maxLen;
        int occ = 0;
        while (i > 0 && input.length() > 0 && input.charAt(0) >= '0' && input.charAt(0) <= '7') {
            occ = 8 * occ + input.charAt(0) - '0';
            input.deleteCharAt(0);
            i--;
        }
        return (char) occ;
    }

    private static final String escapes = "btnfr\"'\\";
    private static final String escaped = "\b\t\n\f\r\"'\\";

    /**
     * Handle the escape sequence. The escape sequence is
     *
     * 
    *
  • backslash and a 'b', 't', 'n', 'f', 'r', '"', '\' or an apostrophe, or
  • *
  • backslash and 2 or 3 octal characters.
  • *
* * @param input the input string * @param output the output string where the escaped character is appended * @throws BadSyntax if the escape sequence is invalid */ static void handleEscape(Input input, StringBuilder output) throws BadSyntax { input.deleteCharAt(0); BadSyntax.when(input.length() == 0, "Source ended inside a string."); final var nextCh = input.charAt(0); final int esindex = escapes.indexOf(nextCh); if (esindex == -1) { if (nextCh >= '0' && nextCh <= '3') { output.append(octal(input, 3)); } else if (nextCh >= '4' && nextCh <= '7') { output.append(octal(input, 2)); } else { throw new BadSyntax("Invalid escape sequence in string: \\" + nextCh); } } else { output.append(escaped.charAt(esindex)); input.deleteCharAt(0); } } static void handleNormalCharacter(Input input, StringBuilder output) throws BadSyntax { final char ch = input.charAt(0); BadSyntax.when(ch == '\n' || ch == '\r', () -> String.format("String not terminated before eol:\n%s...", input.substring(1, Math.min(input.length(), 60)))); output.append(ch); input.deleteCharAt(0); } static void handleNormalMultiLineStringCharacter(Input input, StringBuilder output) { char ch = input.charAt(0); if (ch == '\n' || ch == '\r') { normalizedNewLines(input, output); } else { output.append(ch); input.deleteCharAt(0); } } /** *

Convert many subsequent {@code \n} and {@code \r} characters to {@code \n} only. There will be as many {@code * \n} characters in the output as many there were in the input and the {@code \r} characters are simply ignored. * The only exception is, when there are no {@code \n} characters. In this case there will be one {@code \n} in the * output for all the {@code \r} characters.

* *

The method deletes the characters from the start of the input {@code input} and append the output * to the {@code output}. The original characters will be appended to the end of {@code original} without any * conversion.

* * @param input the input, from which the characters are consumed. * @param output where the converted newline(s) are appended to */ private static void normalizedNewLines(Input input, StringBuilder output) { char ch = input.charAt(0); int countNewLines = 0; while (input.length() > 0 && (ch == '\n' || ch == '\r')) { if (ch == '\n') { countNewLines++; } input.deleteCharAt(0); if (input.length() > 0) { ch = input.charAt(0); } } // if there was a single, or multiple \r without any \n if (countNewLines == 0) { countNewLines++; } output.append("\n".repeat(countNewLines)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy