Move cd and cwd primitives to native I/O, fix Windows normalize-pathname

db4
Slava Pestov 2008-02-05 13:11:36 -06:00
parent 751a1da3d2
commit ba1a958a32
18 changed files with 93 additions and 93 deletions

View File

@ -553,8 +553,6 @@ builtins get num-tags get tail f union-class define-class
{ "millis" "system" } { "millis" "system" }
{ "type" "kernel.private" } { "type" "kernel.private" }
{ "tag" "kernel.private" } { "tag" "kernel.private" }
{ "cwd" "io.files" }
{ "cd" "io.files" }
{ "modify-code-heap" "compiler.units" } { "modify-code-heap" "compiler.units" }
{ "dlopen" "alien" } { "dlopen" "alien" }
{ "dlsym" "alien" } { "dlsym" "alien" }

View File

@ -1,11 +1,11 @@
! Copyright (C) 2004, 2007 Slava Pestov. ! Copyright (C) 2004, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: init command-line namespaces words debugger io USING: init command-line namespaces words debugger io
kernel.private math memory continuations kernel io.files kernel.private math memory continuations kernel io.files
io.backend system parser vocabs sequences prettyprint io.backend system parser vocabs sequences prettyprint
vocabs.loader combinators splitting source-files strings vocabs.loader combinators splitting source-files strings
definitions assocs compiler.errors compiler.units definitions assocs compiler.errors compiler.units
math.parser ; math.parser generic ;
IN: bootstrap.stage2 IN: bootstrap.stage2
! Wrap everything in a catch which starts a listener so ! Wrap everything in a catch which starts a listener so
@ -88,5 +88,5 @@ IN: bootstrap.stage2
"output-image" get resource-path save-image-and-exit "output-image" get resource-path save-image-and-exit
] if ] if
] [ ] [
print-error :c "listener" vocab-main execute print-error :c "listener" vocab-main execute 1 exit
] recover ] recover

View File

@ -52,12 +52,12 @@ HELP: <file-appender>
{ $description "Outputs an output stream for writing to the specified pathname. The stream begins writing at the end of the file." } { $description "Outputs an output stream for writing to the specified pathname. The stream begins writing at the end of the file." }
{ $errors "Throws an error if the file cannot be opened for writing." } ; { $errors "Throws an error if the file cannot be opened for writing." } ;
HELP: cwd ( -- path ) HELP: cwd
{ $values { "path" "a pathname string" } } { $values { "path" "a pathname string" } }
{ $description "Outputs the current working directory of the Factor process." } { $description "Outputs the current working directory of the Factor process." }
{ $errors "Windows CE has no concept of ``current directory'', so this word throws an error there." } ; { $errors "Windows CE has no concept of ``current directory'', so this word throws an error there." } ;
HELP: cd ( path -- ) HELP: cd
{ $values { "path" "a pathname string" } } { $values { "path" "a pathname string" } }
{ $description "Changes the current working directory of the Factor process." } { $description "Changes the current working directory of the Factor process." }
{ $errors "Windows CE has no concept of ``current directory'', so this word throws an error there." } ; { $errors "Windows CE has no concept of ``current directory'', so this word throws an error there." } ;

View File

@ -1,10 +1,14 @@
! Copyright (C) 2004, 2007 Slava Pestov. ! Copyright (C) 2004, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
IN: io.files IN: io.files
USING: io.backend io.files.private io hashtables kernel math USING: io.backend io.files.private io hashtables kernel math
memory namespaces sequences strings assocs arrays definitions memory namespaces sequences strings assocs arrays definitions
system combinators splitting sbufs ; system combinators splitting sbufs ;
HOOK: cd io-backend ( path -- )
HOOK: cwd io-backend ( -- path )
HOOK: <file-reader> io-backend ( path -- stream ) HOOK: <file-reader> io-backend ( path -- stream )
HOOK: <file-writer> io-backend ( path -- stream ) HOOK: <file-writer> io-backend ( path -- stream )

View File

@ -1,9 +1,16 @@
! Copyright (C) 2005, 2007 Slava Pestov. ! Copyright (C) 2005, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: io.backend io.nonblocking io.unix.backend io.files io USING: io.backend io.nonblocking io.unix.backend io.files io
unix kernel math continuations math.bitfields ; unix kernel math continuations math.bitfields ;
IN: io.unix.files IN: io.unix.files
M: unix-io cwd
MAXPATHLEN dup <byte-array> getcwd
[ alien>char-string ] [ (io-error) ] if* ;
M: unix-io cd
chdir io-error ;
: read-flags O_RDONLY ; inline : read-flags O_RDONLY ; inline
: open-read ( path -- fd ) : open-read ( path -- fd )

View File

@ -2,45 +2,10 @@ USING: alien alien.c-types arrays assocs combinators
continuations destructors io io.backend io.nonblocking continuations destructors io io.backend io.nonblocking
io.windows libc kernel math namespaces sequences io.windows libc kernel math namespaces sequences
threads tuples.lib windows windows.errors windows.kernel32 threads tuples.lib windows windows.errors windows.kernel32
strings splitting io.files qualified ascii ; strings splitting io.files qualified ascii combinators.lib ;
QUALIFIED: windows.winsock QUALIFIED: windows.winsock
IN: io.windows.nt.backend IN: io.windows.nt.backend
: unicode-prefix ( -- seq )
"\\\\?\\" ; inline
M: windows-nt-io root-directory? ( path -- ? )
dup length 2 = [
dup first Letter?
swap second CHAR: : = and
] [
drop f
] if ;
M: windows-nt-io normalize-pathname ( string -- string )
dup string? [ "pathname must be a string" throw ] unless
"/" split "\\" join
{
! empty
{ [ dup empty? ] [ "empty path" throw ] }
! .\\foo
{ [ dup ".\\" head? ] [
>r unicode-prefix cwd r> 1 tail 3append
] }
! c:\\foo
{ [ dup 1 tail ":" head? ] [ >r unicode-prefix r> append ] }
! \\\\?\\c:\\foo
{ [ dup unicode-prefix head? ] [ ] }
! foo.txt ..\\foo.txt
{ [ t ] [
[
unicode-prefix % cwd %
dup first CHAR: \\ = [ CHAR: \\ , ] unless %
] "" make
] }
} cond [ "/\\." member? ] right-trim
dup peek CHAR: : = [ "\\" append ] when ;
SYMBOL: io-hash SYMBOL: io-hash
TUPLE: io-callback port continuation ; TUPLE: io-callback port continuation ;

View File

@ -1,8 +1,64 @@
USING: continuations destructors io.buffers io.nonblocking USING: continuations destructors io.buffers io.files io.backend
io.windows io.windows.nt.backend kernel libc math threads io.nonblocking io.windows io.windows.nt.backend kernel libc math
windows windows.kernel32 ; threads windows windows.kernel32 alien.c-types alien.arrays
sequences combinators combinators.lib ascii splitting alien
strings ;
IN: io.windows.nt.files IN: io.windows.nt.files
M: windows-nt-io cwd
MAX_UNICODE_PATH dup "ushort" <c-array>
[ GetCurrentDirectory win32-error=0/f ] keep
alien>u16-string ;
M: windows-nt-io cd
SetCurrentDirectory win32-error=0/f ;
: unicode-prefix ( -- seq )
"\\\\?\\" ; inline
M: windows-nt-io root-directory? ( path -- ? )
dup length 2 = [
dup first Letter?
swap second CHAR: : = and
] [
drop f
] if ;
: root-directory ( string -- string' )
{
[ dup length 2 >= ]
[ dup second CHAR: : = ]
[ dup first Letter? ]
} && [ 2 head ] [ "Not an absolute path" throw ] if ;
: prepend-prefix ( string -- string' )
unicode-prefix swap append ;
: windows-path+ ( cwd path -- newpath )
{
! empty
{ [ dup empty? ] [ "empty path" throw ] }
! \\\\?\\c:\\foo
{ [ dup unicode-prefix head? ] [ nip ] }
! ..\\foo
{ [ dup "..\\" head? ] [ >r parent-directory r> 2 tail windows-path+ ] }
! .\\foo
{ [ dup ".\\" head? ] [ 1 tail append prepend-prefix ] }
! \\foo
{ [ dup "\\" head? ] [ >r root-directory r> append prepend-prefix ] }
! c:\\foo
{ [ dup second CHAR: : = ] [ nip prepend-prefix ] }
! foo.txt
{ [ t ] [ [ first CHAR: \\ = "" "\\" ? ] keep 3append prepend-prefix ] }
} cond ;
M: windows-nt-io normalize-pathname ( string -- string )
dup string? [ "pathname must be a string" throw ] unless
"/" split "\\" join
cwd swap windows-path+
[ "/\\." member? ] right-trim
dup peek CHAR: : = [ "\\" append ] when ;
M: windows-nt-io CreateFile-flags ( DWORD -- DWORD ) M: windows-nt-io CreateFile-flags ( DWORD -- DWORD )
FILE_FLAG_OVERLAPPED bitor ; FILE_FLAG_OVERLAPPED bitor ;

View File

@ -1,4 +1,4 @@
USING: io.files kernel tools.test ; USING: io.files kernel tools.test io.backend splitting ;
IN: temporary IN: temporary
[ "c:\\foo\\" ] [ "c:\\foo\\bar" parent-directory ] unit-test [ "c:\\foo\\" ] [ "c:\\foo\\bar" parent-directory ] unit-test
@ -14,3 +14,7 @@ IN: temporary
[ f ] [ "c:\\foo" root-directory? ] unit-test [ f ] [ "c:\\foo" root-directory? ] unit-test
[ f ] [ "." root-directory? ] unit-test [ f ] [ "." root-directory? ] unit-test
[ f ] [ ".." root-directory? ] unit-test [ f ] [ ".." root-directory? ] unit-test
[ ] [ "" resource-path cd ] unit-test
[ "\\foo\\bar" ] [ "/foo/bar" normalize-pathname ":" split1 nip ] unit-test

2
extra/unix/bsd/bsd.factor Normal file → Executable file
View File

@ -5,6 +5,8 @@ USING: alien.syntax ;
! FreeBSD ! FreeBSD
: MAXPATHLEN 1024 ; inline
: O_RDONLY HEX: 0000 ; inline : O_RDONLY HEX: 0000 ; inline
: O_WRONLY HEX: 0001 ; inline : O_WRONLY HEX: 0001 ; inline
: O_RDWR HEX: 0002 ; inline : O_RDWR HEX: 0002 ; inline

2
extra/unix/linux/linux.factor Normal file → Executable file
View File

@ -5,6 +5,8 @@ USING: alien.syntax ;
! Linux. ! Linux.
: MAXPATHLEN 1024 ; inline
: O_RDONLY HEX: 0000 ; inline : O_RDONLY HEX: 0000 ; inline
: O_WRONLY HEX: 0001 ; inline : O_WRONLY HEX: 0001 ; inline
: O_RDWR HEX: 0002 ; inline : O_RDWR HEX: 0002 ; inline

View File

@ -124,6 +124,7 @@ FUNCTION: void freeaddrinfo ( addrinfo* ai ) ;
FUNCTION: int futimes ( int id, timeval[2] times ) ; FUNCTION: int futimes ( int id, timeval[2] times ) ;
FUNCTION: char* gai_strerror ( int ecode ) ; FUNCTION: char* gai_strerror ( int ecode ) ;
FUNCTION: int getaddrinfo ( char* hostname, char* servname, addrinfo* hints, addrinfo** res ) ; FUNCTION: int getaddrinfo ( char* hostname, char* servname, addrinfo* hints, addrinfo** res ) ;
FUNCTION: char* getcwd ( char* buf, size_t size ) ;
FUNCTION: int getdtablesize ; FUNCTION: int getdtablesize ;
FUNCTION: gid_t getegid ; FUNCTION: gid_t getegid ;
FUNCTION: uid_t geteuid ; FUNCTION: uid_t geteuid ;

View File

@ -892,7 +892,8 @@ FUNCTION: DWORD GetConsoleTitleW ( LPWSTR lpConsoleTitle, DWORD nSize ) ;
! FUNCTION: GetCurrentActCtx ! FUNCTION: GetCurrentActCtx
! FUNCTION: GetCurrentConsoleFont ! FUNCTION: GetCurrentConsoleFont
! FUNCTION: GetCurrentDirectoryA ! FUNCTION: GetCurrentDirectoryA
! FUNCTION: GetCurrentDirectoryW FUNCTION: BOOL GetCurrentDirectoryW ( DWORD len, LPTSTR buf ) ;
: GetCurrentDirectory GetCurrentDirectoryW ; inline
FUNCTION: HANDLE GetCurrentProcess ( ) ; FUNCTION: HANDLE GetCurrentProcess ( ) ;
! FUNCTION: GetCurrentProcessId ! FUNCTION: GetCurrentProcessId
FUNCTION: HANDLE GetCurrentThread ( ) ; FUNCTION: HANDLE GetCurrentThread ( ) ;
@ -1387,7 +1388,8 @@ FUNCTION: BOOL SetConsoleTitleW ( LPCWSTR lpConsoleTitle ) ;
! FUNCTION: SetCPGlobal ! FUNCTION: SetCPGlobal
! FUNCTION: SetCriticalSectionSpinCount ! FUNCTION: SetCriticalSectionSpinCount
! FUNCTION: SetCurrentDirectoryA ! FUNCTION: SetCurrentDirectoryA
! FUNCTION: SetCurrentDirectoryW FUNCTION: BOOL SetCurrentDirectoryW ( LPCWSTR lpDirectory ) ;
: SetCurrentDirectory SetCurrentDirectoryW ; inline
! FUNCTION: SetDefaultCommConfigA ! FUNCTION: SetDefaultCommConfigA
! FUNCTION: SetDefaultCommConfigW ! FUNCTION: SetDefaultCommConfigW
! FUNCTION: SetDllDirectoryA ! FUNCTION: SetDllDirectoryA

2
vm/io.h Normal file → Executable file
View File

@ -13,5 +13,3 @@ DECLARE_PRIMITIVE(fread);
DECLARE_PRIMITIVE(open_file); DECLARE_PRIMITIVE(open_file);
DECLARE_PRIMITIVE(stat); DECLARE_PRIMITIVE(stat);
DECLARE_PRIMITIVE(read_dir); DECLARE_PRIMITIVE(read_dir);
DECLARE_PRIMITIVE(cwd);
DECLARE_PRIMITIVE(cd);

View File

@ -115,19 +115,6 @@ DEFINE_PRIMITIVE(read_dir)
dpush(result); dpush(result);
} }
DEFINE_PRIMITIVE(cwd)
{
char wd[MAXPATHLEN];
if(getcwd(wd,MAXPATHLEN) == NULL)
io_error();
box_char_string(wd);
}
DEFINE_PRIMITIVE(cd)
{
chdir(unbox_char_string());
}
DEFINE_PRIMITIVE(os_envs) DEFINE_PRIMITIVE(os_envs)
{ {
GROWABLE_ARRAY(result); GROWABLE_ARRAY(result);

View File

@ -10,16 +10,6 @@ s64 current_millis(void)
| (s64)ft.dwHighDateTime<<32) - EPOCH_OFFSET) / 10000; | (s64)ft.dwHighDateTime<<32) - EPOCH_OFFSET) / 10000;
} }
DEFINE_PRIMITIVE(cwd)
{
not_implemented_error();
}
DEFINE_PRIMITIVE(cd)
{
not_implemented_error();
}
char *strerror(int err) char *strerror(int err)
{ {
/* strerror() is not defined on WinCE */ /* strerror() is not defined on WinCE */

View File

@ -8,21 +8,6 @@ s64 current_millis(void)
- EPOCH_OFFSET) / 10000; - EPOCH_OFFSET) / 10000;
} }
DEFINE_PRIMITIVE(cwd)
{
F_CHAR buf[MAX_UNICODE_PATH];
if(!GetCurrentDirectory(MAX_UNICODE_PATH, buf))
io_error();
box_u16_string(buf);
}
DEFINE_PRIMITIVE(cd)
{
SetCurrentDirectory(unbox_u16_string());
}
DEFINE_PRIMITIVE(os_envs) DEFINE_PRIMITIVE(os_envs)
{ {
GROWABLE_ARRAY(result); GROWABLE_ARRAY(result);

View File

@ -30,6 +30,7 @@ typedef wchar_t F_CHAR;
F_STRING *get_error_message(void); F_STRING *get_error_message(void);
DLLEXPORT F_CHAR *error_message(DWORD id); DLLEXPORT F_CHAR *error_message(DWORD id);
void windows_error(void);
void init_ffi(void); void init_ffi(void);
void ffi_dlopen(F_DLL *dll, bool error); void ffi_dlopen(F_DLL *dll, bool error);

View File

@ -109,8 +109,6 @@ void *primitives[] = {
primitive_millis, primitive_millis,
primitive_type, primitive_type,
primitive_tag, primitive_tag,
primitive_cwd,
primitive_cd,
primitive_modify_code_heap, primitive_modify_code_heap,
primitive_dlopen, primitive_dlopen,
primitive_dlsym, primitive_dlsym,