Mercurial > cgi-bin > hgweb.cgi > PassMan
diff src/main/kotlin/name/blackcap/passman/See.kt @ 3:eafa3779aef8
More bug fixes, quote strings in diagnostics.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 11 Sep 2022 20:36:06 -0700 |
parents | a6cfdffcaa94 |
children | 02b101422726 |
line wrap: on
line diff
--- a/src/main/kotlin/name/blackcap/passman/See.kt Sun Sep 11 18:24:55 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/See.kt Sun Sep 11 20:36:06 2022 -0700 @@ -1,56 +1,46 @@ package name.blackcap.passman +/* Would be nice if there was a more programmatic and comprehensive way of + doing this, but alas. Even the oft-recommended StringEscapeUtils does + something cruder than the below. Le sigh. */ + import java.util.Formatter -private val UNPRINTABLE = setOf<Character.UnicodeBlock>( - Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, - Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS_EXTENDED, - Character.UnicodeBlock.COMBINING_HALF_MARKS, - Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS_SUPPLEMENT, - Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, - Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, - Character.UnicodeBlock.HIGH_SURROGATES, - Character.UnicodeBlock.LOW_SURROGATES, - Character.UnicodeBlock.PRIVATE_USE_AREA, - Character.UnicodeBlock.SPECIALS, +private const val DELIM = '"' -) +private val STD_ESC_MAP = mapOf<Char, Char>('\t' to 't', '\b' to 'b', '\n' to 'n', + '\r' to 'r', '\u000c' to 'f', '\"' to '"', '\\' to '\\') +private const val MIN_ASCII = ' ' +private const val MAX_ASCII = '~' +private const val MIN_8859 = '\u00a1' +private const val MAX_8859 = '\u00ff' +private const val SHY = '\u00ad' -private val DELIM = '"' +fun see(input: String, simple: Boolean = false): String = + if (simple) seeSimple(input) else seeAggressive(input) -private val EXEMPT = setOf<Char>(' ') -private val PREFIXED = setOf<Char>(DELIM, '\\') +private fun seeSimple(input: String): String = StringBuilder().run { + append(DELIM) + append(input) + append(DELIM) + toString() +} -fun see(input: String): String { - val accum = StringBuilder() - val formatter = Formatter(accum) - accum.append(DELIM) +private fun seeAggressive(input: String): String { + val accum = Formatter() + accum.format("%c", DELIM) for (ch in input) { - val block = Character.UnicodeBlock.of(ch) - if (ch in EXEMPT) { - accum.append(ch) - } else if (block == null || block in UNPRINTABLE || Character.isSpaceChar(ch) || Character.isWhitespace(ch)) { - formatter.format("\\u%04x", ch.code) - } else if (ch in PREFIXED) { - accum.append('\\') - accum.append(ch) + if ((ch in MIN_ASCII..MAX_ASCII) || ((ch != SHY) && (ch in MIN_8859 .. MAX_8859))) { + accum.format("%c", ch) + continue + } + val mapped = STD_ESC_MAP[ch] + if (mapped != null) { + accum.format("\\%c", mapped) } else { - accum.append(ch) + accum.format("\\u%04x", ch.code) } } - accum.append(DELIM) + accum.format("%c", DELIM) return accum.toString() } - -fun dump(input: String): String { - val accum = StringBuilder() - var needSpace = false - for (ch in input) { - if (needSpace) { - accum.append(' ') - } - accum.append(ch.code) - needSpace = true - } - return accum.toString() -}