This morning I had an email from a blog subscriber ( Hi Rick! ) asking for a code tips on how to cleanup IFS file names to remove erroneous characters and/or malformed directory name slashes. Rather than reply with a plethora of programming options — here is an old, but functional, RPG code snippet that should help. 🙂
A looong time ago (in an office far far away) I faced a similar problem so decided to write a little RPGLE service program to give me some re-useable procedures to cleanup IFS file addresses.
In my case the users were asked to enter a file name in a green screen. What could go wrong? 😉
We all know that asking our users for a valid IFS File name is prone to spelling errors, syntax errors, finger slips and plain old end-user madness.
For example: Lets imagine an old IFS file that should be entered as /home/nick/myfile.cssv which is a lovely clean little file name.
In the real world, this could easily be entered as virtually any combination of keyboard whacks — /home\Nick//%¢&my file .CSV
While this file name might look reasonable to an end-user we (and when I say *we* I am referring to us propeller headed programming chaps and chappettes) know that the combination for front slashes, rear slashes and spaces in the file name might give us endless errors
So, I knocked up the #cleanifsfolder routine which basically switches everything to lower cases, removes duff characters, removes double spaces and replace spaces for underscores – obviously you can hack these rules to your heart’s delight.
Anyway, I’m waffling as usual, so lets just copy/paste the code:
// |
// | #CleanIFSfolder - Clean up the string to remove Duff Stuff! |
// |
// | Remove duff characters from parm and then use a cheeky little do loop to
// | squish it up so if this programs is passed a value of 'this is A file%¢&NaMe PlOp'
// |
// | The results will be calculated like this:
// | starting 1. '/this is A file%¢&/NaMe PlOp'
// | strip duff 2. '/this is A file /NaMe PlOp'
// | lower 3. '/this is a file /name plop'
// | SquishSingle 4. '/this is a file/name plop'
// |
dcl-proc #CleanIFSfolder export;
dcl-pi #CleanIFSfolder char(1024);
ParmIfsFolder char(1024) const;
end-pi;
dcl-s NeedsSquishing ind inz(*off);
dcl-c @Dirty const('\,¢!~`?%&*<>()+"|:;'); // naughty characters edit this to your needs
dcl-c @Clean const('/ ');
dcl-s cleanIfsFolder char(1024);
// Load up work field with the input value
clear cleanIfsFolder;
cleanIfsFolder = %subst(ParmIfsFolder:1:%Len(ParmIfsFolder));
If cleanIfsFolder <> *blanks;
// Clean out any duff characters and switch to *blanks
cleanIfsFolder = %Xlate(@Dirty:@Clean:cleanIfsFolder );
cleanIfsFolder = %Xlate(@quoteMark:@blank:cleanIfsFolder);
// Make sure we only have forward slashes
cleanIfsFolder = #LeanForward ( cleanIfsFolder );
// make it all lower case to be neat
cleanIfsFolder = #lowercase ( cleanIfsFolder );
// Squish out any multiple blanks
cleanIfsFolder = #SquishSingle ( cleanIfsFolder );
// Append '/' to the end
cleanIfsFolder = %trim(cleanIfsFolder) + '/';
// underscore it to make it look saucy
cleanIfsFolder = #underscoreIt ( cleanIfsFolder );
// change any accidental double forward-slashes to singles
Dow %Scan('//': %trimR(cleanIfsFolder )) > *Zeros;
NeedsSquishing = *on;
cleanIfsFolder = %Replace('/':cleanIfsFolder:%Scan('//':%trimR(cleanIfsFolder )): 2);
EndDo;
// Squish out any blanks again after double thing
if NeedsSquishing;
cleanIfsFolder = #SquishSingle ( cleanIfsFolder );
Endif;
Endif;
Return cleanIfsFolder ;
end-proc;
// +----------------------------------------------------------------+
// | #LeanForward - Fix the Forward lash to backslash debacle |
// +----------------------------------------------------------------+
dcl-proc #LeanForward export;
dcl-pi #LeanForward char(1024);
p_Data char(1024) const;
end-pi;
dcl-s $SlashData char(1024);
$SlashData = %subst(p_Data:1:%Len(p_Data));
// Replace any LESS THAN or GREATER THAN Chevrons with UNDERSCORE
$SlashData = %Xlate( '\':'/':$SlashData);
Return $SlashData;
end-proc;
// +-----------------------------------------------------------+
// | #SQUISHSINGLE - Squish together leaving ONE single space |
// +-----------------------------------------------------------+
dcl-proc #SquishSingle export;
dcl-pi #SquishSingle char(1024);
p_Data char(1024) const;
end-pi;
dcl-s $Squishey like(p_Data);
// Load up work field with the input value
$Squishey = %subst(p_Data:1:%Len(p_Data));
// replace all double blanks with a single one
Dow %Scan(' ':%trimR($Squishey)) > *Zeros;
$Squishey = %Replace(' ':$Squishey:%Scan(' ':%trimR($Squishey)):2);
EndDo;
$BigVariable = %trim($Squishey);
Return $BigVariable;
end-proc;
// +-------------------------------------------------+
// | #UnderScoreIt - switch spaces to underscores |
// | 1. 'this is a file name plop ' |
// | 2. 'this_is_a_file_name_plop ' |
// +-------------------------------------------------+
dcl-proc #UnderScoreIt export;
dcl-pi #UnderScoreIt like($bigvariable);
p_Data like($bigvariable) const;
end-pi;
dcl-s clnVariable like(p_Data);
clnVariable = %subst(p_Data:1:%Len(p_Data));
clnVariable = %Xlate(@blank:@underScore:%trim(clnVariable));
// Replace Double UNDERSCORES with Singles
Dow %Scan('__': %trimR(clnVariable )) > *Zeros;
clnVariable = %Replace(@underScore:clnVariable:%Scan('__':%trimR(clnVariable)): 2);
EndDo;
// check for any left behind
Dow %Scan('_ ':clnVariable ) > *Zeros;
clnVariable = %Replace(' ':clnVariable:%Scan('_ ':clnVariable ): 2);
EndDo;
Return clnVariable;
end-proc;
// +---------------------------------------------------------+
// | #lowercase - purpose:convert text to lower case. |
// | input:text data |
// | Returns:lower case text data |
// +---------------------------------------------------------+
dcl-proc #LowerCase export;
dcl-pi #LowerCase like($bigvariable);
ParmInput like($bigvariable) const;
end-pi;
dcl-s lowercaseWaffle like($bigvariable);
EXEC SQL
SET :lowercaseWaffle = lower(:ParmInput);
Return lowercaseWaffle;
end-proc;
// +---------------------------------------------------------+
// | #uppercase - purpose:convert text to upper case. |
// | input:text data |
// | Returns:upper case text data |
// +---------------------------------------------------------+
dcl-proc #UpperCase export;
dcl-pi #UpperCase like($bigvariable);
ParmInput like($bigvariable) const;
end-pi;
dcl-s upperCaseWaffle like($bigvariable);
EXEC SQL
SET :upperCaseWaffle = UPPER(:ParmInput);
Return upperCaseWaffle;
end-proc;
Be gentle with me….
These code snippets are from over a decade ago, I’m sure there are some super simple SQL way of doing this nowadays.
But hopefully they will be useful…

Hi Nick
I’ve just read a good article about clearing messy IFS files. Thank you for sharing your experience. I am right that utility you published there has nothing with reading IFS directory ( possibly containing the files with messing names ) but just cleans the file name specified as the parameter ?
Hi Nick
I’ve returned again to your code – it really nice not for those “old” time but for our modern time too… It seems me that you occasionally dropped the definition for “@quoteMark” variable mentioned in the beginning of your code. Can you please update it ? ( do you mean it was an single apostrophe value ? )