diff --git a/doc/simh_doc.doc b/doc/simh_doc.doc index 6a13325b..8edf3403 100644 Binary files a/doc/simh_doc.doc and b/doc/simh_doc.doc differ diff --git a/scp.c b/scp.c index c496ad94..ce0a8254 100644 --- a/scp.c +++ b/scp.c @@ -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} \"\"|EnVarName1 \"|EnvVarName2\"\n\n" + "++{-i}{-w} {NOT} \"\"|EnVarName1 \"|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" " and 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} \"\" == \"\" \n\n" + "++-F{W} {NOT} \"\" == \"\" \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" @@ -3735,11 +3740,11 @@ if ((*cptr == '"') || (*cptr == '\'')) { cptr = (char *)dbuf; } if (lp) { - tmxr_linemsgf (lp, "%s%s", cptr, (sim_switches & SWMASK('N')) ? "" : "\r\n"); + tmxr_linemsgf (lp, "%s%s", cptr, (sim_switches & SWMASK ('N')) ? "" : "\r\n"); tmxr_send_buffered_data (lp); } else - sim_printf ("%s%s", cptr, (sim_switches & SWMASK('N')) ? "" : "\n"); + sim_printf ("%s%s", cptr, (sim_switches & SWMASK ('N')) ? "" : "\n"); return SCPE_OK; } @@ -4608,9 +4613,42 @@ if (sim_switches & SWMASK ('F')) { /* File Compare? */ fclose (f1); return 1; } - while (((c1 = fgetc (f1)) == (c2 = fgetc (f2))) && - (c1 != EOF)) - ++diff_offset; + 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) { @@ -7445,7 +7483,7 @@ for (i = 0; i < start; i++) { } for (i = start; (dptr = sim_devices[i]) != NULL; i++) { sim_switches = saved_sim_switches; /* restore initial switches */ - if (sim_switches & SWMASK('P')) { + if (sim_switches & SWMASK ('P')) { tmxr_add_debug (dptr); /* Add TMXR debug to MUX devices */ sim_tape_add_debug (dptr); /* Add TAPE debug to TAPE devices */ } @@ -8891,7 +8929,7 @@ if ((dptr != NULL) && (dptr->examine != NULL)) { } if ((r == SCPE_OK) || (i > 0)) { fprintf (st, " ("); - if (fprint_sym (st, (t_addr) pcval, sim_eval, NULL, SWMASK('M')|SIM_SW_STOP) > 0) + if (fprint_sym (st, (t_addr) pcval, sim_eval, NULL, SWMASK ('M') | SIM_SW_STOP) > 0) fprint_val (st, sim_eval[0], dptr->dradix, dptr->dwidth, PV_RZRO); fprintf (st, ")"); } @@ -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 */ /* @@ -15055,7 +15151,9 @@ return data2 > data1; static int _i_strcmp (const char *s1, const char *s2) { -return ((sim_switches & SWMASK('I')) ? strcasecmp (s2, s1) : strcmp (s2, s1)); +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)); } static t_svalue _op_str_eq (const char *str1, const char *str2)