Sender: bkorb AT sco DOT COM Message-ID: <397DCC3F.32D9BB7C@sco.com> Date: Tue, 25 Jul 2000 10:19:59 -0700 From: Bruce Korb Organization: Santa Cruz Operations X-Mailer: Mozilla 4.7 [en] (X11; I; SCO_SV 3.2 i386) X-Accept-Language: en MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com, Eli Zaretskii Subject: DJGPP patch for fixincludes Content-Type: multipart/mixed; boundary="------------FC1CEB417F1C2B6392839F2F" Reply-To: djgpp-workers AT delorie DOT com This is a multi-part message in MIME format. --------------FC1CEB417F1C2B6392839F2F Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hey, this was easy. What's the big deal? ;-) Attached are two patches. The first is yet to be applied to the source base, but will be RSN: http://gcc.gnu.org/ml/gcc-patches/2000-07/msg00777.html The second should be considered a ground level implementation guide. I pounded it out in a couple of hours last night, but it is a several hundred line patch. The 5,000 foot view: The fixincl program gets split in two. The routines in "fixfixes.c" become a separate program. Instead of fork()-ing, fixincl will use system(3) to invoke this program and have it produce a temporary file. Eventually, fixincl will compare the final temporary file with the original and decide to create or not the new file. The new executable will be named "applyfix" FOR DOS ONLY these three targets have these dependencies: applyfix : fixfixes.o gnu-regex.o fixlib.o fixfixes.o : fixincl.x fixlib.h fixincl : fixincl.o fixlib.o fixtests.o gnu-regex.o DO NOT link either procopen.o or server.o into the executables. The patch assumes that __DOS__ is defined. If it is named differently, then an adjustment will be necessary :-) All fix tests that depend on using a server shell are presumed to NOT APPLY in DOS-land. All fixes that use a shell script to produce the modification (all of one example anyway) are also presumed to NOT APPLY. Good luck and feel free to write :-). Cheers, Bruce --------------FC1CEB417F1C2B6392839F2F Content-Type: text/plain; charset=us-ascii; name="PATCH" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="PATCH" 2000-07-24 Bruce Korb * fixincl/fixfixes.c(emit_gnu_type): rewrote to *rely* on GCC defining the __xxx_TYPE__ macros. * fixincl/fixincl.tpl(gnu_type_map): now obsolete * fixincl/fixlib.h: don't need to include "tm.h" anymore * fixincl/inclhack.def(type_map): now obsolete *** fixfixes.c.ori Mon Jul 24 08:34:10 2000 --- fixfixes.c Mon Jul 24 08:51:41 2000 *************** *** 135,194 **** emit_gnu_type ( text, rm ) const char* text; regmatch_t* rm; { ! extern t_gnu_type_map gnu_type_map[]; ! extern int gnu_type_map_ct; ! ! const char* pzt = text + rm[GTYPE_SE_CT].rm_so; ! t_gnu_type_map* p_tm = gnu_type_map; ! int ct = gnu_type_map_ct; fwrite (text, rm[0].rm_so, 1, stdout); - text += rm[0].rm_eo; ! for (;;) ! { ! if (strncmp (pzt, p_tm->pz_type, p_tm->type_name_len) == 0) ! break; ! #ifdef DEBUG ! if (--ct <= 0) ! return (const char*)NULL; ! #else ! if (--ct <= 0) ! return text; ! #endif ! p_tm++; ! } /* ! * Now print out the reformed typedef */ { tSCC z_fmt[] = "\ - #ifndef __%s_TYPE__\n#define __%s_TYPE__ %s\n#endif\n\ - \ #if !defined(_GCC_%s_T)%s\n\ ! \ ! #define _GCC_%s_T\ntypedef __%s_TYPE__ %s_t;\n#endif\n"; ! const char* pz_guard; ! /* ! * We magically know that the first entry and only the first ! * entry needs guarding against __cplusplus (it is "wchar_t"). ! * If others wind up needing similar special treatment, then ! * go look into inclhack.def. This code, obviously, works closely ! * with that file :-) ! */ ! pz_guard = (p_tm == gnu_type_map) ? " && ! defined(__cplusplus)" : ""; ! printf (z_fmt, p_tm->pz_TYPE, p_tm->pz_TYPE, p_tm->pz_gtype, ! p_tm->pz_TYPE, pz_guard, ! p_tm->pz_TYPE, p_tm->pz_TYPE, p_tm->pz_type); } ! return text; } /* --- 135,177 ---- emit_gnu_type ( text, rm ) const char* text; regmatch_t* rm; { ! char z_TYPE[ 64 ]; ! char z_type[ 64 ]; fwrite (text, rm[0].rm_so, 1, stdout); ! { ! char* ps = text + rm[1].rm_so; ! char* pe = text + rm[1].rm_eo; ! char* pd = z_type; ! char* pD = z_TYPE; ! while (ps < pe) ! *(pD++) = toupper( *(pd++) = *(ps++) ); ! ! *pD = *pd = NUL; ! } /* ! * Now print out the reformed typedef, ! * with a C++ guard for WCHAR */ { tSCC z_fmt[] = "\ #if !defined(_GCC_%s_T)%s\n\ ! #define _GCC_%s_T\n\ ! typedef __%s_TYPE__ %s_t;\n\ ! #endif\n"; ! const char* pz_guard = (strcmp (z_type, "wchar") == 0) ! ? " && ! defined(__cplusplus)" : ""; ! printf (z_fmt, z_TYPE, pz_guard, z_TYPE, z_TYPE, z_type); } ! return text += rm[0].rm_eo; } /* *************** *** 693,738 **** compile_re (pz_pat, &re, 1, "gnu type typedef", "gnu_type_fix"); while (regexec (&re, text, GTYPE_SE_CT+1, rm, 0) == 0) { - #ifndef DEBUG text = emit_gnu_type (text, rm); - #else - tSCC z_mismatch[] = "``%s'' mismatched:\n"; - - /* - * Make sure we matched *all* subexpressions - */ - if (rm[GTYPE_SE_CT].rm_so == -1) - { - int i; - - fprintf (stderr, z_mismatch, pz_pat); - - for (i=0; i <= GTYPE_SE_CT; i++) - { - if (rm[i].rm_so != -1) - { - fprintf( stderr, "%4d: ``", i ); - fwrite( text + rm[i].rm_so, rm[i].rm_eo - rm[i].rm_so, - 1, stderr ); - fputs( "''\n", stderr ); - } - else - { - fprintf( stderr, "%4d: BROKEN\n", i ); - } - } - exit (EXIT_BROKEN); - } - - text = emit_gnu_type (text, rm); - if (text == NULL) - { - fprintf (stderr, z_mismatch, pz_pat); - exit (EXIT_BROKEN); - } - #endif } /* * Dump out the rest of the file --- 676,684 ---- *** fixincl.tpl.ori Mon Jul 24 08:34:18 2000 --- fixincl.tpl Mon Jul 24 08:38:49 2000 *************** *** 202,224 **** a[=hackname _cap=]Tests, apz[=hackname _cap=]Patch }[= /fix=] }; - - #define GNU_TYPE_CT [=_eval type_map _count =] - int gnu_type_map_ct = GNU_TYPE_CT; - - /* - * The following table depends upon XXX_TYPE being #define-d to the - * correct string via defines in a header file pointed to by the - * generated file "tm.h". - */ - t_gnu_type_map gnu_type_map[ GNU_TYPE_CT ] = {[= - - _FOR type_map , - - =] - { [=_EVAL type_map _len=], "[=type_map=]", "[=type_map _up=]", [= - type_map _up=]_TYPE }[= - - /type_map=] - }; --- 202,205 ---- *** fixlib.h.ori Mon Jul 24 08:34:23 2000 --- fixlib.h Mon Jul 24 08:54:24 2000 *************** *** 32,41 **** #include "gnu-regex.h" #include "machname.h" #include "libiberty.h" - #include "tm.h" - #ifndef STDIN_FILENO # define STDIN_FILENO 0 #endif #ifndef STDOUT_FILENO --- 32,39 ---- *************** *** 148,156 **** Everything you ever wanted to know about how to apply a particular fix (which files, how to qualify them, how to actually make the fix, etc...) ! NB: the FD_ defines are BIT FLAGS */ #define FD_MACH_ONLY 0x0000 #define FD_MACH_IFNOT 0x0001 --- 146,155 ---- Everything you ever wanted to know about how to apply a particular fix (which files, how to qualify them, how to actually make the fix, etc...) ! NB: the FD_ defines are BIT FLAGS, even though ! some are mutually exclusive */ #define FD_MACH_ONLY 0x0000 #define FD_MACH_IFNOT 0x0001 *** inclhack.def.ori Mon Jul 24 08:34:41 2000 --- inclhack.def Mon Jul 24 08:39:35 2000 *************** *** 2518,2533 **** /* * Fix these files to use the same types that we think they should. - * Each type must be present in two places: the select clause - * and a "type_map" entry below. The types mapped to are found from - * the "tm.h" header, which is a generated file that refers to - * a header in the gcc/config/ tree. Keep these in sync!! - * - * Also, "wchar" is first and known to need guarding against __cplusplus. - * Keep *that* in mind, too, when hacking the gnu_type_fix routine - * in fixfixes.c. */ fix = { hackname = gnu_types; files = "sys/types.h"; --- 2518,2525 ---- *************** *** 2543,2554 **** test_text = "typedef long int ptrdiff_t; /* long int */\n" "typedef uint_t size_t; /* uint_t */\n" "typedef ushort_t wchar_t; /* ushort_t */"; }; - - type_map = wchar; - type_map = ptrdiff; - type_map = size; /* * Fix return value of mem{ccpy,chr,cpy,set} and str{len,spn,cspn} --- 2535,2542 ---- --------------FC1CEB417F1C2B6392839F2F Content-Type: text/plain; charset=us-ascii; name="DOSFIX.PAT" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="DOSFIX.PAT" *** fixfixes.c.dos Mon Jul 24 08:51:41 2000 --- fixfixes.c Mon Jul 24 14:34:56 2000 *************** *** 58,67 **** --- 58,71 ---- Boston, MA 02111-1307, USA. */ #include "fixlib.h" #define GTYPE_SE_CT 1 + #ifdef __DOS__ + #include "fixincl.x" + #endif + tSCC zNeedsArg[] = "fixincl error: `%s' needs %s argument (c_fix_arg[%d])\n"; typedef struct { const char* fix_name; void (*fix_proc)(); *************** *** 723,727 **** --- 727,794 ---- } buf = load_file_data (stdin); (*pfe->fix_proc)( filname, buf, p_fixd ); } + + #ifdef __DOS__ + tSCC z_usage[] = + "USAGE: applyfix \n"; + tSCC z_reopen[] = + "FS error %d (%s) reopening %s as std%s\n"; + + int + main( argc, argv ) + int argc; + char** argv; + { + tFixDesc* pFix; + char* pz_tmptmp; + + if (argc != 5) + { + usage_failure: + fputs( z_usage, stderr ); + return EXIT_FAILURE; + } + + { + char* pz = argv[1]; + long idx; + + if (! isdigit( *pz )) + goto usage_failure; + + idx = strtol( pz, &pz, 10 ); + if ((*pz != NUL) || ((unsigned)idx >= FIX_COUNT)) + goto usage_failure; + pFix = fixDescList + idx; + } + + if (freopen( argv[3], "r", stdin ) != stdin) + { + fprintf( stderr, z_reopen, errno, strerror( errno ), argv[3], "in" ); + return EXIT_FAILURE; + } + + pz_tmptmp = (char*)xmalloc( strlen( argv[4] ) + 5 ); + sprintf( pz_tmptmp, "%sX", argv[4] ); + if (freopen( pz_tmptmp, "w", stdout ) != stdin) + { + fprintf( stderr, z_reopen, errno, strerror( errno ), pz_tmptmp, "out" ); + return EXIT_FAILURE; + } + + apply_fix( pFix, argv[1] ); + close( STDOUT_FILENO ); + close( STDIN_FILENO ); + unlink( argv[4] ); + if (rename( pz_tmptmp, argv[4] ) != 0) + { + fprintf( stderr, "error %d (%s) renaming %s to %s\n", errno, + strerror( errno ), pz_tmptmp, argv[4] ); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } + #endif *** fixincl.c.dos Mon Jul 24 08:34:17 2000 --- fixincl.c Mon Jul 24 14:34:38 2000 *************** *** 28,39 **** #include #define BAD_ADDR ((void*)-1) #endif #include ! #include "server.h" /* The contents of this string are not very important. It is mostly just used as part of the "I am alive and working" test. */ static const char program_id[] = "fixincl version 1.1"; --- 28,40 ---- #include #define BAD_ADDR ((void*)-1) #endif #include ! #ifndef __DOS__ #include "server.h" + #endif /* The contents of this string are not very important. It is mostly just used as part of the "I am alive and working" test. */ static const char program_id[] = "fixincl version 1.1"; *************** *** 72,81 **** --- 73,84 ---- pid_t process_chain_head = (pid_t) -1; char* pz_curr_file; /* name of the current file under test/fix */ char* pz_curr_data; /* original contents of that file */ + char* pz_temp_file; /* for DOS, a place to stash the temporary + fixed data between system(3) calls */ t_bool curr_data_mapped; int data_map_fd; size_t data_map_size; size_t ttl_data_size = 0; *************** *** 176,185 **** --- 179,192 ---- fprintf (stderr, zFmt, process_ct, ttl_data_size, apply_ct, fixed_ct, altered_ct); } # endif /* DO_STATS */ + + # ifdef __DOS__ + unlink( pz_temp_file ); + # endif return EXIT_SUCCESS; } void *************** *** 193,204 **** --- 200,215 ---- 2. that we can compile all the regular expressions. 3. we can correctly run our server shell process */ run_compiles (); sprintf (zBuf, zFmt, program_id); + #ifndef __DOS__ puts (zBuf + 5); exit (strcmp (run_shell (zBuf), program_id)); + #else + exit (system (zBuf)); + #endif } /* * * * * * * * * * * * */ void *************** *** 285,294 **** --- 296,316 ---- /* Compile all the regular expressions now. That way, it is done only once for the whole run. */ run_compiles (); + # ifdef __DOS__ + { + tSCC z_tmp_fname_fmt[] = "%s/fxinc%03X.tp"; + char* pz = getenv( "TMP" ); + if (pz == NULL) + pz = "/tmp"; + pz_temp_file = (char*)xmalloc (sizeof(z_tmp_fname_fmt) + strlen (pz)); + sprintf (pz_temp_file, z_tmp_fname_fmt, pz, getpid() & 0x0FFF); + } + # endif + signal (SIGQUIT, SIG_IGN); #ifdef SIGIOT signal (SIGIOT, SIG_IGN); #endif signal (SIGPIPE, SIG_IGN); *************** *** 346,403 **** #endif return res; } ! ! /* * * * * * * * * * * * * ! ! run_compiles run all the regexp compiles for all the fixes once. ! */ ! void ! run_compiles () ! { ! tFixDesc *p_fixd = fixDescList; ! int fix_ct = FIX_COUNT; ! tTestDesc *p_test; ! int test_ct; ! const char *pz_err; ! regex_t *p_re = (regex_t *) malloc (REGEX_COUNT * sizeof (regex_t)); ! ! if (p_re == (regex_t *) NULL) ! { ! fprintf (stderr, "fixincl ERROR: cannot allocate %d bytes for regex\n", ! REGEX_COUNT * sizeof (regex_t)); ! exit (EXIT_FAILURE); ! } ! ! /* Make sure compile_re does not stumble across invalid data */ ! ! memset ( (void*)p_re, '\0', REGEX_COUNT * sizeof (regex_t) ); ! memset ( (void*)&incl_quote_re, '\0', sizeof (regex_t) ); ! ! compile_re (incl_quote_pat, &incl_quote_re, 1, ! "quoted include", "run_compiles"); ! ! /* Allow machine name tests to be ignored (testing, mainly) */ ! ! if (pz_machine && ((*pz_machine == '\0') || (*pz_machine == '*'))) ! pz_machine = (char*)NULL; ! ! /* FOR every fixup, ... */ ! do ! { ! p_test = p_fixd->p_test_desc; ! test_ct = p_fixd->test_ct; ! ! /* IF the machine type pointer is not NULL (we are not in test mode) ! AND this test is for or not done on particular machines ! THEN ... */ ! ! if ( (pz_machine != NULL) ! && (p_fixd->papz_machs != (const char**) NULL) ) { tSCC case_fmt[] = "case %s in\n"; /* 9 bytes, plus string */ tSCC esac_fmt[] = " )\n echo %s ;;\n* ) echo %s ;;\nesac";/* 4 bytes */ tSCC skip[] = "skip"; /* 4 bytes */ tSCC run[] = "run"; /* 3 bytes */ --- 368,382 ---- #endif return res; } ! int ! machine_matches( p_fixd ) ! tFixDesc *p_fixd; { + # ifndef __DOS__ tSCC case_fmt[] = "case %s in\n"; /* 9 bytes, plus string */ tSCC esac_fmt[] = " )\n echo %s ;;\n* ) echo %s ;;\nesac";/* 4 bytes */ tSCC skip[] = "skip"; /* 4 bytes */ tSCC run[] = "run"; /* 3 bytes */ *************** *** 455,488 **** skip = (*pz == 's'); free ( (void*)pz ); if (skip) { p_fixd->fd_flags |= FD_SKIP_TEST; ! continue; } } } /* FOR every test for the fixup, ... */ while (--test_ct >= 0) { switch (p_test->type) { case TT_EGREP: case TT_NEGREP: - #ifdef DEBUG - { - static int re_ct = REGEX_COUNT; - - if (--re_ct < 0) - { - fputs ("out of RE's\n", stderr); - exit (EXIT_FAILURE); - } - } - #endif p_test->p_test_regex = p_re++; compile_re (p_test->pz_test_text, p_test->p_test_regex, 0, "select test", p_fixd->fix_name); } p_test++; --- 434,521 ---- skip = (*pz == 's'); free ( (void*)pz ); if (skip) { p_fixd->fd_flags |= FD_SKIP_TEST; ! return BOOL_FALSE; ! } ! } ! ! return BOOL_TRUE; ! # else /* is __DOS__ */ ! const char **papz_machs = p_fixd->papz_machs; ! for (;;) ! { ! const char* pz_mach = *(papz_machs++); ! ! if (pz_mach == (const char*) NULL) ! break; ! if (strstr (pz_mach, "dos") != NULL) ! { ! p_fixd->fd_flags |= FD_SKIP_TEST; ! return BOOL_TRUE; } } + + return BOOL_FALSE; + # endif + } + + /* * * * * * * * * * * * * + + run_compiles run all the regexp compiles for all the fixes once. + */ + void + run_compiles () + { + tFixDesc *p_fixd = fixDescList; + int fix_ct = FIX_COUNT; + regex_t *p_re = (regex_t *) malloc (REGEX_COUNT * sizeof (regex_t)); + + if (p_re == (regex_t *) NULL) + { + fprintf (stderr, "fixincl ERROR: cannot allocate %d bytes for regex\n", + REGEX_COUNT * sizeof (regex_t)); + exit (EXIT_FAILURE); } + /* Make sure compile_re does not stumble across invalid data */ + + memset ( (void*)p_re, '\0', REGEX_COUNT * sizeof (regex_t) ); + memset ( (void*)&incl_quote_re, '\0', sizeof (regex_t) ); + + compile_re (incl_quote_pat, &incl_quote_re, 1, + "quoted include", "run_compiles"); + + /* Allow machine name tests to be ignored (testing, mainly) */ + + if (pz_machine && ((*pz_machine == '\0') || (*pz_machine == '*'))) + pz_machine = (char*)NULL; + + /* FOR every fixup, ... */ + do + { + tTestDesc *p_test = p_fixd->p_test_desc; + int test_ct = p_fixd->test_ct; + + /* IF the machine type pointer is not NULL (we are not in test mode) + AND this test is for or not done on particular machines + THEN ... */ + + if ( (pz_machine != NULL) + && (p_fixd->papz_machs != (const char**) NULL) + && ! machine_matches () ) + continue; + /* FOR every test for the fixup, ... */ while (--test_ct >= 0) { switch (p_test->type) { case TT_EGREP: case TT_NEGREP: p_test->p_test_regex = p_re++; compile_re (p_test->pz_test_text, p_test->p_test_regex, 0, "select test", p_fixd->fix_name); } p_test++; *************** *** 576,586 **** test_test make sure a shell-style test expression passes. Input: a pointer to the descriptor of the test to run and the name of the file that we might want to fix Result: APPLY_FIX or SKIP_FIX, depending on the result of the shell script we run. */ ! int test_test (p_test, pz_test_file) tTestDesc *p_test; char* pz_test_file; { --- 609,619 ---- test_test make sure a shell-style test expression passes. Input: a pointer to the descriptor of the test to run and the name of the file that we might want to fix Result: APPLY_FIX or SKIP_FIX, depending on the result of the shell script we run. */ ! #ifndef __DOS__ int test_test (p_test, pz_test_file) tTestDesc *p_test; char* pz_test_file; { *************** *** 614,624 **** } free ((void *) pz_res); return res; } ! /* * * * * * * * * * * * * egrep_test make sure an egrep expression is found in the file text. Input: a pointer to the descriptor of the test to run and --- 647,663 ---- } free ((void *) pz_res); return res; } ! #else ! /* ! * IF we are in MS-DOS land, then whatever shell-type test is required ! * will, by definition, fail ! */ ! #define test_test(t,tf) SKIP_FIX ! #endif /* * * * * * * * * * * * * egrep_test make sure an egrep expression is found in the file text. Input: a pointer to the descriptor of the test to run and *************** *** 765,775 **** /* * * * * * * * * * * * * Somebody wrote a *_fix subroutine that we must call. */ ! int internal_fix (read_fd, p_fixd) int read_fd; tFixDesc* p_fixd; { --- 804,814 ---- /* * * * * * * * * * * * * Somebody wrote a *_fix subroutine that we must call. */ ! #ifndef __DOS__ int internal_fix (read_fd, p_fixd) int read_fd; tFixDesc* p_fixd; { *************** *** 831,849 **** --- 870,992 ---- fcntl (read_fd, F_DUPFD, STDIN_FILENO); apply_fix (p_fixd, pz_curr_file); exit (0); } + #endif + + + #ifdef __DOS__ + static void + fix_with_system (p_fixd, pz_fix_file, pz_file_source, pz_temp_file) + tFixDesc* p_fixd; + tCC* pz_fix_file; + tCC* pz_file_source; + tCC* pz_temp_file; + { + char* pz_cmd; + char* pz_scan; + size_t argsize; + + if (p_fixd->fd_flags & FD_SUBROUTINE) + { + tSCC z_applyfix_prog = "fixinc/applyfix"; + + argsize = 32 + + strlen( pz_dest_dir ) + + sizeof( z_applyfix_prog ) + + strlen( pz_fix_file ) + + strlen( pz_file_source ) + + strlen( pz_temp_file ); + + pz_cmd = (char*)xmalloc( argsize ); + + strcpy( pz_cmd, pz_dest_dir ); + pz_scan = strrchr( pz_cmd, '/' ); + strcpy( pz_scan+1, z_applyfix_prog ); + pz_scan += sizeof( z_applyfix_prog ); + *(pz_scan++) = ' '; + + /* + * Now add the fix number and file names that may be needed + */ + snprintf (pz_scan, argsize - (pz_scan - pz_cmd), + "%d %s %s %s", fixDescList - p_fixd, + pz_fix_file, pz_file_source, pz_temp_file); + } + else /* NOT an "internal" fix: */ + { + tSCC z_cmd_fmt[] = " %s > %sX\nrm -f %s\nmv -f %sX %s"; + tCC** ppArgs = p_fixd->patch_args; + + argsize = sizeof( z_cmd_fmt ) + 4 * strlen( pz_temp_file ) + + strlen( pz_file_source ); + + /* + * Compute the size of the command line. Add lotsa extra space + * because some of the args to sed use lotsa single quotes. + * (This requires three extra bytes per quote. Here we allow + * for up to 8 single quotes for each argument, including the + * command name "sed" itself. Nobody will *ever* need more. :) + */ + for (;;) + { + tCC* p_arg = *(ppArgs++); + if (p_arg == NULL) + break; + argsize += 24 + strlen( p_arg ); + } + + pz_scan = pz_cmd = (char*)xmalloc( argsize ); + ppArgs = p_fixd->patch_args; + + /* + * Copy the program name, unquoted + */ + { + tCC* pArg = *(ppArgs++); + for (;;) + { + char ch = *(pArg++); + if (ch == NUL) + break; + *(pz_scan++) = ch; + } + } + + /* + * Copy the program arguments, quoted + */ + for (;;) + { + tCC* pArg = *(ppArgs++); + if (pArg == NULL) + break; + *(pz_scan++) = ' '; + pz_scan = make_raw_shell_str( pz_scan, pArg ); + } + /* + * add the file machinations. Make sure we don't overflow + * the buffer due to sloppy size estimation. + */ + snprintf( pz_scan, argsize - (pz_scan - pz_cmd), z_cmd_fmt, + pz_file_source, + pz_temp_file, pz_temp_file, pz_temp_file ); + } + system( pz_cmd ); + free( (void*)pz_cmd ); + } /* * * * * * * * * * * * * This loop should only cycle for 1/2 of one loop. "chain_open" starts a process that uses "read_fd" as its stdin and returns the new fd this process will use for stdout. */ + #else /* is *NOT* __DOS__ */ int start_fixer (read_fd, p_fixd, pz_fix_file) int read_fd; tFixDesc* p_fixd; char* pz_fix_file; *************** *** 910,919 **** --- 1053,1063 ---- p_fixd->patch_args[2] = pz_cmd_save; } return read_fd; } + #endif /* * * * * * * * * * * * * Process the potential fixes for a particular include file. *************** *** 922,942 **** t_bool fix_applies (p_fixd) tFixDesc *p_fixd; { - #ifdef DEBUG - static const char z_failed[] = "not applying %s %s to %s - \ - test %d failed\n"; - #endif const char *pz_fname = pz_curr_file; const char *pz_scan = p_fixd->file_list; int test_ct; tTestDesc *p_test; if (p_fixd->fd_flags & FD_SKIP_TEST) return BOOL_FALSE; /* IF there is a file name restriction, THEN ensure the current file name matches one in the pattern */ if (pz_scan != (char *) NULL) --- 1066,1092 ---- t_bool fix_applies (p_fixd) tFixDesc *p_fixd; { const char *pz_fname = pz_curr_file; const char *pz_scan = p_fixd->file_list; int test_ct; tTestDesc *p_test; + # ifdef __DOS__ + /* + * There is only one fix that uses a shell script as of this writing. + * I hope to nuke it anyway, it does not apply to DOS and it would + * be painful to implement. Therefore, no "shell" fixes for DOS. + */ + if (p_fixd->fd_flags & (FD_SHELL_SCRIPT | FD_SKIP_TEST)) + return BOOL_FALSE; + # else if (p_fixd->fd_flags & FD_SKIP_TEST) return BOOL_FALSE; + # endif /* IF there is a file name restriction, THEN ensure the current file name matches one in the pattern */ if (pz_scan != (char *) NULL) *************** *** 950,967 **** for (;;) { pz_scan = strstr (pz_scan + 1, pz_fname); /* IF we can't match the string at all, THEN bail */ ! if (pz_scan == (char *) NULL) { ! #ifdef DEBUG ! if (VLEVEL( VERB_EVERYTHING )) ! fprintf (stderr, "file %s not in list for %s\n", ! pz_fname, p_fixd->fix_name ); ! #endif return BOOL_FALSE; - } /* IF the match is surrounded by the '|' markers, THEN we found a full match -- time to run the tests */ if ((pz_scan[-1] == '|') && (pz_scan[name_len] == '|')) --- 1100,1111 ---- for (;;) { pz_scan = strstr (pz_scan + 1, pz_fname); /* IF we can't match the string at all, THEN bail */ ! if (pz_scan == (char *) NULL) return BOOL_FALSE; /* IF the match is surrounded by the '|' markers, THEN we found a full match -- time to run the tests */ if ((pz_scan[-1] == '|') && (pz_scan[name_len] == '|')) *************** *** 1131,1145 **** Result: none. A new file may or may not be created. */ void process () { - static char env_current_file[1024]; tFixDesc *p_fixd = fixDescList; int todo_ct = FIX_COUNT; int read_fd = -1; int num_children = 0; if (access (pz_curr_file, R_OK) != 0) { int erno = errno; fprintf (stderr, "Cannot access %s from %s\n\terror %d (%s)\n", --- 1275,1292 ---- Result: none. A new file may or may not be created. */ void process () { tFixDesc *p_fixd = fixDescList; int todo_ct = FIX_COUNT; int read_fd = -1; + # ifndef __DOS__ int num_children = 0; + # else /* is __DOS__ */ + char* pz_file_source = pz_curr_file; + # endif if (access (pz_curr_file, R_OK) != 0) { int erno = errno; fprintf (stderr, "Cannot access %s from %s\n\terror %d (%s)\n", *************** *** 1156,1165 **** --- 1303,1313 ---- process_ct++; #endif if (VLEVEL( VERB_PROGRESS ) && have_tty) fprintf (stderr, "%6d %-50s \r", data_map_size, pz_curr_file ); + # ifndef __DOS__ process_chain_head = NOPROCESS; /* For every fix in our fix list, ... */ for (; todo_ct > 0; p_fixd++, todo_ct--) { *************** *** 1216,1222 **** --- 1364,1396 ---- do { wait ((int *) NULL); } while (--num_children > 0); } + # else /* is __DOS__ */ + + for (; todo_ct > 0; p_fixd++, todo_ct--) + { + if (! fix_applies (p_fixd)) + continue; + + if (VLEVEL( VERB_APPLIES )) + fprintf (stderr, "Applying %-24s to %s\n", + p_fixd->fix_name, pz_curr_file); + + if (p_fixd->fd_flags & FD_REPLACEMENT) + { + write_replacement (p_fixd); + UNLOAD_DATA(); + return; + } + fix_with_system (p_fixd, pz_curr_file, pz_file_source, pz_temp_file); + pz_file_source = pz_temp_file; + } + + read_fd = open( pz_temp_file, O_RDONLY ); + test_for_changes( read_fd ); + unlink( pz_temp_file ); + + # endif UNLOAD_DATA(); } *** fixlib.c.dos Mon Jul 24 08:34:22 2000 --- fixlib.c Mon Jul 24 14:35:34 2000 *************** *** 242,247 **** --- 242,291 ---- mn_compiled++; } *label_re = &mn_label_re; *name_re = &mn_name_re; } + #endif + + + #ifdef __DOS__ + + char* + make_raw_shell_str( pz_d, pz_s ) + char* pz_d; + tCC* pz_s; + { + tSCC zQ[] = "'\\''"; + size_t dtaSize; + + dtaSize = strlen( pz_s ) + 3; + + { + char* pz = pz_s - 1; + + for (;;) { + pz = strchr( pz+1, '\'' ); + if (pz == (char*)NULL) + break; + dtaSize += sizeof( zQ )-1; + } + } + + *(pz_d++) = '\''; + + for (;;) { + switch (*(pz_d++) = *(pz_s++)) { + case NUL: + goto loopDone; + + case '\'': + strcpy( pz_d-1, zQ ); + pz_d += sizeof( zQ )-2; + } + } loopDone:; + pz_d[-1] = '\''; + *pz_d = NUL; + + return pz_d; + } + #endif *** fixlib.h.dos Mon Jul 24 08:54:24 2000 --- fixlib.h Mon Jul 24 13:25:27 2000 *************** *** 202,211 **** --- 202,215 ---- tCC *e1, tCC *e2 )); void apply_fix _P_(( tFixDesc* p_fixd, tCC* filname )); apply_fix_p_t run_test _P_((tCC* t_name, tCC* f_name, tCC* text )); + #ifdef __DOS__ + char* make_raw_shell_str _P_(( char* pz_d, tCC* pz_s )); + #endif + #ifdef MN_NAME_PAT void mn_get_regexps _P_(( regex_t** label_re, regex_t** name_re, tCC *who )); #endif #endif /* FIXINCLUDES_FIXLIB_H */ --------------FC1CEB417F1C2B6392839F2F--