Hi,
I've been playing with compiling GNU Smalltalk-2.3.5 on MinGW and had some success. I have been able to build the code and "make check" passes with only one failure (quit.st), but some issues remain with paths that need further work and, probably, more knowledge of the internals of GNU Smalltalk than I have. With the enclosed changes applied, remaking the documentation will fail due to path issues and any paths supplied need to be in c:/some/where format rather than c:\some\where. I haven't extensively tested the program further than "make check" so other issues may be present too, but I'm posting my changes in the hope that they might be useful towards a full MinGW port. The build sequence I used was: * Run ./configure --without-readline --without-gmp * Edit the top Makefile and change `cygpath -w gsticon.ico` to just gsticon.ico * in the tests directory run unix2dos -o *.ok * Apply the enclosed changes to lib-src/poll.c, libgst/cint.c, libgst/sysdep.c, kernel/Directory.st, kernel/File.st and kernel/FileDescr.st * type make * type make again (the first make fails when rebuilding the classes doc) * make check (maybe more than once if it tries to rebuild the doc again) Freddie ## ---------------------- ## ## Detailed failed tests. ## ## ---------------------- ## # -*- compilation -*- 22. testsuite.at:48: testing ... ./testsuite.at:48: cd $abs_srcdir && $GST -r quit.st 2>&1 --- expout Thu Jun 14 13:21:23 2007 +++ /home/faa59/smalltalk-2.3.5/tests/testsuite.dir/at-stdout Thu Jun 14 13:21 :23 2007 @@ -1,2 +0,0 @@ -^M -Execution begins...^M 22. testsuite.at:48: 22. quit.st (testsuite.at:48): FAILED (testsuite.at:48) ## ---------------------- ## ## Code changes ## ## ---------------------- ## --- ../smalltalk-2.3.5-orig/lib-src/poll.c Wed Jan 3 10:51:30 2007 +++ lib-src/poll.c Thu Jun 14 13:55:29 2007 @@ -19,14 +19,45 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + #include "config.h" #include <sys/types.h> #include "poll.h" #include <errno.h> +#include <stdio.h> #include <limits.h> -#include <sys/socket.h> -#include <sys/select.h> +#include <windows.h> +#include <winsock2.h> +#include <io.h> + +#undef FD_ISSET +#define FD_ISSET(fd, set) my_fd_isset(fd, set) /* to avoid a WSA call */ + +static int my_fd_isset(int fd, fd_set* set) +{ + int i; + if (set == NULL) + { + return 0; + } + for(i=0; i < set->fd_count; i++) + { + if (set->fd_array[i] == fd) + { + return 1; + } + } + return 0; +} + +#define ESHUTDOWN WSAESHUTDOWN +#define ENOTCONN WSAENOTCONN +#define ECONNRESET WSAECONNRESET +#define ECONNABORTED WSAECONNABORTED +#define ENETRESET WSAENETRESET + +typedef int nfds_t; #include <unistd.h> #ifdef HAVE_SYS_IOCTL_H @@ -55,6 +86,76 @@ #define EOVERFLOW EINVAL #endif +// n = maxfd + 1 +#define MAX_WIN_HANDLES 300 +static int win_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *ptv) +{ + HANDLE handle_array[MAX_WIN_HANDLES]; + int handle_fd[MAX_WIN_HANDLES]; + fd_set* handle_set[MAX_WIN_HANDLES]; + int i; + DWORD ret, wait_timeout, nhandles = 0; + int nset, done; + done = 0; + nset = 0; + _flushall(); + for(i=0; i<n; i++) + { + if ((efds != NULL) && FD_ISSET(i, efds)) + { + FD_CLR(i, efds); /* assume no exceptions */ + } + if ((wfds != NULL) && FD_ISSET(i, wfds)) + { + handle_array[nhandles] = (HANDLE)_get_osfhandle(i); + handle_fd[nhandles] = i; + handle_set[nhandles] = wfds; + nhandles++; + FD_CLR(i, wfds); /* we will set it later if there is output */ + } + if ((rfds != NULL) && FD_ISSET(i, rfds)) + { + handle_array[nhandles] = (HANDLE)_get_osfhandle(i); + handle_fd[nhandles] = i; + handle_set[nhandles] = rfds; + nhandles++; + FD_CLR(i, rfds); /* we will set it later if there is input */ + } + } +/* do a quick poll - WaitForMultipleObjects only tells us if 1 handle + is ready and there may be more */ + for(i=0; i<nhandles; i++) + { + ret = WaitForSingleObject(handle_array[i], 0); + if (ret == WAIT_OBJECT_0) + { + FD_SET(handle_fd[i], handle_set[i]); + nset++; + } + } + if ((nset == 0) && (nhandles > 0)) // nothing set, so wait full time + { + if (ptv == NULL) + { + wait_timeout = INFINITE; + } + else + { + wait_timeout = ptv->tv_sec * 1000 + ptv->tv_usec / 1000; + } +/* Need to use MsgWaitForMultipleObjects and maybe pump messages if a GUI application? */ + + ret = WaitForMultipleObjectsEx(nhandles, handle_array, FALSE, wait_timeout, FALSE); + i = ret - WAIT_OBJECT_0; + if (i >= 0 && i < nhandles) + { + FD_SET(handle_fd[i], handle_set[i]); + nset++; + } + } + return nset; +} + int poll (pfd, nfd, timeout) struct pollfd *pfd; @@ -142,8 +243,9 @@ } /* examine fd sets */ - rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv); - if (rc < 0) + rc = win_select (maxfd + 1, &rfds, &wfds, &efds, ptv); + + if (rc < 0) return rc; /* establish results */ @@ -158,6 +260,7 @@ { int r; + char data[64]; #if defined __MACH__ && defined __APPLE__ /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK for some kinds of descriptors. Detect if this descriptor is a @@ -167,9 +270,9 @@ if (r == 0 || errno == ENOTSOCK) ioctl(pfd[i].fd, FIONREAD, &r); #else - char data[64]; - r = recv (pfd[i].fd, data, sizeof (data), MSG_PEEK); +// r = recv (pfd[i].fd, data, sizeof (data), MSG_PEEK); #endif + r = 1; if (r == 0) happened |= POLLHUP; --- ../smalltalk-2.3.5-orig/libgst/cint.c Thu Dec 7 08:09:12 2006 +++ libgst/cint.c Thu Jun 14 12:19:44 2007 @@ -341,7 +341,8 @@ times[0].tv_sec = new_atime + 86400 * 10957; times[1].tv_sec = new_mtime + 86400 * 10957; times[0].tv_usec = times[1].tv_usec = 0; - result = utimes (name, times); + result = 0; + printf("utimes called\n"); /* needs fixing */ if (!result) errno = 0; return (result); --- ../smalltalk-2.3.5-orig/libgst/sysdep.c Mon May 7 14:12:04 2007 +++ libgst/sysdep.c Thu Jun 14 12:18:17 2007 @@ -710,7 +710,7 @@ char *cwd; char *ret; unsigned path_max; - int save_errno; + int i, save_errno; path_max = (unsigned) PATH_MAX; path_max += 2; /* The getcwd docs say to do this. */ @@ -721,6 +721,11 @@ do { ret = getcwd (cwd, path_max); + for(i=0; i<strlen(cwd); i++) + { + if (cwd[i] == '\\') + cwd[i] = '/'; + } if (ret) return (cwd); --- ../smalltalk-2.3.5-orig/kernel/Directory.st Sun Feb 5 18:41:26 2006 +++ kernel/Directory.st Thu Jun 14 12:17:52 2007 @@ -108,6 +108,10 @@ directory isEmpty ifTrue: [ ^fileName ]. (fileName at: 1) = self pathSeparator ifTrue: [ ^fileName ]. + "Check to see if building up a windows absolute path from scratch i.e. appending X: to /" + ((directory = '/') and: [ (fileName size = 2) and: [ ((fileName at: 2) = $:) ]]) ifTrue: [ ^fileName ]. + "Check for a complete absolute windows path of form X:/" + ((fileName size >= 3) and: [ ((fileName at: 2) = $:) and: [ ((fileName at: 3) = $/) ]]) ifTrue: [ ^fileName ]. (self pathSeparator = $\ and: [ fileName size >= 2 and: [ (fileName at: 2) = $: ]]) ifTrue: [ ^fileName ]. ^(directory at: directory size) = self pathSeparator --- ../smalltalk-2.3.5-orig/kernel/File.st Sun Feb 5 18:41:26 2006 +++ kernel/File.st Thu Jun 14 12:17:00 2007 @@ -132,9 +132,19 @@ "Answer the full path to a file called `aString', resolving the `.' and `..' directory entries, and answer the result. `/..' is the same as '/'." - | path substrings | + | path substrings respath isAbsolute | + isAbsolute _ false. + "Windows paths starting X:/ are absolute" + (aString size >= 3) ifTrue: [ + ( ((aString at: 2) = $:) & ((aString at: 3) = $/) ) ifTrue: [ + isAbsolute _ true + ] + ]. + ((aString at: 1) = Directory pathSeparator) ifTrue: [ + isAbsolute _ true. + ]. path := OrderedCollection new. - (aString at: 1) = Directory pathSeparator ifFalse: [ + isAbsolute ifFalse: [ path addAll: (Directory working substrings: Directory pathSeparator). ]. substrings := aString substrings: Directory pathSeparator. @@ -148,9 +158,16 @@ ] ]. - ^path inject: '/' into: [ :old :each | + respath _ path inject: '/' into: [ :old :each | Directory append: each to: old - ] + ]. + "remove initial / from /C:/" + (respath size >= 4) ifTrue: [ + ( ((respath at: 1) = $/) & ((respath at: 3) = $:) & ((respath at: 4) = $/) ) ifTrue: [ + respath _ respath copyFrom: 2 + ] + ]. + ^respath ! ! --- ../smalltalk-2.3.5-orig/kernel/FileDescr.st Fri May 18 12:35:09 2007 +++ kernel/FileDescr.st Thu Jun 14 12:16:21 2007 @@ -103,7 +103,8 @@ finished with it anyway, using #close. To keep a file open even when no references exist anymore, send it #removeToBeFinalized" - ((fileName indexOfSubCollection: ':/') > 0 and: [ +"look for :// rather than :/ to avoid matching C:/some/where on windows" + ((fileName indexOfSubCollection: '://') > 0 and: [ fileMode = FileStream read ]) ifTrue: [ ^NetClients.URIResolver openStreamOn: fileName ]. _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Akeroyd, FA (Freddie) wrote:
> Hi, > > I've been playing with compiling GNU Smalltalk-2.3.5 on MinGW and had > some success. Great! > With the enclosed changes applied, remaking the > documentation will fail due to path issues and any paths supplied need > to be in c:/some/where format rather than c:\some\where. The attached patch, on top of 2.3.5, is my take on this. It fixes all path issues, so the only things left should be: 1) modifying _gst_set_file_access_times to use the appropriate Windows API function 2) figuring out what to do with poll 3) figuring out why tests are failing without unix2dos. One possibility could be the second patch I attach, please tell me if it works. Please send future patches relative to this one (I suggest that you create your own CVS/svn/Arch/git repository). Thanks! Paolo 2007-06-15 Freddie Akeroyd <[hidden email]> Paolo Bonzini <[hidden email]> * kernel/Character.st: Add #isPathSeparator. * kernel/Directory.st: Use it; add special cases for Win32 systems. * kernel/File.st: Use it; add special cases for Win32 systems. * kernel/FileDescr.st: Look for :// instead of :/ to distinguish URIs. * libgst/cint.c: Remove my_utime. * libgst/sysdep.c: Move it here as _gst_set_file_access_times. * libgst/sysdep.h: Declare it. * libgst/dict.c: Add CSymbols.PathSeparator. --- orig/Makefile.am +++ mod/Makefile.am @@ -107,7 +107,7 @@ DISTCLEANFILES += config.h # These two lines add a beatiful icon to the Win32 executable gsticon.o: gsticon.ico - echo ProgramIcon ICON `cygpath -w gsticon.ico` | windres -o gsticon.o + echo ProgramIcon ICON `$(CYGPATH_W) gsticon.ico` | windres -o gsticon.o gst.im: $(bin_PROGRAMS) $(srcdir)/kernel/stamp-classes SMALLTALK_KERNEL="`cd $(srcdir)/kernel; pwd`" \ --- orig/configure.ac +++ mod/configure.ac @@ -215,7 +215,7 @@ AC_REPLACE_FUNCS(putenv strdup strerror getdtablesize strstr ftruncate floorl ceill sqrtl frexpl ldexpl asinl \ acosl atanl logl expl tanl sinl cosl truncl lrintl strsep strpbrk) AC_CHECK_FUNCS_ONCE(gethostname memcpy memmove sighold uname sbrk usleep lstat \ - grantpt popen getrusage gettimeofday getcwd fork strchr \ + grantpt popen getrusage gettimeofday getcwd fork strchr utimes \ sigsetmask alarm select mprotect madvise nl_langinfo waitpid \ setsid spawnl nanosleep pread pwrite) --- orig/kernel/Character.st +++ mod/kernel/Character.st @@ -258,6 +258,12 @@ isPunctuation ^(Table at: 1 + codePoint ifAbsent: [ 0 ]) = 4 ! +isPathSeparator + "Returns true if self is a path separator ($/ or $\ under Windows, + $/ only under Unix systems including Mac OS X). + ^self == $/ or: [ self == Directory pathSeparator ] +! + isVowel "Returns true if self is a, e, i, o, or u; case insensitive" | char | --- orig/kernel/Directory.st +++ mod/kernel/Directory.st @@ -106,26 +106,33 @@ append: fileName to: directory "Answer the name of a file named `fileName' which resides in a directory named `directory'." directory isEmpty ifTrue: [ ^fileName ]. - (fileName at: 1) = self pathSeparator - ifTrue: [ ^fileName ]. - (self pathSeparator = $\ and: [ fileName size >= 2 and: [ - (fileName at: 2) = $: ]]) ifTrue: [ ^fileName ]. - ^(directory at: directory size) = self pathSeparator + self pathSeparator == $\ + ifFalse: [ + (fileName at: 1) isPathSeparator ifTrue: [ ^fileName ] ] + ifTrue: [ + (fileName at: 1) isPathSeparator ifTrue: [ + ^(directory size >= 2 and: [ (directory at: 2) = $: ]) + ifTrue: [ '%1:%2' bindWith: directory first with: fileName ] + ifFalse: [ fileName ] ]. + (fileName size >= 2 and: [ (fileName at: 2) = $: ]) + ifTrue: [ ^fileName ] ]. + + ^(directory at: directory size) isPathSeparator ifTrue: [ directory, fileName ] ifFalse: [ '%1%2%3' bindWith: directory - with: self pathSeparatorString + with: self pathSeparator with: fileName ] ! pathSeparator "Answer (as a Character) the character used to separate directory names" - ^$/ + ^CSymbols.PathSeparator ! pathSeparatorString "Answer (in a String) the character used to separate directory names" - ^'/' + ^String with: self pathSeparator ! ! --- orig/kernel/File.st +++ mod/kernel/File.st @@ -132,9 +132,18 @@ fullNameFor: aString "Answer the full path to a file called `aString', resolving the `.' and `..' directory entries, and answer the result. `/..' is the same as '/'." - | path substrings | + | path substrings result isAbsolute isWindows | + + isAbsolute := (aString at: 1) isPathSeparator. + isWindows := Directory pathSeparator == $\. + "Windows paths starting X:/ are absolute" + (isWindows and: [ + aString size >= 3 and: [ + (aString at: 2) = $: and: [ + (aString at: 3) isPathSeparator ]]]) ifTrue: [ isAbsolute := true ]. + path := OrderedCollection new. - (aString at: 1) = Directory pathSeparator ifFalse: [ + isAbsolute ifFalse: [ path addAll: (Directory working substrings: Directory pathSeparator). ]. substrings := aString substrings: Directory pathSeparator. @@ -148,9 +157,18 @@ fullNameFor: aString ] ]. - ^path inject: '/' into: [ :old :each | - Directory append: each to: old - ] + result := path inject: Directory pathSeparatorString into: [ :old :each | + Directory append: each to: old + ]. + + "Remove initial / from /C:/" + ^(isWindows and: [ + result size >= 4 and: [ + (result at: 1) isPathSeparator and: [ + (result at: 3) = $: and: [ + (result at: 4) isPathSeparator ]]]]) + ifTrue: [ result copyFrom: 2 ] + ifFalse: [ result ] ! pathFrom: srcName to: destName --- orig/kernel/FileDescr.st +++ mod/kernel/FileDescr.st @@ -103,7 +103,7 @@ open: fileName mode: fileMode finished with it anyway, using #close. To keep a file open even when no references exist anymore, send it #removeToBeFinalized" - ((fileName indexOfSubCollection: ':/') > 0 and: [ + ((fileName indexOfSubCollection: '://') > 0 and: [ fileMode = FileStream read ]) ifTrue: [ ^NetClients.URIResolver openStreamOn: fileName ]. --- orig/libgst/cint.c +++ mod/libgst/cint.c @@ -332,22 +332,6 @@ get_errno (void) } int -my_utime (const char *name, - long new_atime, - long new_mtime) -{ - struct timeval times[2]; - int result; - times[0].tv_sec = new_atime + 86400 * 10957; - times[1].tv_sec = new_mtime + 86400 * 10957; - times[0].tv_usec = times[1].tv_usec = 0; - result = utimes (name, times); - if (!result) - errno = 0; - return (result); -} - -int my_stat (const char *name, gst_stat * out) { @@ -539,7 +523,7 @@ _gst_init_cfuncs (void) _gst_define_cfunc ("strerror", strerror); _gst_define_cfunc ("stat", my_stat); _gst_define_cfunc ("lstat", my_lstat); - _gst_define_cfunc ("utime", my_utime); + _gst_define_cfunc ("utime", _gst_set_file_access_times); _gst_define_cfunc ("opendir", my_opendir); _gst_define_cfunc ("closedir", closedir); --- orig/libgst/dict.c +++ mod/libgst/dict.c @@ -1088,6 +1088,14 @@ init_c_symbols () #define NAN (0.0 / 0.0) #endif +#if defined WIN32 && !defined __CYGWIN__ + NAMESPACE_AT_PUT (cSymbolsOOP, _gst_intern_string ("PathSeparator"), + CHAR_OOP_AT ('\\')); +#else + NAMESPACE_AT_PUT (cSymbolsOOP, _gst_intern_string ("PathSeparator"), + CHAR_OOP_AT ('/')); +#endif + NAMESPACE_AT_PUT (cSymbolsOOP, _gst_intern_string ("CDoubleMin"), floatd_new (DBL_MIN)); NAMESPACE_AT_PUT (cSymbolsOOP, _gst_intern_string ("CDoubleMax"), --- orig/libgst/sysdep.c +++ mod/libgst/sysdep.c @@ -745,6 +745,21 @@ _gst_get_cur_dir_name (void) } +int +_gst_set_file_access_times (const char *name, long new_atime, long new_mtime) +{ + struct timeval times[2]; + int result; + times[0].tv_sec = new_atime + 86400 * 10957; + times[1].tv_sec = new_mtime + 86400 * 10957; + times[0].tv_usec = times[1].tv_usec = 0; + result = utimes (name, times); + if (!result) + errno = 0; + return (result); +} + + char * _gst_get_full_file_name (const char *fileName) { --- orig/libgst/sysdep.h +++ mod/libgst/sysdep.h @@ -138,6 +138,12 @@ extern time_t _gst_get_time (void) extern time_t _gst_get_file_modify_time (const char *fileName) ATTRIBUTE_HIDDEN; +/* Sets the time when FILENAME was last modified. The times are in + seconds, relative to 1 Jan 2000. */ +extern int _gst_set_file_access_times (const char *name, long new_atime, + long new_mtime) + ATTRIBUTE_HIDDEN; + /* Converts the given time (expressed in seconds since midnight Jan 1, 1970, and in Universal Coordinated Time) into a local time. */ extern time_t _gst_adjust_time_zone (time_t t) --- orig/tests/testsuite +++ mod/tests/testsuite @@ -1224,6 +1224,10 @@ else at_diff=diff fi +if at_diff2=`diff --strip-trailing-cr "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff2" +then + at_diff="$at_diff --strip-trailing-cr" +fi for at_group in $at_groups do _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
In reply to this post by Akeroyd, FA (Freddie)
Akeroyd, FA (Freddie) wrote:
> Thanks for the patches ... unfortunately I've been busier today than I > though and so haven't been able to try them out properly, but will be > able to do that next week. With regard to patch 2 for the testsuite, I > think what you suggest would work but unfortunately the diff supplied > with MinGW does not seem to support that option. Using "diff > --ignore-space-change" works, but is not an ideal solution. Could you check instead if "sed b < foo > bar" has the same effect as "unix2dos"? Thanks, Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
In reply to this post by Akeroyd, FA (Freddie)
> The attached patch, on top of 2.3.5, is my take on this. It fixes all > path issues, so the only things left should be: I've rebuilt my MinGW version using the supplied patches and the program compiles and creates an image OK. There are, however, two test failures on a make check (quit.st and fileext.st). The quit test is probably to do with buffer flushing at program exit and I will look at that; the details of the filext failure are: 18. testsuite.at:44: testing ... ./testsuite.at:44: cd $abs_srcdir && $GST -r fileext.st 2>&1 --- expout Mon Jun 18 13:54:50 2007 +++ tests/testsuite.dir/at-stdout Mon Jun 18 13:54:50 2007 @@ -11,18 +11,18 @@ true true true +false true true true true +false true true true true true -true -true -true +false true true true 18. testsuite.at:44: 18. fileext.st (testsuite.at:44): FAILED (testsuite.at:44) Also if I try to rebuild the documentation with touch kernel/File.st make It fails with the following error: Making all in doc make[2]: Entering directory `/home/faa59/Smalltalk_gnu/smalltalk-2.3.5/doc' rm -f ./classes.texi builddir=`pwd`; gst=$builddir/../gst; gst_im=$builddir/../gst.im; \ cd . && \ $gst -I $gst_im -f ../scripts/GenBaseDoc.st \ Smalltalk SystemExceptions NetClients VFS writing documentation for AbstractNamespace Object: FileStream error: could not open C:\msys\1.0\home\faa59\Smalltalk_gnu\smalltalk-2.3.5/C:/msys/1.0/home/fa a59/Smalltalk_gnu/smalltalk-2.3.5/kernel/AbstNamespc.st SystemExceptions.FileError(Exception)>>#signal SystemExceptions.FileError class(Exception class)>>#signal: [] in FileStream class(FileDescriptor class)>>#open:mode: [] in FileStream class(FileDescriptor class)>>#fopen:mode:ifFail: FileStream(FileDescriptor)>>#fileOp:with:with:ifFail: FileStream class(FileDescriptor class)>>#fopen:mode:ifFail: VFS.RealFileHandler>>#open:mode:ifFail: FileStream class(FileDescriptor class)>>#open:mode: FileSegment>>#withFileDo: FileSegment>>#asString MethodInfo>>#sourceString > Could you check instead if "sed b < foo > bar" has the same effect as "unix2dos"? Unfortunately not - no \r characters are added to the lines and so the tests still fail. However the Windows putchar() function intercepts a bare \n and substitutes \r\n so the following piece of C code will do the conversion on windows and leave things unchanged on unix: #include <stdio.h> int main(int argc, char* argv[]) { int c; while( (c = getchar()) != EOF ) { putchar(c); } return 0; } > modifying _gst_set_file_access_times to use the appropriate Windows API function Windows provides an implementation of the POSIX utime() function which should do the job for us. I notice the current code uses utimes() rather than utime() - is utimes() generally more widely available or is this usage purely for historical reasons? Freddie _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
> Object: FileStream error: could not open > C:\msys\1.0\home\faa59\Smalltalk_gnu\smalltalk-2.3.5/C:/msys/1.0/home/fa > a59/Smalltalk_gnu/smalltalk-2.3.5/kernel/AbstNamespc.st You should find out how the problematic path is built (see kernel/MethodInfo.st as well as examples/Publish.st). You can try (AbstractNamespace >> #superspace) methodSourceCode fileName to see if the bad path is generated by GNU Smalltalk itself, or rather by something in kernel/File.st or kernel/Directory.st (in which case there is something more to fix there). I tried the obvious test: Directory append: 'C:/msys/1.0/home/faa59/Smalltalk_gnu/smalltalk-2.3.5/kernel/AbstNamespc.st' to: 'C:\msys\1.0\home\faa59\Smalltalk_gnu\smalltalk-2.3.5' but it gave correctly 'C:/msys/1.0/home/faa59/Smalltalk_gnu/smalltalk-2.3.5/kernel/AbstNamespc.st' >> Could you check instead if "sed b < foo > bar" has the same effect as > "unix2dos"? > > Unfortunately not - no \r characters are added to the lines and so the > tests still fail. However the Windows putchar() function intercepts a > bare \n and substitutes \r\n so the following piece of C code will do > the conversion on windows and leave things unchanged on unix: Okay, then I prefer stripping \r from GNU Smalltalk's output. :-) >> modifying _gst_set_file_access_times to use the appropriate Windows >> API function > > Windows provides an implementation of the POSIX utime() function which > should do the job for us. I notice the current code uses utimes() rather > than utime() - is utimes() generally more widely available or is this > usage purely for historical reasons? utime provides only 1-second resolution. That's fine for GNU Smalltalk though. The attached patch (to be applied on top of the previous one) implements this. Paolo --- orig/configure.ac +++ mod/configure.ac @@ -186,7 +186,7 @@ AC_DEFINE(_GNU_SOURCE, 1, [We want the d AC_HEADER_ASSERT AC_CHECK_HEADERS_ONCE(stdint.h inttypes.h unistd.h poll.h sys/ioctl.h \ sys/resource.h sys/utsname.h stropts.h sys/param.h stddef.h limits.h \ - sys/timeb.h termios.h sys/mman.h sys/file.h execinfo.h \ + sys/timeb.h termios.h sys/mman.h sys/file.h execinfo.h utime.h \ sys/wait.h fcntl.h, [], [], [AC_INCLUDES_DEFAULT]) AC_TYPE_INT8_T @@ -215,7 +215,7 @@ AC_REPLACE_FUNCS(putenv strdup strerror getdtablesize strstr ftruncate floorl ceill sqrtl frexpl ldexpl asinl \ acosl atanl logl expl tanl sinl cosl truncl lrintl strsep strpbrk) AC_CHECK_FUNCS_ONCE(gethostname memcpy memmove sighold uname sbrk usleep lstat \ - grantpt popen getrusage gettimeofday getcwd fork strchr utimes \ + grantpt popen getrusage gettimeofday getcwd fork strchr utimes utime \ sigsetmask alarm select mprotect madvise nl_langinfo waitpid \ setsid spawnl nanosleep pread pwrite) --- orig/libgst/sysdep.c +++ mod/libgst/sysdep.c @@ -58,6 +58,10 @@ #include "gstpriv.h" +#ifdef HAVE_UTIME_H +# include <utime.h> +#endif + #ifdef HAVE_SYS_TIMES_H # include <sys/times.h> #endif @@ -745,11 +749,22 @@ _gst_get_cur_dir_name (void) _gst_set_file_access_times (const char *name, long new_atime, long new_mtime) { int result; +#if defined HAVE_UTIMES struct timeval times[2]; times[0].tv_sec = new_atime + 86400 * 10957; times[1].tv_sec = new_mtime + 86400 * 10957; times[0].tv_usec = times[1].tv_usec = 0; result = utimes (name, times); +#elif defined HAVE_UTIME + struct utimbuf utb; + utb.actime = new_atime + 86400 * 10957; + utb.modtime = new_mtime + 86400 * 10957; + result = utime (name, &utb); +#else +#warning neither utime nor utimes are available. + errno = ENOSYS; + result = -1; +#endif if (!result) errno = 0; return (result); --- orig/tests/fileext.st +++ mod/tests/fileext.st @@ -72,4 +72,5 @@ testStripExtensionFrom [(File stripExtensionFrom: each key), (File extensionFor: each key) = each key] value printNl ]! ! +CSymbols.PathSeparator := $/. Object new testExtensionFor; testStripExtensionFrom! --- orig/tests/local.at +++ mod/tests/local.at @@ -25,7 +25,7 @@ m4_define([AT_CHECK_GST], [ *) GST="$AUTOTEST_PATH/gst m4_ifval([$2], [-I $2])" ;; esac - AT_CHECK([cd m4_ifval([$3], [$3], [$abs_top_builddir]) && $GST $1], 0, [$4], [$5]) + AT_CHECK([cd m4_ifval([$3], [$3], [$abs_top_builddir]) && $GST $1 | tr -d '\r'], 0, [$4], [$5]) ]) dnl AT_DIFF_TEST([FILE], [XFAILS]) _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Hi,
> You should find out how the problematic path is built (see > kernel/MethodInfo.st as well as examples/Publish.st). You can try > (AbstractNamespace >> #superspace) methodSourceCode fileName > to see if the bad path is generated by GNU Smalltalk itself, or rather This gave 'C:\msys\1.0\home\faa59\Smalltalk_gnu\smalltalk-2.3.5/C:/msys/1.0/home/f aa59/Smalltalk_gnu/smalltalk-2.3.5/kernel/AbstNamespc.st' I applied the enclosed patch to File.st and that fixed the "make doc" of the library, but it is not the end of the story as now rebuilding the Blox documentation fails with invalid paths. The File.st patch does not make the methodSourceCode filename above correct, it just allows Smalltalk to handle it in the library case. I think the cause of the problem is illustrated by running: (File fullNameFor: 'c:\some\rubbish\c:\windows') printNl! Which returns c:\windows So (Directory exists: 'c:\some\rubbish\c:\windows') will return true. I believe the Blox doc issue occurs as the paths being built up in the baseDirs method of the Package are using "Directory exists:" and thus getting told incorrect information which they then store. The root of the problem probably lies with how to treat c: when it is detected in the "Directory append:" method as bits of a path are passed to it. In the above example the first c: should indicate the start an absolute path, but not the second c: as that then leads to an incorrect result. Freddie _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk File.patch (966 bytes) Download Attachment |
Akeroyd, FA (Freddie) wrote:
> Hi, > >> You should find out how the problematic path is built (see >> kernel/MethodInfo.st as well as examples/Publish.st). You can try > >> (AbstractNamespace >> #superspace) methodSourceCode fileName > >> to see if the bad path is generated by GNU Smalltalk itself, or rather > > > This gave > > 'C:\msys\1.0\home\faa59\Smalltalk_gnu\smalltalk-2.3.5/C:/msys/1.0/home/f > aa59/Smalltalk_gnu/smalltalk-2.3.5/kernel/AbstNamespc.st' > > I applied the enclosed patch to File.st The patch is fine, I'm applying it. The bug you found in fullNameFor: is also real; to fix it, you can simply use "old, self pathSeparatorString, each" instead of "Directory append: each to: old". The real problem however is in _gst_get_full_file_name, which also needs to know about Windows paths. Something like this should do (in libgst/sysdep.c): char * _gst_get_full_file_name (const char *fileName) { char *fullFileName; static char *fullPath = NULL; /* Absolute paths don't need to change */ if (fileName[0] == '/') return (xstrdup (fileName)); #if defined WIN32 && !defined __CYGWIN__ if (fileName[0] == '\\' || (fileName[0] != '\0' && fileName[1] == ':')) return (xstrdup (fileName)); #endif /* Only need to do this once, then cache the result */ if (fullPath == NULL) fullPath = _gst_get_cur_dir_name (); #if !defined WIN32 || defined __CYGWIN__ asprintf (&fullFileName, "%s/%s", fullPath, fileName); #else asprintf (&fullFileName, "%s\\%s", fullPath, fileName); #endif return (fullFileName); } For 3.0 I will use the Win32 API function GetFullPathName (this piece of code changed completely), but for now this should be enough. Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On Tue, 2007-06-19 at 14:22 +0200, Paolo Bonzini wrote:
> The bug you found in fullNameFor: is also real; to fix it, you can > simply use "old, self pathSeparatorString, each" instead of "Directory Or, better yet, "{old. self pathSeparatorString. each} joinAll", in devo. :) -- ;;; Stephen Compall ** http://scompall.nocandysw.com/blog ** "Peta" is Greek for fifth; a petabyte is 10 to the fifth power, as well as fifth in line after kilo, mega, giga, and tera. -- Lee Gomes, performing every Wednesday in his tech column "Portals" on page B1 of The Wall Street Journal _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk signature.asc (196 bytes) Download Attachment |
In reply to this post by Paolo Bonzini
Akeroyd, FA (Freddie) wrote:
> Hi, > > Your suggestions seem to sort everything out - thanks. I'll see if I can > get everything into a patch kit for you today, but otherwise it will be > the end of next week as I'm away from lunchtime today. Thanks! Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |