From: pavenis AT lanet DOT lv Message-ID: To: Mumit Khan , djgpp-workers AT delorie DOT com Date: Mon, 10 Jan 2000 18:57:40 +0200 MIME-Version: 1.0 Content-type: Multipart/Mixed; boundary=Message-Boundary-4105 Subject: Re: (patch) updated protoize patch In-reply-to: <200001070051.SAA12564@mercury.xraylith.wisc.edu> X-mailer: Pegasus Mail for Win32 (v3.12b) Reply-To: djgpp-workers AT delorie DOT com Errors-To: dj-admin AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk --Message-Boundary-4105 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Mail message body On 6 Jan 00, at 18:51, Mumit Khan wrote: > Please ignore the last patch I had sent and use this one instead. Just > as a reminder, this is against gcc-2.95.2 tree. For those using gcc > mainline, it's already in the sources. You can look at the mainline > patch (already committed) at: > > Linkname: (patch) [Take 2] protoize fixes for dos/windows32 > URL: http://gcc.gnu.org/ml/gcc-patches/2000-01/msg00195.html > > The caveats I had mentioned in the previous email still stands -- > especially the one about inconsistent spelling of FILE_SYSTEM vs > FILEYSTEM in DOS_BASED_FILE_SYSTEM macro. > > fyi, I'm not a subscriber to this list, so please do copy me if you > have questions. > Well, I did some tests with DJGPP. After fixing bug in gcc/config/i386/xm-djgpp.h (HAVE_DOS_BASED_FILESYSTEM were written instead of HAVE_DOS_BASED_FILE_SYSTEM) and after fixing following additional things in protoize.c - expanding $DJDIR in begin of filename in process_aux_info_file() - replacing aux_info_suffix for DJGPP (I used "X" instead of ".X" as foo.c.X in not a legal file name for DOS when LFN support is not available) - I also used /dev/null instead of "NUL:" of course protoize and unprotoize seems to work. However I haven't done much tests with it Andris PS. I'm including in attachment last protoize.c patch against v2.95.2 I used --Message-Boundary-4105 Content-type: text/plain; charset=US-ASCII Content-disposition: inline Content-description: Attachment information. The following section of this message contains a file attachment prepared for transmission using the Internet MIME message format. If you are using Pegasus Mail, or any another MIME-compliant system, you should be able to save it or view it from within your mailer. If you cannot, please ask your system administrator for assistance. ---- File information ----------- File: protoize.c.diff Date: 10 Jan 2000, 18:46 Size: 19834 bytes. Type: Text --Message-Boundary-4105 Content-type: Application/Octet-stream; name="protoize.c.diff"; type=Text Content-disposition: attachment; filename="protoize.c.diff" --- protoize.c~1 Fri Apr 16 19:52:36 1999 +++ protoize.c Mon Jan 10 18:46:20 2000 @@ -61,6 +61,39 @@ #include "intl.h" #undef abort +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + +/* Define IS_DIR_SEPARATOR. */ +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +/* Macro to see if the path elements match. */ +#ifdef HAVE_DOS_BASED_FILE_SYSTEM +#define IS_SAME_PATH_CHAR(a,b) (toupper (a) == toupper (b)) +#else +#define IS_SAME_PATH_CHAR(a,b) ((a) == (b)) +#endif + +/* Macro to see if the paths match. */ +#ifdef HAVE_DOS_BASED_FILE_SYSTEM +#define IS_SAME_PATH(a,b) (strcasecmp (a, b) == 0) +#else +#define IS_SAME_PATH(a,b) (strcmp (a, b) == 0) +#endif + +/* Suffix for renamed C++ files. */ +#ifdef HAVE_DOS_BASED_FILE_SYSTEM +#define CPLUS_FILE_SUFFIX "cc" +#else +#define CPLUS_FILE_SUFFIX "C" +#endif + #if ! defined (_WIN32) || defined (__CYGWIN__) || defined (_UWIN) #if defined(POSIX) || defined(CONCURRENT) #include @@ -69,6 +102,9 @@ #endif #endif #include +#ifdef HAVE_UNISTD_H +#include +#endif /* Some systems like Linux don't declare rindex if _POSIX_SOURCE is declared, but it normally does declare it. This means that configure thinks we don't @@ -100,11 +136,7 @@ #define my_access(file,flag) access((char *)file, flag) #define my_stat(file,pkt) stat((char *)file, pkt) -#ifdef __MINGW32__ -#define my_link(file1, file2) -1 -#else -#define my_link(file1, file2) link((char *)file1, (char *)file2) -#endif +#define my_rename(file1, file2) rename((char *)file1, (char *)file2) #define my_unlink(file) unlink((char *)file) #define my_open(file, mode, flag) open((char *)file, mode, flag) #define my_chmod(file, mode) chmod((char *)file, mode) @@ -171,12 +203,24 @@ /* Suffix of aux_info files. */ -static const char * const aux_info_suffix = ".X"; +#ifdef DJGPP +#define PROTOIZE_AUX_INFO_SUFFIX "X" +#endif + +#ifndef PROTOIZE_AUX_INFO_SUFFIX +#define PROTOIZE_AUX_INFO_SUFFIX ".X" +#endif + +static const char * const aux_info_suffix = PROTOIZE_AUX_INFO_SUFFIX; /* String to attach to filenames for saved versions of original files. */ static const char * const save_suffix = ".save"; +/* String to attach to C filenames renamed to C++. */ + +static const char * const cplus_suffix = CPLUS_FILE_SUFFIX; + #ifndef UNPROTOIZE /* File name of the file which contains descriptions of standard system @@ -567,6 +611,7 @@ /* Forward declaration. */ static const char *shortpath (); +static int is_abspath PVPROTO ((const char *)); /* Translate and output an error message. */ static void notice PVPROTO ((const char *, ...)) @@ -843,12 +888,12 @@ { struct default_include *p; - if (path[0] != '/') + if (! is_abspath (path)) abort (); /* Must be an absolutized filename. */ for (p = include_defaults; p->fname; p++) if (!strncmp (path, p->fname, strlen (p->fname)) - && path[strlen (p->fname)] == '/') + && IS_DIR_SEPARATOR (path[strlen (p->fname)])) return 1; return 0; } @@ -870,7 +915,17 @@ char *dir_last_slash; strcpy (dir_name, path); - dir_last_slash = strrchr (dir_name, '/'); + dir_last_slash = strrchr (dir_name, DIR_SEPARATOR); +#ifdef DIR_SEPARATOR_2 + { + char *slash; + + slash = strrchr (dir_last_slash ? dir_last_slash : dir_name, + DIR_SEPARATOR_2); + if (slash) + dir_last_slash = slash; + } +#endif if (dir_last_slash) *dir_last_slash = '\0'; else @@ -904,7 +959,17 @@ char *dir_last_slash; strcpy (dir_name, path); - dir_last_slash = strrchr (dir_name, '/'); + dir_last_slash = strrchr (dir_name, DIR_SEPARATOR); +#ifdef DIR_SEPARATOR_2 + { + char *slash; + + slash = strrchr (dir_last_slash ? dir_last_slash : dir_name, + DIR_SEPARATOR_2); + if (slash) + dir_last_slash = slash; + } +#endif if (dir_last_slash) *dir_last_slash = '\0'; else @@ -1011,14 +1076,14 @@ for (p = directory_list; p; p = p->next) if (!strncmp (name, p->name, strlen (p->name)) - && name[strlen (p->name)] == '/') + && IS_DIR_SEPARATOR (name[strlen (p->name)])) { const char *q = name + strlen (p->name) + 1; /* If there are more slashes, it's in a subdir, so this match doesn't count. */ - while (*q) - if (*q++ == '/') + while (*q++) + if (IS_DIR_SEPARATOR (*(q-1))) goto lose; return 1; @@ -1039,7 +1104,7 @@ for (p = exclude_list; p; p = p->next) if (!strcmp (name + len - strlen (p->name), p->name) - && name[len - strlen (p->name) - 1] == '/') + && IS_DIR_SEPARATOR (name[len - strlen (p->name) - 1])) return 1; return 0; @@ -1243,6 +1308,20 @@ return (got_unexpanded ? savestring (line_buf, copy_p - line_buf) : 0); } +/* Return 1 if pathname is absolute. */ + +static int +is_abspath (path) + const char *path; +{ + return (IS_DIR_SEPARATOR (path[0]) +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* Check for disk name on MS-DOS-based systems. */ + || (path[0] && path[1] == ':' && IS_DIR_SEPARATOR (path[2])) +#endif + ); +} + /* Return the absolutized filename for the given relative filename. Note that if that filename is already absolute, it may still be returned in a modified form because this routine also @@ -1271,13 +1350,24 @@ { const char *src_p; - if (rel_filename[0] != '/') + if (! is_abspath (rel_filename)) { src_p = cwd2; while ((*endp++ = *src_p++)) continue; - *(endp-1) = '/'; /* overwrite null */ + *(endp-1) = DIR_SEPARATOR; /* overwrite null */ } +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + else if (IS_DIR_SEPARATOR (rel_filename[0])) + { + /* A path starting with a directory separator is considered absolute + for dos based filesystems, but it's really not -- it's just the + convention used throughout GCC and it works. However, in this + case, we still need to prepend the drive spec from cwd_buffer. */ + *endp++ = cwd2[0]; + *endp++ = cwd2[1]; + } +#endif src_p = rel_filename; while ((*endp++ = *src_p++)) continue; @@ -1289,32 +1379,33 @@ outp = inp = abs_buffer; *outp++ = *inp++; /* copy first slash */ #if defined (apollo) || defined (_WIN32) || defined (__INTERIX) - if (inp[0] == '/') + if (IS_DIR_SEPARATOR (inp[0])) *outp++ = *inp++; /* copy second slash */ #endif for (;;) { if (!inp[0]) break; - else if (inp[0] == '/' && outp[-1] == '/') + else if (IS_DIR_SEPARATOR (inp[0]) && IS_DIR_SEPARATOR (outp[-1])) { inp++; continue; } - else if (inp[0] == '.' && outp[-1] == '/') + else if (inp[0] == '.' && IS_DIR_SEPARATOR (outp[-1])) { if (!inp[1]) break; - else if (inp[1] == '/') + else if (IS_DIR_SEPARATOR (inp[1])) { inp += 2; continue; } - else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/')) + else if ((inp[1] == '.') && (inp[2] == 0 + || IS_DIR_SEPARATOR (inp[2]))) { - inp += (inp[2] == '/') ? 3 : 2; + inp += (IS_DIR_SEPARATOR (inp[2])) ? 3 : 2; outp -= 2; - while (outp >= abs_buffer && *outp != '/') + while (outp >= abs_buffer && ! IS_DIR_SEPARATOR (*outp)) outp--; if (outp < abs_buffer) { @@ -1337,7 +1428,7 @@ the last character of the returned string is *not* a slash. */ *outp = '\0'; - if (outp[-1] == '/') + if (IS_DIR_SEPARATOR (outp[-1])) *--outp = '\0'; /* Make a copy (in the heap) of the stuff left in the absolutization @@ -1375,13 +1466,14 @@ path_p = abspath (cwd, filename); rel_buf_p = rel_buffer = (char *) xmalloc (filename_len); - while (*cwd_p && (*cwd_p == *path_p)) + while (*cwd_p && IS_SAME_PATH_CHAR (*cwd_p, *path_p)) { cwd_p++; path_p++; } - if (!*cwd_p && (!*path_p || *path_p == '/')) /* whole pwd matched */ + if (!*cwd_p && (!*path_p || IS_DIR_SEPARATOR (*path_p))) { + /* whole pwd matched */ if (!*path_p) /* input *is* the current path! */ return "."; else @@ -1393,7 +1485,7 @@ { --cwd_p; --path_p; - while (*cwd_p != '/') /* backup to last slash */ + while (! IS_DIR_SEPARATOR (*cwd_p)) /* backup to last slash */ { --cwd_p; --path_p; @@ -1404,8 +1496,8 @@ } /* Find out how many directory levels in cwd were *not* matched. */ - while (*cwd_p) - if (*cwd_p++ == '/') + while (*cwd_p++) + if (IS_DIR_SEPARATOR (*(cwd_p-1))) unmatched_slash_count++; /* Now we know how long the "short name" will be. @@ -1422,7 +1514,7 @@ return filename; *rel_buf_p++ = '.'; *rel_buf_p++ = '.'; - *rel_buf_p++ = '/'; + *rel_buf_p++ = DIR_SEPARATOR; } /* Then tack on the unmatched part of the desired file's name. */ @@ -1434,7 +1526,7 @@ while ((*rel_buf_p++ = *path_p++)); --rel_buf_p; - if (*(rel_buf_p-1) == '/') + if (IS_DIR_SEPARATOR (*(rel_buf_p-1))) *--rel_buf_p = '\0'; return rel_buffer; } @@ -1557,7 +1649,11 @@ { const char *filename_start = p = l + 3; - while (*p != ':') + while (*p != ':' +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1))) +#endif + ) p++; filename = (char *) alloca ((size_t) (p - filename_start) + 1); strncpy (filename, filename_start, (size_t) (p - filename_start)); @@ -1615,7 +1711,11 @@ const char *filename_start = p = l + 3; char *filename; - while (*p != ':') + while (*p != ':' +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1))) +#endif + ) p++; filename = (char *) alloca ((size_t) (p - filename_start) + 1); strncpy (filename, filename_start, (size_t) (p - filename_start)); @@ -1642,7 +1742,11 @@ const char *line_number_start = ++p; char line_number[10]; - while (*p != ':') + while (*p != ':' +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1))) +#endif + ) p++; strncpy (line_number, line_number_start, (size_t) (p - line_number_start)); line_number[p-line_number_start] = '\0'; @@ -2032,7 +2136,11 @@ temp_params[param_count++] = "-S"; temp_params[param_count++] = "-o"; +#if (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN)) + temp_params[param_count++] = "NUL"; +#else temp_params[param_count++] = "/dev/null"; +#endif /* Leave room for the input file name argument. */ input_file_name_index = param_count; @@ -2065,7 +2173,7 @@ compile_params[aux_info_file_name_index] = savestring2 (compile_params[input_file_name_index], strlen (compile_params[input_file_name_index]), - ".X", + PROTOIZE_AUX_INFO_SUFFIX, 2); if (!quiet_flag) @@ -2138,7 +2246,18 @@ /* Construct the aux_info filename from the base source filename. */ +#ifdef DJGPP + if (strncasecmp(base_source_filename,"$DJDIR",6)==0 && + IS_DIR_SEPARATOR(base_source_filename[6])) + { + strcpy (aux_info_filename, getenv("DJDIR")); + strcat (aux_info_filename, base_source_filename+5); + } + else + strcpy (aux_info_filename, base_source_filename); +#else strcpy (aux_info_filename, base_source_filename); +#endif strcat (aux_info_filename, aux_info_suffix); /* Check that the aux_info file exists and is readable. If it does not @@ -2256,10 +2375,16 @@ { int aux_info_file; + int fd_flags; /* Open the aux_info file. */ - if ((aux_info_file = my_open (aux_info_filename, O_RDONLY, 0444 )) == -1) + fd_flags = O_RDONLY; +#ifdef O_BINARY + /* Use binary mode to avoid having to deal with different EOL characters. */ + fd_flags |= O_BINARY; +#endif + if ((aux_info_file = my_open (aux_info_filename, fd_flags, 0444 )) == -1) { int errno_val = errno; notice ("%s: can't open aux info file `%s' for reading: %s\n", @@ -2324,7 +2449,11 @@ { char *p = aux_info_base; - while (*p != ':') + while (*p != ':' +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1))) +#endif + ) p++; p++; while (*p == ' ') @@ -2332,20 +2461,30 @@ invocation_filename = p; /* Save a pointer to first byte of path. */ while (*p != ' ') p++; - *p++ = '/'; + *p++ = DIR_SEPARATOR; *p++ = '\0'; while (*p++ != '\n') continue; aux_info_second_line = p; aux_info_relocated_name = 0; - if (invocation_filename[0] != '/') + if (! is_abspath (invocation_filename)) { /* INVOCATION_FILENAME is relative; append it to BASE_SOURCE_FILENAME's dir. */ char *dir_end; aux_info_relocated_name = xmalloc (base_len + (p-invocation_filename)); strcpy (aux_info_relocated_name, base_source_filename); - dir_end = strrchr (aux_info_relocated_name, '/'); + dir_end = strrchr (aux_info_relocated_name, DIR_SEPARATOR); +#ifdef DIR_SEPARATOR_2 + { + char *slash; + + slash = strrchr (dir_end ? dir_end : aux_info_relocated_name, + DIR_SEPARATOR_2); + if (slash) + dir_end = slash; + } +#endif if (dir_end) dir_end++; else @@ -2437,38 +2576,31 @@ { const char *filename = hp->symbol; int last_char_index = strlen (filename) - 1; - char *const new_filename = (char *) alloca (strlen (filename) + 1); + char *const new_filename = (char *) alloca (strlen (filename) + + strlen (cplus_suffix) + 1); /* Note that we don't care here if the given file was converted or not. It is possible that the given file was *not* converted, simply because there was nothing in it which actually required conversion. Even in this case, we want to do the renaming. Note that we only rename files with the .c - suffix. */ + suffix (except for the syscalls file, which is left alone). */ - if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.') + if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.' + || IS_SAME_PATH (syscalls_absolute_filename, filename)) return; strcpy (new_filename, filename); - new_filename[last_char_index] = 'C'; + strcpy (&new_filename[last_char_index], cplus_suffix); - if (my_link (filename, new_filename) == -1) + if (my_rename (filename, new_filename)) { int errno_val = errno; - notice ("%s: warning: can't link file `%s' to `%s': %s\n", + notice ("%s: warning: can't rename file `%s' to `%s': %s\n", pname, shortpath (NULL, filename), shortpath (NULL, new_filename), xstrerror (errno_val)); errors++; return; } - - if (my_unlink (filename) == -1) - { - int errno_val = errno; - notice ("%s: warning: can't delete file `%s': %s\n", - pname, shortpath (NULL, filename), xstrerror (errno_val)); - errors++; - return; - } } #endif /* !defined (UNPROTOIZE) */ @@ -4197,10 +4329,16 @@ { int input_file; + int fd_flags; /* Open the file to be converted in READ ONLY mode. */ - if ((input_file = my_open (convert_filename, O_RDONLY, 0444)) == -1) + fd_flags = O_RDONLY; +#ifdef O_BINARY + /* Use binary mode to avoid having to deal with different EOL characters. */ + fd_flags |= O_BINARY; +#endif + if ((input_file = my_open (convert_filename, fd_flags, 0444)) == -1) { int errno_val = errno; notice ("%s: can't open file `%s' for reading: %s\n", @@ -4347,36 +4485,38 @@ strcpy (new_filename, convert_filename); strcat (new_filename, save_suffix); - if (my_link (convert_filename, new_filename) == -1) + + if (my_access (new_filename, F_OK) == 0) + { + if (!quiet_flag) + notice ("%s: warning: file `%s' already saved in `%s'\n", + pname, + shortpath (NULL, convert_filename), + shortpath (NULL, new_filename)); + } + else if (my_rename (convert_filename, new_filename) == -1) { int errno_val = errno; - if (errno_val == EEXIST) - { - if (!quiet_flag) - notice ("%s: warning: file `%s' already saved in `%s'\n", - pname, - shortpath (NULL, convert_filename), - shortpath (NULL, new_filename)); - } - else - { - notice ("%s: can't link file `%s' to `%s': %s\n", - pname, - shortpath (NULL, convert_filename), - shortpath (NULL, new_filename), - xstrerror (errno_val)); - return; - } + notice ("%s: can't rename file `%s' to `%s': %s\n", + pname, + shortpath (NULL, convert_filename), + shortpath (NULL, new_filename), + xstrerror (errno_val)); + return; } } if (my_unlink (convert_filename) == -1) { int errno_val = errno; - notice ("%s: can't delete file `%s': %s\n", - pname, shortpath (NULL, convert_filename), - xstrerror (errno_val)); - return; + /* The file may have already been renamed. */ + if (errno_val != ENOENT) + { + notice ("%s: can't delete file `%s': %s\n", + pname, shortpath (NULL, convert_filename), + xstrerror (errno_val)); + return; + } } { @@ -4392,6 +4532,10 @@ xstrerror (errno_val)); return; } +#ifdef O_BINARY + /* Use binary mode to avoid changing the existing EOL character. */ + setmode (output_file, O_BINARY); +#endif /* Write the output file. */ @@ -4471,9 +4615,9 @@ } syscalls_len = strlen (syscalls_absolute_filename); - if (*(syscalls_absolute_filename + syscalls_len - 1) != '/') + if (! IS_DIR_SEPARATOR (*(syscalls_absolute_filename + syscalls_len - 1))) { - *(syscalls_absolute_filename + syscalls_len++) = '/'; + *(syscalls_absolute_filename + syscalls_len++) = DIR_SEPARATOR; *(syscalls_absolute_filename + syscalls_len) = '\0'; } strcat (syscalls_absolute_filename, syscalls_filename); @@ -4555,7 +4699,16 @@ int c; const char *params = ""; - pname = strrchr (argv[0], '/'); + pname = strrchr (argv[0], DIR_SEPARATOR); +#ifdef DIR_SEPARATOR_2 + { + char *slash; + + slash = strrchr (pname ? pname : argv[0], DIR_SEPARATOR_2); + if (slash) + pname = slash; + } +#endif pname = pname ? pname+1 : argv[0]; #ifdef HAVE_LC_MESSAGES --Message-Boundary-4105--