From 11c3a68e359dd7837a5f6b1d763c1b2aeebdd4de Mon Sep 17 00:00:00 2001 From: Bruce Korb Date: Wed, 28 Jan 2015 20:21:34 +0000 Subject: [PATCH] checksums and test-text * fixincl.tpl: add a check sum acceptance test * fixlib.h: enumerate it * fixincl.c: handle it * README: document it and document the handling of test_text From-SVN: r220215 --- fixincludes/ChangeLog | 15 ++++ fixincludes/README | 44 +++++------ fixincludes/fixincl.c | 159 ++++++++++++++++++++++++++++------------ fixincludes/fixincl.tpl | 83 +++++++++++++-------- fixincludes/fixincl.x | 8 +- fixincludes/fixlib.h | 2 +- 6 files changed, 208 insertions(+), 103 deletions(-) diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog index 571b6d17f60..afed2f8fd22 100644 --- a/fixincludes/ChangeLog +++ b/fixincludes/ChangeLog @@ -1,3 +1,18 @@ +2015-01-24 Bruce Korb + + * README: add some clarification on use of test_text + +2014-12-21 Bruce Korb + + * fixincludes/fixincl.tpl: add handling for "sum" selection + criteria and clean up layout + * fixincludes/fixlib.h: enumerate TT_CKSUM test type + * fixincludes/fixincl.c (fix_applies): add code to handle + the new test type + (cksum_test): function to handle it + * fixincludes/README: doc it and remove explanations from + more than a decade ago. + 2014-12-15 Uros Bizjak * server.c (server_setup): Check return value of diff --git a/fixincludes/README b/fixincludes/README index 3e4e63f4a78..98480165d10 100644 --- a/fixincludes/README +++ b/fixincludes/README @@ -1,24 +1,4 @@ -FIXINCLUDES OPERATION -===================== - -See also: http://autogen.SourceForge.net/fixinc.html - -The set of fixes required was distilled down to just the data required -to specify what needed to happen for each fix. Those data were edited -into a file named fixincludes/inclhack.def. A program called AutoGen -(http://autogen.SourceForge.net) uses these definitions to instantiate -several different templates that then produces code for a fixinclude -program (fixincl.x) and a shell script to test its functioning. On -certain platforms (viz. those that do not have functional bidirectional -pipes), the fixincl program is split into two. This should only concern -you on DOS and BeOS. - -Regards, - Bruce - - - GCC MAINTAINER INFORMATION ========================== @@ -48,6 +28,15 @@ To make your fix, you will need to do several things: There is no real possibility that these fixes will fail. If they do, you will surely know straight away. + NOTE: "test_text" is interpreted by the shell as it gets + copied into the test header. THEREFORE you must quote + dollar sign characters and back quotes -- unless you mean + for them to be interpreted by the shell. + + e.g. the math_huge_val_from_dbl_max test_text needs to + put text into both float.h and math.h, so it includes a + back-quoted script to add text to float.h. + 5. Go into the fixincludes build directory and type, "make check". You are guaranteed to have issues printed out as a result. Look at the diffs produced. Make sure you have not clobbered @@ -82,7 +71,7 @@ MAKING CHANGES TO INCLHACK.DEF 3. It is relatively expensive to fire off a process to fix a source file, therefore write apply tests to avoid unnecessary fix processes. The preferred apply tests are "select", "bypass", "mach" - and "c-test" because they are performed internally: + "sum", and "c-test" because they are performed internally: * select - Run a regex on the contents of the file being considered. All such regex-es must match. Matching is done with @@ -91,6 +80,19 @@ MAKING CHANGES TO INCLHACK.DEF * bypass - Run a regex on the contents of the file being considered. No such regex may match. + * sum - Select a specific version of a file that has a matching + check sum. The BSD version of checksum ["sum(1BSD)"] + is used. Each "sum" entry should contain exactly three + space separated tokens: the sum, some number and the + basename of the file. The "some number" is ignored. + If there are multiple "sum" entries, only one needs to + match in order to pass. For example: + + sum = '1234 3 foobar.h'; + + specifies that the "foobar.h" header in any directory + will match if it has the checksum 1234. + * c_test - call a function in fixtests.c. See that file. * files - the "fnmatch" pattern of the file(s) to examine for diff --git a/fixincludes/fixincl.c b/fixincludes/fixincl.c index 5a113c65b36..16e77eec267 100644 --- a/fixincludes/fixincl.c +++ b/fixincludes/fixincl.c @@ -597,6 +597,63 @@ egrep_test (char* pz_data, tTestDesc* p_test) return SKIP_FIX; } +/* * * * * * * * * * * * * + + cksum_test check the sum of the candidate file + Input: the original file contents and the file name + Result: APPLY_FIX if the check sum matches, SKIP_FIX otherwise + + The caller may choose to reverse meaning if the sense of the test + is inverted. */ + +static int +cksum_test (char * pz_data, tTestDesc * p_test, char * fname) +{ + unsigned int cksum; + + /* + * Testing is off in normal operation mode. + * So, in testing mode, APPLY_FIX is always returned. + */ + if (fixinc_mode != TESTING_OFF) + return APPLY_FIX; + + { + char * fnm = strrchr(fname, '/'); + if (fnm != NULL) + fname = fnm + 1; + + errno = 0; + cksum = (unsigned int)strtoul(p_test->pz_test_text, &fnm, 10); + if (errno != 0) + return SKIP_FIX; + + if (! ISSPACE(*fnm++)) + return SKIP_FIX; + while (ISSPACE(*fnm)) fnm++; + + if (! ISDIGIT(*fnm++)) + return SKIP_FIX; + while (ISDIGIT(*fnm)) fnm++; + + if (! ISSPACE(*fnm++)) + return SKIP_FIX; + while (ISSPACE(*fnm)) fnm++; + + if (strcmp(fnm, fname) != 0) + return SKIP_FIX; + } + + { + unsigned int sum = 0; + while (*pz_data != NUL) { + sum = (sum >> 1) + ((sum & 1) << 15) + (unsigned)(*pz_data++); + sum &= 0xFFFF; + } + + return (sum == cksum) ? APPLY_FIX : SKIP_FIX; + } +} /* * * * * * * * * * * * * @@ -794,7 +851,7 @@ fix_with_system (tFixDesc* p_fixd, if (p_fixd->fd_flags & FD_SUBROUTINE) { static const char z_applyfix_prog[] = - "/../fixincludes/applyfix" EXE_EXT; + "/../fixincludes/applyfix" EXE_EXT; struct stat buf; argsize = 32 @@ -812,12 +869,12 @@ fix_with_system (tFixDesc* p_fixd, strcpy (pz_scan, z_applyfix_prog); /* IF we can't find the "applyfix" executable file at the first guess, - try one level higher up */ + try one level higher up */ if (stat (pz_cmd, &buf) == -1) - { - strcpy (pz_scan, "/.."); - strcpy (pz_scan+3, z_applyfix_prog); - } + { + strcpy (pz_scan, "/.."); + strcpy (pz_scan+3, z_applyfix_prog); + } pz_scan += strlen (pz_scan); @@ -825,7 +882,7 @@ fix_with_system (tFixDesc* p_fixd, * Now add the fix number and file names that may be needed */ sprintf (pz_scan, " %ld '%s' '%s' '%s'", (long) (p_fixd - fixDescList), - pz_fix_file, pz_file_source, pz_temp_file); + pz_fix_file, pz_file_source, pz_temp_file); } else /* NOT an "internal" fix: */ { @@ -899,25 +956,25 @@ fix_with_system (tFixDesc* p_fixd, for (;;) { tCC* pArg = *(ppArgs++); - char* pz_scan_save; + char* pz_scan_save; if (pArg == NULL) break; *(pz_scan++) = ' '; pz_scan = make_raw_shell_str( pz_scan_save = pz_scan, pArg, - parg_size - (pz_scan - pz_cmd) ); - /* - * Make sure we don't overflow the buffer due to sloppy - * size estimation. - */ - while (pz_scan == (char*)NULL) - { - size_t already_filled = pz_scan_save - pz_cmd; - pz_cmd = xrealloc (pz_cmd, argsize += 100); - pz_scan_save = pz_scan = pz_cmd + already_filled; - parg_size += 100; - pz_scan = make_raw_shell_str( pz_scan, pArg, - parg_size - (pz_scan - pz_cmd) ); - } + parg_size - (pz_scan - pz_cmd) ); + /* + * Make sure we don't overflow the buffer due to sloppy + * size estimation. + */ + while (pz_scan == (char*)NULL) + { + size_t already_filled = pz_scan_save - pz_cmd; + pz_cmd = xrealloc (pz_cmd, argsize += 100); + pz_scan_save = pz_scan = pz_cmd + already_filled; + parg_size += 100; + pz_scan = make_raw_shell_str( pz_scan, pArg, + parg_size - (pz_scan - pz_cmd) ); + } } /* @@ -960,7 +1017,7 @@ start_fixer (int read_fd, tFixDesc* p_fixd, char* pz_fix_file) { tSCC z_cmd_fmt[] = "file='%s'\n%s"; pz_cmd = XNEWVEC (char, strlen (p_fixd->patch_args[2]) - + sizeof (z_cmd_fmt) + strlen (pz_fix_file)); + + sizeof (z_cmd_fmt) + strlen (pz_fix_file)); sprintf (pz_cmd, z_cmd_fmt, pz_fix_file, p_fixd->patch_args[2]); pz_cmd_save = p_fixd->patch_args[2]; p_fixd->patch_args[2] = pz_cmd; @@ -1007,7 +1064,15 @@ start_fixer (int read_fd, tFixDesc* p_fixd, char* pz_fix_file) return read_fd; } #endif - +#ifdef DEBUG +# define NOTE_SKIP(_ttyp) do { \ + if (VLEVEL( VERB_EVERYTHING )) \ + fprintf (stderr, z_failed, _ttyp, p_fixd->fix_name, \ + pz_fname, p_fixd->test_ct - test_ct); \ + } while (0) +#else +# define NOTE_SKIP(_ttyp) +#endif /* * * * * * * * * * * * * * @@ -1022,6 +1087,8 @@ fix_applies (tFixDesc* p_fixd) const char *pz_scan = p_fixd->file_list; int test_ct; tTestDesc *p_test; + t_bool saw_sum_test = BOOL_FALSE; + t_bool one_sum_passed = BOOL_FALSE; #ifdef SEPARATE_FIX_PROC /* @@ -1055,6 +1122,7 @@ fix_applies (tFixDesc* p_fixd) } /* FOR each test, see if it fails. + "sum" fails only if all "sum" tests fail. IF it does fail, then we go on to the next test */ for (p_test = p_fixd->p_test_desc, test_ct = p_fixd->test_ct; @@ -1065,52 +1133,51 @@ fix_applies (tFixDesc* p_fixd) { case TT_TEST: if (test_test (p_test, pz_curr_file) != APPLY_FIX) { -#ifdef DEBUG - if (VLEVEL( VERB_EVERYTHING )) - fprintf (stderr, z_failed, "TEST", p_fixd->fix_name, - pz_fname, p_fixd->test_ct - test_ct); -#endif + NOTE_SKIP("TEST"); return BOOL_FALSE; } break; case TT_EGREP: if (egrep_test (pz_curr_data, p_test) != APPLY_FIX) { -#ifdef DEBUG - if (VLEVEL( VERB_EVERYTHING )) - fprintf (stderr, z_failed, "EGREP", p_fixd->fix_name, - pz_fname, p_fixd->test_ct - test_ct); -#endif + NOTE_SKIP("EGREP"); return BOOL_FALSE; } break; case TT_NEGREP: if (egrep_test (pz_curr_data, p_test) == APPLY_FIX) { -#ifdef DEBUG - if (VLEVEL( VERB_EVERYTHING )) - fprintf (stderr, z_failed, "NEGREP", p_fixd->fix_name, - pz_fname, p_fixd->test_ct - test_ct); -#endif + NOTE_SKIP("NEGREP"); /* Negated sense */ return BOOL_FALSE; } break; + case TT_CKSUM: + if (one_sum_passed) + break; // no need to check any more. + + saw_sum_test = BOOL_TRUE; + if (cksum_test (pz_curr_data, p_test, pz_curr_file) != APPLY_FIX) { + NOTE_SKIP("CKSUM"); + } else { + one_sum_passed = BOOL_TRUE; + } + break; + case TT_FUNCTION: if (run_test (p_test->pz_test_text, pz_curr_file, pz_curr_data) != APPLY_FIX) { -#ifdef DEBUG - if (VLEVEL( VERB_EVERYTHING )) - fprintf (stderr, z_failed, "FTEST", p_fixd->fix_name, - pz_fname, p_fixd->test_ct - test_ct); -#endif + NOTE_SKIP("FTEST"); return BOOL_FALSE; } break; } } + if (saw_sum_test) + return one_sum_passed; + return BOOL_TRUE; } @@ -1185,7 +1252,7 @@ test_for_changes (int read_fd) /* IF there are matched data, write the matched part now. */ if ((char*)pz_cmp != pz_curr_data) fwrite (pz_curr_data, (size_t)((char*)pz_cmp - pz_curr_data), - 1, out_fp); + 1, out_fp); /* Emit the current unmatching character */ putc (ch, out_fp); @@ -1248,7 +1315,7 @@ process (void) #endif if (VLEVEL( VERB_PROGRESS ) && have_tty) fprintf (stderr, "%6lu %-50s \r", - (unsigned long) data_map_size, pz_curr_file); + (unsigned long) data_map_size, pz_curr_file); # ifndef SEPARATE_FIX_PROC process_chain_head = NOPROCESS; diff --git a/fixincludes/fixincl.tpl b/fixincludes/fixincl.tpl index c8d4b2ce145..5096a8246f3 100644 --- a/fixincludes/fixincl.tpl +++ b/fixincludes/fixincl.tpl @@ -1,6 +1,9 @@ [= AutoGen5 Template -*- Mode: C -*- x=fixincl.x =] -[= (dne " * " "/* ")=] +[= + (if (version-compare >= autogen-version "5.18") + (dne "-D" " * " "/* ") + (dne " * " "/* ") ) =] */ /* DO NOT SVN-MERGE THIS FILE, EITHER [= (define re-ct 0) (define max-mach 0) (define ct 0) @@ -63,32 +66,32 @@ tSCC z[=(. Hack)=]Name[] = * File name selection pattern */[= - IF (exist? "files")=] + IF (exist? "files") =] tSCC z[=(. Hack)=]List[] = "[= (join "\\0" (stack "files")) =]\0";[= - ELSE =] + ELSE =] #define z[=(. Hack)=]List (char*)NULL[= ENDIF (exist? "files") =] /* * Machine/OS name selection pattern */[= - IF (exist? "mach")=] + IF (exist? "mach") =] tSCC* apz[=(. Hack)=]Machs[] = {[= (set! ct 0) =][= - FOR mach =] + FOR mach =] [= (set! tmp (get "mach")) (set! ct (+ ct (string-length tmp) 5)) (kr-string tmp)=],[= - ENDFOR=] + ENDFOR =] (const char*)NULL };[= (if (> ct max-mach) (set! max-mach ct)) =][= - ELSE =] + ELSE =] #define apz[=(. Hack)=]Machs (const char**)NULL[= ENDIF (exist? "mach") =][= @@ -97,43 +100,57 @@ tSCC* apz[=(. Hack)=]Machs[] = {[= /* * content selection pattern - do fix if pattern found */[= - FOR select =] + FOR select =] tSCC z[=(. Hack)=]Select[=(for-index)=][] = [=(kr-string (get "select"))=];[= - ENDFOR select =][= - ENDIF =][= + ENDFOR select =][= + ENDIF =][= - IF (exist? "bypass")=] + IF (exist? "bypass") =] /* * content bypass pattern - skip fix if pattern found */[= - FOR bypass =] + FOR bypass =] tSCC z[=(. Hack)=]Bypass[=(for-index)=][] = [=(kr-string (get "bypass"))=];[= - ENDFOR bypass =][= - ENDIF =][= + ENDFOR bypass =][= + ENDIF =][= - IF (exist? "test")=] + IF (exist? "sum")=][= + (if (not (exist? "files")) + (error "specifying a 'sum' requires specifying 'files'")) + =] + +/* + * file selection - do fix if checksum matches + */[= + FOR sum =] +tSCC z[=(. Hack)=]Sum[=(for-index)=][] = + [=(kr-string (get "sum"))=];[= + ENDFOR sum =][= + ENDIF =][= + + IF (exist? "test") =] /* * perform the 'test' shell command - do fix on success */[= - FOR test =] + FOR test =] tSCC z[=(. Hack)=]Test[=(for-index)=][] = [=(kr-string (get "test"))=];[= - ENDFOR =][= - ENDIF =][= + ENDFOR =][= + ENDIF =][= - IF (exist? "c_test")=] + IF (exist? "c_test") =] /* * perform the C function call test */[= - FOR c_test =] + FOR c_test =] tSCC z[=(. Hack)=]FTst[=(for-index)=][] = "[=c_test=]";[= - ENDFOR c_test =][= - ENDIF =][= + ENDFOR c_test =][= + ENDIF =][= IF (set! ct (+ (count "select") (count "bypass") (count "test") (count "c_test"))) @@ -145,24 +162,28 @@ tSCC z[=(. Hack)=]FTst[=(for-index)=][] = "[=c_test=]";[= ELSE =] #define [=(. HACK)=]_TEST_CT [=(. ct)=][= - (set! re-ct (+ re-ct (count "select") (count "bypass"))) =] + (set! re-ct (+ re-ct (count "select") (count "bypass"))) =] static tTestDesc a[=(. Hack)=]Tests[] = {[= - FOR test =] + FOR test =] { TT_TEST, z[=(. Hack)=]Test[=(for-index)=], 0 /* unused */ },[= - ENDFOR test =][= + ENDFOR test =][= - FOR c_test =] + FOR c_test =] { TT_FUNCTION, z[=(. Hack)=]FTst[=(for-index)=], 0 /* unused */ },[= - ENDFOR c_test =][= + ENDFOR c_test =][= - FOR bypass =] + FOR bypass =] { TT_NEGREP, z[=(. Hack)=]Bypass[=(for-index)=], (regex_t*)NULL },[= - ENDFOR bypass =][= + ENDFOR bypass =][= - FOR select =] + FOR select =] { TT_EGREP, z[=(. Hack)=]Select[=(for-index)=], (regex_t*)NULL },[= - ENDFOR select =] };[= + ENDFOR select =][= + + FOR sum =] + { TT_CKSUM, z[=(. Hack)=]Sum[=(for-index)=], 0 /* unused */ },[= + ENDFOR sum =] };[= ENDIF =] /* diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x index eb98f44958d..ea868369e98 100644 --- a/fixincludes/fixincl.x +++ b/fixincludes/fixincl.x @@ -1,12 +1,12 @@ /* -*- buffer-read-only: t -*- vi: set ro: - * + * * DO NOT EDIT THIS FILE (fixincl.x) - * - * It has been AutoGen-ed October 21, 2014 at 10:18:16 AM by AutoGen 5.16.2 + * + * It has been AutoGen-ed December 20, 2014 at 03:22:33 PM by AutoGen 5.18.5pre6 * From the definitions inclhack.def * and the template file fixincl */ -/* DO NOT SVN-MERGE THIS FILE, EITHER Tue Oct 21 10:18:17 CEST 2014 +/* DO NOT SVN-MERGE THIS FILE, EITHER Sat Dec 20 15:22:33 PST 2014 * * You must regenerate it. Use the ./genfixes script. * diff --git a/fixincludes/fixlib.h b/fixincludes/fixlib.h index 45fe5a3cdb2..03277454c22 100644 --- a/fixincludes/fixlib.h +++ b/fixincludes/fixlib.h @@ -161,7 +161,7 @@ ENV_TABLE */ typedef enum { - TT_TEST, TT_EGREP, TT_NEGREP, TT_FUNCTION + TT_TEST, TT_EGREP, TT_NEGREP, TT_FUNCTION, TT_CKSUM } te_test_type; typedef struct test_desc tTestDesc;