Search code examples
clojure

Toggle case sensitivity for a huge chunk of Clojure code


There is a large chunk of code (mostly not mine) that does the following with user input (that is more or less, space separated list of commands with some arguments/options):

  1. Remove all unsupported characters
  2. Split on space into a vector
  3. Recursively apply first item in vector on the rest of the vector (function uses whatever arguments it needs, and returns vector without itself and its arguments to the loop).

Functions themselves, as far as input is concerned, have a mix of (case), (cond), (condp), (=) and (compare) with some nasty (keyword) comparisons mixed in.

Everyone was fine with the fact that this all is strictly case-sensitive until very recently. Now some (previously unknown) ancient integration bits acting as users appeared and are having some casing issues that I have no control over.

Question: is there a viable way (shortcut before there will be more time to redo it all) to make string comparison case insensitive for some sort of a scope, based on some variable?

I considered 3 options:

  1. Fixing the code (will be done sometime, anyway, but not viable at the moment).
  2. Extracting some low level comparison function (hopefully just one) and rebinding it for the local scope (sounds great, but catching cases might be difficult and error-prone).
  3. Standardize input (might not be possible without some hacks since some data, outside comparisons, NEEDS to be case sensitive).

After some research, the answer is probably no (and planning for major changes should start), but I figured asking would not hurt, maybe someone thought of it before.

Edit: sample problematic input:

"Command1 ARG1 aRG2 Command3 command9 Arg4 Arg9 aRg5 COMMAND4 arg8"

Breaking it down: "Commands" with broken case I need to be able, on demand, to match case insensitively. Arguments are matched case insensitively on another level - so they do not concern this piece of code, but their case inside this bit of code should be preserved to be sent further along. NB! It is not possible at the start of the processing to tell what is in the input a command and what is argument.


Solution

    1. As per Alan Thompson's comment, str/lower-case was the right first half of approach - I just needed to find the right place to apply it to just command name.

    2. Afterwards redefining = and couple of functions used inside cond and condp (credit to ClojureMostly) solved the matching part.

    3. All that was left were the string literals inside case statements which I just find-and-replaced with lower case.