SCP: Add whitespace ignore option to file and string content comparisons

This commit is contained in:
Mark Pizzolato 2020-11-01 16:27:47 -08:00
parent 462f5a51b8
commit f9ce5ae8ff
2 changed files with 109 additions and 11 deletions

Binary file not shown.

104
scp.c
View file

@ -2347,8 +2347,11 @@ static const char simh_help2[] =
" file. Otherwise, the next command in the command file is processed.\n\n"
"5String Comparison Expressions\n"
" String Values can be compared with:\n"
"++{-i} {NOT} \"<string1>\"|EnVarName1 <compare-op> \"<string2>|EnvVarName2\"\n\n"
"++{-i}{-w} {NOT} \"<string1>\"|EnVarName1 <compare-op> \"<string2>|EnvVarName2\"\n\n"
" The -i switch, if present, causes comparisons to be case insensitive.\n"
" The -w switch, if present, causes comparisons to allow arbitrary runs of\n"
" whitespace to be equivalent to a single space.\n"
" The -i and -w switches may be combined.\n"
" <string1> and <string2> are quoted string values which may have\n"
" environment variables substituted as desired.\n"
" Either quoted string may alternatively be an environment variable name.\n"
@ -2376,9 +2379,11 @@ static const char simh_help2[] =
" Specifies a true (false {NOT}) condition if the file exists.\n"
"5File Comparison Expressions\n"
" Files can have their contents compared with:\n\n"
"++-F {NOT} \"<filespec1>\" == \"<filespec2>\" \n\n"
"++-F{W} {NOT} \"<filespec1>\" == \"<filespec2>\" \n\n"
" Specifies a true (false {NOT}) condition if the indicated files\n"
" have the same contents.\n\n"
" have the same contents. If the -W switch is present, allows\n"
" arbitrary runs of whitespace to be considered a single space\n"
" during file content comparison.\n\n"
" When a file comparison determines that files are different, the environment\n"
" variable _FILE_COMPARE_DIFF_OFFSET is set to the file offset where the first\n"
" difference in the files was observed\n\n"
@ -4608,9 +4613,42 @@ if (sim_switches & SWMASK ('F')) { /* File Compare? */
fclose (f1);
return 1;
}
if (sim_switches & SWMASK ('W')) { /* whitespace runs equivalent? */
c1 = c2 = 0;
while ((c1 == c2) && (c1 != EOF)) {
if (c1 == ' ') { /* last character was space? */
while (c1 == ' ') { /* read until not a space */
c1 = fgetc (f1);
++diff_offset;
if (sim_isspace (c1))
c1 = ' '; /* all whitespace is a space */
}
}
else { /* get new character */
c1 = fgetc (f1);
++diff_offset;
if (sim_isspace (c1))
c1 = ' '; /* all whitespace is a space */
}
if (c2 == ' ') { /* last character was space? */
while (c2 == ' ') { /* read until not a space */
c2 = fgetc (f2);
if (sim_isspace (c2))
c2 = ' '; /* all whitespace is a space */
}
}
else { /* get new character */
c2 = fgetc (f2);
if (sim_isspace (c2))
c2 = ' '; /* all whitespace is a space */
}
};
}
else { /* Binary File Compare */
while (((c1 = fgetc (f1)) == (c2 = fgetc (f2))) &&
(c1 != EOF))
++diff_offset;
}
fclose (f1);
fclose (f2);
if (c1 != c2) {
@ -9978,6 +10016,64 @@ while (1) {
return 0;
}
int sim_strwhitecasecmp (const char *string1, const char *string2, t_bool casecmp)
{
unsigned char s1 = 1, s2 = 1; /* start with equal, but not space */
while ((s1 == s2) && (s1 != '\0')) {
if (s1 == ' ') { /* last character was space? */
while (s1 == ' ') { /* read until not a space */
s1 = *string1++;
if (sim_isspace (s1))
s1 = ' '; /* all whitespace is a space */
else {
if (casecmp)
s1 = (unsigned char)sim_toupper (s1);
}
}
}
else { /* get new character */
s1 = *string1++;
if (sim_isspace (s1))
s1 = ' '; /* all whitespace is a space */
else {
if (casecmp)
s1 = (unsigned char)sim_toupper (s1);
}
}
if (s2 == ' ') { /* last character was space? */
while (s2 == ' ') { /* read until not a space */
s2 = *string2++;
if (sim_isspace (s2))
s2 = ' '; /* all whitespace is a space */
else {
if (casecmp)
s2 = (unsigned char)sim_toupper (s2);
}
}
}
else { /* get new character */
s2 = *string2++;
if (sim_isspace (s2))
s2 = ' '; /* all whitespace is a space */
else {
if (casecmp)
s2 = (unsigned char)sim_toupper (s2);
}
}
if (s1 == s2) {
if (s1 == 0)
return 0;
continue;
}
if (s1 < s2)
return -1;
if (s1 > s2)
return 1;
}
return 0;
}
/* strlcat() and strlcpy() are not available on all platforms */
/* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> */
/*
@ -15055,6 +15151,8 @@ return data2 > data1;
static int _i_strcmp (const char *s1, const char *s2)
{
if (sim_switches & SWMASK ('W')) /* Whitespace compress? */
return sim_strwhitecasecmp (s1, s2, sim_switches & SWMASK ('I'));
return ((sim_switches & SWMASK ('I')) ? strcasecmp (s2, s1) : strcmp (s2, s1));
}