-- FILE:     FILE2.EX
-- PROJECT:  Lib2 (Unit testing)
-- PURPOSE:  Verify the results of FILE2.E & DOSLFN.E library.
-- AUTHOR:   Shian Lee
-- VERSION:  1.30  February/13/2022
-- LANGUAGE: Euphoria version 3.1.1 (http://www.RapidEuphoria311.com)
-- PLATFORM: Any
-- LICENCE:  Free. Use at your own risk.
-- NOTE:     * Set USER PARAMETERS manually before test.
--           * Test on DOS/Win/Linux/FreeBSD/Linux-on-FreeBSD/DOSBox-Linux.
--           * Using EUDIR's subdirectories as source files.
--           * in DOSBox on Linux file or dir name can include ? or *.
--             DOSBox doesn't support space, ' ', in file names.
--           * Created using EDU 3.10.
-- HISTORY:  1.15: Initial version (January/16/2022)
--           1.21: t_rename_file() test rename directory.
--           1.30: new in os_menu(): FreeDOS (Long File Name).
-----------------------------------------------------------------------------


include machine2.e
include graphics.e
include file.e
include get.e
include wildcard.e

-- Lib2 1.48+
include string.e
include doslfn.e
include file2.e


with trace


integer os

function os_menu()
-- select OS for test, return test #
    integer n
    
    clear_screen()
    n = floor(prompt_number(
	" Select OS for test (0=Quit):\n" &
	" ----------------------------\n\n" &
	" 1. FreeDOS\n" & 
	" 2. FreeDOS (Long File Name)\n" & 
	" 3. DOSBox on Linux\n" & 
	" 4. Windows XP / Windows 10 (using exwc)\n" &
	" 5. TinyCore Linux\n" &
	" 6. Linux Mint\n" &
	" 7. FreeBSD (GhostBSD)\n" &
	" 8. Linux on FreeBSD\n\n ",
	{0, 8}
    ))
    if n >= 1 and n <= 8 then
	return n
    end if
    abort(0)
end function
os = os_menu()

constant FD_LFN = (os = 2) -- (TRUE = Testing FreeDOS with LFN support)
constant DOSBOX_ON_LINUX = (os = 3) -- (TRUE = Testing in DOSBox on Linux)

constant LFN = iif(FD_LFN, "-Long-File-Name", EMPTY)


--bookmark: ****** USER PARAMETERS ******;

-- note: path is case sensitive on Linux/FreeBSD
constant HOME = iif(os < 5, "C:\\",             -- DOS/Windows
		iif(os = 5, "/home/tc/",        -- tc Linux
		iif(os = 6, "/home/shian/",     -- Linux Mint
			    "/usr/home/shian/"  -- FreeBSD (7,8)
		)))

-- constant INIT_DIR = HOME & "data" -- full path to Init dir (where file2.ex)
constant INIT_DIR = HOME & "lfn" -- full path to Init dir (where file2.ex)

-- full path to Test dir (temp dir), keep the LFN extension:
constant TEST_DIR = HOME & "~UTEST" & LFN 

constant PAUSE_TEST = 0 -- TRUE will pause after each test
constant SHOW_FILES = 1 -- TRUE will call files() for some tests
constant ALL_MODES  = 0 -- TRUE will test all graphics modes for dos_system()

-- *********** END USER PARAMETERS ******


constant UNIX = OS_LINUX,
	 NOT_UNIX = not UNIX,
	 U = UNIX,
	 W = UNIX or DOSBOX_ON_LINUX -- use Wildcard ? or * for file/dir name

constant INIT_DRIVE = INIT_DIR[1]

constant TEST_DRIVE = TEST_DIR[1],
	 TDIR = slash_path(TEST_DIR, TRUE)

constant TSUBDIR = TDIR & "~SUBDIR" & LFN

constant NDIR = slash_path("~@#####", TRUE) -- (subdir Not exist)

constant EU_DIR = getenv("EUDIR"),
	 EDIR = slash_path(EU_DIR, TRUE)



allow_break(FALSE) -- don't crash on control-c
tick_rate(100) -- for delay()
allow_lfn(FD_LFN) -- allow LFN?


procedure init_lfn()
-- check_lfn() and do a quick test to lfn_dir() 
    sequence s, dirs
    object x
    
    if check_lfn() != FD_LFN then
	puts(1, "\n\t* LFN error * check that LFN driver is installed. abort...\n")
	pause()
	abort(1)
    end if

    -- do quick test to lfn_dir()
    dirs = {"bin", "include", "doc", "html", "source", "unittest", "demo"}
    for i = 1 to length(dirs) do
	s = EDIR & dirs[i]
	puts(1, s & '\n')
	delay(5)
	x = dir(s)
	if atom(x) then
	    puts(1, "\n\t* Euphoria Directory (EUDIR) error * abort...\n")
	    pause()
	    abort(2)
	elsif not equal(x, lfn_dir(s)) then
	    printf(1, "\n\t* lfn_dir() error *\n" &
		"not equal(dir(%s), lfn_dir(%s))\n abort...\n", {s, s})
	    pause()
	    abort(2)
	end if
    end for
end procedure

init_lfn()


--bookmark: helper routines;

procedure normal_color()
-- restore black & white screen colors
    text_color(WHITE)
end procedure


procedure line()
-- print an empty line
    puts(1, '\n')
end procedure


function bs(object s)
-- replace slash / with backslash \ in a path name
    if NOT_UNIX and sequence(s) then
	return translate(s, "/", "\\")
    end if
    return s
end function


function sp(object s)
-- replace space ' ' with '_' in a path name
-- DOSBox doesn't support space in file names
    if DOSBOX_ON_LINUX  and sequence(s) then
	return translate(s, " ", "_")
    end if
    return s
end function


procedure chdir_init()
-- restore current drive & directory to INIT_DIR
    integer i
    
    if NOT_UNIX then
	i = chdrive(INIT_DRIVE)
    end if
    i = lfn_chdir(INIT_DIR)
    puts(1, "Init directory is set? " & lfn_current_dir() & '\n')
end procedure


procedure check_stop(string txt)
-- stop test on control-c or 'Q' (quit), if txt not empty then [FAIL]
    integer i
    sequence vc
    
    if check_break() or length(txt) or find(get_key(), "qQ") then
	vc = video_config()
	if vc[VC_MODE] != 3 then
	    i = graphics_mode(3) -- restore normal text mode
	end if
	if length(txt) then
	    text_color(BRIGHT_RED)
	    puts(1, txt) -- for [FAIL]
	else
	    text_color(YELLOW)
	    puts(1, "\n\n  User pressed <Q> or <Control-C>, abort ...\n")
	end if
	normal_color()
	pause()
	chdir_init()
	? 1 / 0 -- (create ex.err)
    end if
end procedure


procedure pause_test()
-- check break and only pause if flag is set    
    check_stop(EMPTY)
    if PAUSE_TEST then
	pause()
    end if
end procedure


procedure p_(boolean ok_msg, string format, object args)
-- print green (OK) message if ok_msg=1, or red (FAIL) message 
    string txt
    
    txt = sprintf(format, args)
    
    if ok_msg then
	-- print success message
	text_color(BRIGHT_GREEN)
	puts(1, "[OK] " & txt & '\n')
	normal_color()
	pause_test() -- check break & pause after each test
    else
	-- abort with red message on any error
	check_stop("[FAIL] " & txt & " abort...")
    end if
end procedure


procedure chdir_test()
-- restore current drive and directory to TEST_DIR
    integer ok
    
    if UNIX then
	ok = TRUE
    else
	ok = chdrive(TEST_DRIVE)
    end if
    ok = ok and lfn_chdir(TEST_DIR)
    p_(ok, "Set test directory: %s", {TEST_DIR})
end procedure


function mf(boolean make, string pn)
-- make file: create an empty file for test, return pn
    integer fn
    
    pn = sp(pn)
    if make then
	fn = lfn_open(pn, "w")
	if fn = -1 then
	    p_(FALSE, "cannot create file for test: %s", {pn})
	end if
	close(fn)
    end if
    
    return pn
end function


function system_diff(string pn, string pn2)
-- compare files using system command, 0=fail, 1=ok
    string s
    integer v
    boolean ok
    
    normal_color()
    puts(1, ' ') -- apply color
    s = iif(UNIX, "diff -s ", "fc ") & quote(pn) & ' ' & quote(pn2)
    v = system_exec(s, 2)
    if NOT_UNIX and v = 2 then 
	ok = TRUE -- "too many filespec" (2) return by FC for space, ' '
    else
	ok = v = 0
    end if
    p_(ok, s, EMPTY)
    
    return ok
end function


procedure f_(string pn)
-- call files() with color for some tests 
    if SHOW_FILES then
	text_color(CYAN)
	files(pn)
	normal_color()
    end if
end procedure


function remove_test_dir()
-- remove test directory on start or when done test, return 0/1 (fail/ok)
    string name
    object d
    boolean ok
    
    if sequence(lfn_dir(TEST_DIR)) then
	d = lfn_dir(TEST_DIR)
	for i = 1 to length(d) do
	    name = slash_path(TEST_DIR, TRUE) & d[i][D_NAME]
	    if find('d', d[i][D_ATTRIBUTES]) then
		ok = remove_dir(name)
	    else
		ok = delete_file(name)
	    end if
	end for
    end if
    ok = remove_dir(TEST_DIR)
    return ok
end function


procedure init_program()
-- initialize the program

    ? remove_test_dir()   -- clean if previous run failed
    ? make_dir(TEST_DIR)  -- try to create test directory

    normal_color()
    clear_screen()

    -- test dir warning
    chdir_test()
    puts(1, "Work directory is: ")
    text_color(YELLOW)
    puts(1, lfn_current_dir() & '\n')
    text_color(CYAN)
    files("")
    normal_color()
    
    -- on DOSBox 'Q' works, in other cases control-c
    puts(1, "Press any key to start test, <Q> or <Control-C> to abort ...")
    pause()
    check_stop(EMPTY)
    puts(1, "\n\n")
end procedure

init_program()



--bookmark: ----- Start Test; ------------------------


-- count 19 test routines
constant TOTAL_TESTS = 19
integer count_tests
count_tests = 0

-- chdrive, current_drive, get_drives, 
-- make_dir, remove_dir, delete_file
-- copy_file, compare_file, rename_file, files, 
-- full_pathname, full_dirname, full_filename, 
-- slash_path, parse_path,
-- open_libc, open_libm, dos_system, dos_system_exec.
-- & (lfn_short_path, lfn_long_path, temp_filename)

procedure t_current_drive()
    integer v
    boolean ok
    
    count_tests += 1
    v = current_drive()
    ok = find(v, lfn_current_dir()) = 1
    p_(ok, "current_drive() is %s", {v})
end procedure
t_current_drive()


procedure t_get_drives()
    sequence s
    integer v
    boolean ok
    
    count_tests += 1
    s = get_drives()
    v = length(s) = 0
    ok = (UNIX and v) or (NOT_UNIX and not v) 
    p_(ok, "get_drives() is \"%s\"", {s})
end procedure
t_get_drives()


procedure t_chdrive()
    sequence s
    integer v
    boolean ok
    
    count_tests += 1
    s = get_drives()
    for i = 1 to length(s) do 
	v = s[i]
	if v > 'B' then -- skip floppies
	    ok = chdrive(v)
	    ok = v = current_drive()
	    p_(ok, "chdrive('%s') is %s", {v, current_drive()})
	end if
    end for
    if UNIX then
	p_(TRUE, "chdrive() -- (no drives on Linux)", EMPTY)
    end if
    chdir_test() -- restore test drive
end procedure
t_chdrive()


procedure t_make_dir()
    sequence s, name
    integer v
    boolean ok

    count_tests += 1
    s = {
    {0, NDIR & "MAKEDIR" & LFN},  -- subdir not found
    {1, TDIR & "MAKEDIR" & LFN},  -- dir
    {0, TDIR & "MAKEDIR" & LFN},  -- already exist
    {1, TDIR & "MAK DIR" & LFN},  -- Space
    {0, TDIR & "MAK DIR" & LFN},  -- already exist
    {W, TDIR & "M?KEDIR" & LFN},  -- ?
    {W, TDIR & "M*KEDIR" & LFN}   -- *
    }
    for i = 1 to length(s) do
	name = sp(s[i][2])
	v = make_dir(name)
	ok = v = s[i][1]
	p_(ok, "make_dir(%s) = %d", {name, v})
	f_(name)
    end for
end procedure
line()
t_make_dir()


procedure t_remove_dir()
    sequence s, name
    integer v
    boolean ok

    count_tests += 1
    s = {
    {0, NDIR & "MAKEDIR" & LFN},  -- subdir not found
    {1, TDIR & "MAKEDIR" & LFN},  -- dir  -- made by t_make_dir()
    {0, TDIR & "MAKEDIR" & LFN},  -- not exist
    {1, TDIR & "MAK DIR" & LFN},  -- dir  -- made by t_make_dir()
    {0, TDIR & "MAK DIR" & LFN},  -- not exist
    {W, TDIR & "M?KEDIR" & LFN},  -- ?    -- made by t_make_dir()
    {0, TDIR & "M?KEDIR" & LFN},  -- not exist
    {W, TDIR & "M*KEDIR" & LFN},  -- *    -- made by t_make_dir()
    {0, TDIR & "M*KEDIR" & LFN}   -- not exist
    }
    for i = 1 to length(s) do
	name = sp(s[i][2])
	v = remove_dir(name)
	ok = v = s[i][1]
	p_(ok, "remove_dir(%s) = %d", {name, v})
	f_(name)
    end for
end procedure
line()
t_remove_dir()


procedure t_delete_file()
    sequence s, name
    integer v
    boolean ok
    
    count_tests += 1
    s = {
    {0,       NDIR & "DEL FILE.TMP" & LFN},   -- path not found
    {1, mf(1, TDIR & "DEL FILE.TMP" & LFN)},  -- file
    {0,       TDIR & "DEL FILE.TMP" & LFN},   -- not exist
    {W, mf(W, TDIR & "D?L FILE.TMP" & LFN)},  -- ?
    {W, mf(W, TDIR & "D*L FILE.TMP" & LFN)}   -- *
    }
    for i = 1 to length(s) do
	name = sp(s[i][2])
	v = delete_file(name)
	ok = v = s[i][1]
	p_(ok, "delete_file(%s) = %d", {name, v})
	f_(name)
    end for
end procedure
line()
t_delete_file()


-- made by t_copy_file(); used by t_compare_file(), t_rename_file()
constant NAME1 = EU_DIR & iif(UNIX, "/bin/exu", "\\bin\\ex.exe")
constant NAME2 = TDIR & "COPY.TMP" & LFN

procedure t_copy_file()
    sequence s, name, name2
    integer v, over
    boolean ok
    
    count_tests += 1
    s = {
    {1, NAME1, NAME2},                      -- file
    {0, NAME1, NAME2},                      -- (i = 2) already exist
    {1, NAME1, TDIR & "CO PY_S.TMP" & LFN}, -- Space
    {0, NAME1, TDIR & "CO PY_S.TMP" & LFN}, -- (i = 4) already exist
    {0, NAME2, NAME2},                      -- itself (equal string)
    {1, NAME1, NAME2},                      -- (i != 2) already exist
    {0, NAME1, NDIR & "COPY.TMP" & LFN},    -- path not found
    {0, NDIR & "COPY.TMP" & LFN, NAME2},    -- path not found
    {W, NAME1, TDIR & "C?OPY.TMP" & LFN},   -- ?
    {W, NAME1, TDIR & "C*OPY.TMP" & LFN}    -- *
    }
    for i = 1 to length(s) do
	name = sp(s[i][2])
	name2 = sp(s[i][3])
	over = (i != 2 and i != 4)
	v = copy_file(name, name2, over)
	ok = v = s[i][1]
	if v then
	    ok = system_diff(name, name2) -- verify
	end if
	p_(ok, "copy_file(%s, %s, %d) = %d", {name, name2, over, v})
	f_(name)
	f_(name2)
    end for
end procedure
line()
t_copy_file()


procedure t_compare_file()
    sequence s, name, name2
    integer v
    boolean ok
    
    count_tests += 1
    -- files made by t_copy_file()
    s = {
    {1, NAME1, NAME2},                      -- file
    {1, NAME2, NAME2},                      -- itself
    {1, NAME1, TDIR & "CO PY_S.TMP" & LFN}, -- Space
    {1, TDIR & "CO PY_S.TMP" & LFN, TDIR & "CO PY_S.TMP" & LFN}, -- itself
    {0, NAME1, NDIR & "COPY.TMP" & LFN},    -- path not found
    {0, NDIR & "COPY.TMP" & LFN, NAME2},    -- path not found
    {W, NAME1, TDIR & "C?OPY.TMP" & LFN},   -- ?
    {W, NAME1, TDIR & "C*OPY.TMP" & LFN}    -- *
    }
    for i = 1 to length(s) do
	name = sp(s[i][2])
	name2 = sp(s[i][3])
	v = compare_file(name, name2) = 1
	ok = v = s[i][1]
	if v then
	    ok = system_diff(name, name2) -- verify
	end if
	p_(ok, "compare_file(%s, %s) = %d", {name, name2, v})
	f_(name)
    --  f_(name2)
    end for
end procedure
line()
t_compare_file()


procedure t_rename_file()
    sequence s, name, name2
    integer v
    boolean ok

    count_tests += 1
    v = make_dir(TSUBDIR) -- create test-subdir
    p_(v, "make_dir(%s) = %d", {TSUBDIR, v})
    
    -- files made by t_copy_file()
    s = {
    {1, NAME2, "RENAME.TMP" & LFN},           -- file
    {1, "RENAME.TMP" & LFN, NAME2},           -- file
    {1, NAME2, "RE AME.TMP" & LFN},           -- space
    {1, "RE AME.TMP" & LFN, NAME2},           -- space
    {1, TSUBDIR, "@SD@" & LFN},               -- rename a subdir
    {1, "@SD@" & LFN, TSUBDIR},               -- rename a subdir
    {1, NAME2, TSUBDIR & "/REN2.TMP" & LFN},  -- to subdir
    {1, TSUBDIR & "/REN2.TMP" & LFN, NAME2},  -- to updir
    {0, NAME2, NDIR & "RENAME.TMP" & LFN},    -- path not found
    {0, NDIR & "COPY.TMP" & LFN, NAME2},      -- path not found
    {FD_LFN or not OS_DOS32, NAME2, NAME2},   -- itself (return -1 with ex.exe)
    {W, NAME2, TDIR & "R?NAME.TMP" & LFN},    -- ?
    {W, TDIR & "R?NAME.TMP" & LFN, NAME2},    -- restore name
    {W, NAME2, TDIR & "R*NAME.TMP" & LFN},    -- *
    {W, TDIR & "R*NAME.TMP" & LFN, NAME2}     -- restore name
    }
    for i = 1 to length(s) do
	name = sp(bs(s[i][2]))
	name2 = sp(bs(s[i][3]))
	v = rename_file(name, name2) = 1
	ok = v = s[i][1]
	p_(ok, "rename_file(%s, %s) = %d", {name, name2, v})
	f_(name)
	f_(name2)
    end for
end procedure
line()
t_rename_file()


procedure t_files()
-- (verify by looking at the screen)   
    sequence s, name, text
    
    count_tests += 1
    chdir_test()
    
    s = {
    {"",      TEST_DIR},
    {TSUBDIR, TSUBDIR},
    {"../",   "up dir"},
    {"..",    "up dir"},
    {"/~@#xyz012/", "path not found"},
    {"~@#xyz012",   "file not found"},
    {EDIR & "readme.doc", "readme.doc"},
    {iif(UNIX, "/", "D:"), iif(UNIX, "/", "D:")} -- test drive
    }
    for i = 1 to length(s) do
	name = sp(bs(s[i][1]))
	text = s[i][2]
	printf(1, "\nfiles(%s) --> %s\n", {name, text})
	f_(name)
	pause_test()
    end for
end procedure
t_files()


procedure t_full_pathname()
    sequence s, name, drv
    object x, name2
    boolean ok
    
    count_tests += 1
    ok = lfn_chdir(EU_DIR)
    p_(ok, "lfn_chdir(%s) = %d", {EU_DIR, ok})

    drv = current_drive() & EMPTY
    s = {
    {1, "",               -1},
    {1, ".",              EU_DIR},
    {1, "./",             EU_DIR},
    {1, "./xyz.txt",      EDIR & "xyz.txt"},
    {1, "html",           EDIR & "html"},
    {1, "/html/",         -1},              -- path not found
    {1, "html#/",         -1},              -- path not found
    {1, "include#/get.e", -1},              -- note: on FreeBSD /include exists
    {1, "include/get.e",  EDIR & "include/get.e"},
    {1, "./*.TMP",        EDIR & "*.TMP"},
    {1, "./X Y.TMP",      EDIR & "X Y.TMP"},
    {1, "././?p.TMP",     EDIR & "?p.TMP"},
    {1, "/",              iif(UNIX, "/", drv & ":/")},  -- / or x:\
    {1, drv,              iif(UNIX, "/", EDIR & drv)},  -- / or filename
    {1, drv & ':',        iif(UNIX, "/:", EU_DIR)},     -- /: or curdir
    {1, mf(W, TDIR & "x?z .txt"), TDIR & "x?z .txt"},   -- ? (exist)
    {1, mf(W, TDIR & "x*z .txt"), TDIR & "x*z .txt"}    -- * (exist)
    }
    for i = 1 to length(s) do
	name = sp(bs(s[i][2]))
	name2 = sp(bs(s[i][3]))
	x = full_pathname(name)
	ok = s[i][1] = equal(lower(x), lower(name2))
--      puts(1, x & '\n')
	p_(ok, "full_pathname(\"%s\") = %s", 
		{name, iif(atom(name2), "-1", name2)})
    end for
    
    chdir_test() -- restore test dir
end procedure
line()
t_full_pathname()


procedure t_full_dirname()
    sequence s, drv, tmpf
    object x, name, name2, ntmpf
    boolean ok
    
    count_tests += 1
    ok = lfn_chdir(EU_DIR)
    p_(ok, "lfn_chdir(%s) = %d", {EU_DIR, ok})

    drv = current_drive() & EMPTY
    
    name = sp(TDIR & "x?z dir") -- ? (dirs for test)
    ok = make_dir(name) or not W 
    p_(ok, "make_dir(%s) = %d", {name, ok})

    name = sp(TDIR & "x*z dir") -- *
    ok = make_dir(name) or not W 
    p_(ok, "make_dir(%s) = %d", {name, ok})
    
    tmpf = TDIR & temp_filename(TDIR)
    ok = make_dir(tmpf) 
    p_(ok, "make_dir(%s) = %d", {tmpf, ok})
    ntmpf = temp_filename(NDIR)
    s = {
    {1, "",               -1},
    {1, ".",              EU_DIR},
    {1, "./",             EU_DIR},
    {1, "./xyz.txt",      -1},              -- path not found
    {1, "html",           EDIR & "html"},
    {1, "/html/",         -1},              -- path not found
    {1, "html#/",         -1},              -- path not found
    {1, "include#/get.e", -1},              -- path not found
    {1, "include/get.e",  -1},              -- path not found
    {1, "./bin",          EDIR & "bin"},
    {1, "./b n",          -1},              -- path not found
    {1, "./b?n",          -1},              -- ?
    {1, "./b*n",          -1},              -- *
    {1, "././bin",        EDIR & "bin"},
    {1, "././bin/..",     EU_DIR},
    {1, "/",              iif(UNIX, "/", drv & ":/")},  -- / or x:\
    {1, drv,              iif(UNIX, "/", -1)},          -- /
    {1, drv & ':',        iif(UNIX, -1, EU_DIR)},       -- -1 or curdir
    {W, TDIR & "x?z dir", TDIR & "x?z dir"},            -- ? (exist)
    {W, TDIR & "x*z dir", TDIR & "x*z dir"},            -- * (exist)
    {1, tmpf, tmpf},
    {1, ntmpf,  -1},                  -- path not found
    -- lfn
    {FD_LFN, lfn_short_path("././bin/..", 1), EU_DIR},
    {FD_LFN,  lfn_long_path("././bin/..", 1), EU_DIR},
    {FD_LFN, lfn_short_path(TSUBDIR, 1), TSUBDIR},
    {FD_LFN,  lfn_long_path(TSUBDIR, 1), TSUBDIR},
    {1, lfn_short_path(NDIR, 1), -1}, -- path not found
    {1,  lfn_long_path(NDIR, 1), -1}, -- path not found
    {1, lfn_short_path(NDIR, 0), -1}, -- ignore path not found
    {1,  lfn_long_path(NDIR, 0), -1}  -- ignore path not found
    }
    for i = 1 to length(s) do
	name = sp(bs(s[i][2]))
	name2 = sp(bs(s[i][3]))
	if sequence(name) then
	    x = full_dirname(name)
	else
	    x = name
	end if
	ok = s[i][1] = equal(lower(x), lower(name2))
	p_(ok, "full_dirname(\"%s\") = %s", 
		{name, iif(atom(name2), "-1", name2)})
    end for
    
    chdir_test() -- restore test dir
end procedure
line()
t_full_dirname()


procedure t_full_filename()
    sequence s, drv, tmpf
    object x, name, name2, ntmpf
    boolean ok
    
    count_tests += 1
    ok = lfn_chdir(EU_DIR)
    p_(ok, "lfn_chdir(%s) = %d", {EU_DIR, ok})

    drv = current_drive() & EMPTY
    tmpf = TDIR & temp_filename(TDIR)
    ntmpf = temp_filename(NDIR)
    s = {
    {1, "",               -1},
    {1, ".",              -1},      -- dir name
    {1, "./",             -1},
    {1, "./xyz.txt",      -1},
    {1, "./readme.doc",   EDIR & "readme.doc"},
    {1, "././readme.doc", EDIR & "readme.doc"},
    {1, "readme.doc",     EDIR & "readme.doc"},
    {1, "r?adme.doc",     -1},      -- ?
    {1, "r*adme.doc",     -1},      -- *
    {1, "r adme.doc",     -1},      -- space
    {1, "html",           -1},      -- dir name
    {1, "./html",         -1},
    {1, "/html/",         -1},
    {1, "html#/",         -1},
    {1, "include#/get.e", -1},
    {1, "include/get.e",  EDIR & "include/get.e"},
    {1, "./bin/ed.ex",    EDIR & "bin/ed.ex"},
    {1, "././bin/ed.ex",  EDIR & "bin/ed.ex"},
    {1, "./doc/*.doc",    -1},
    {1, "/",              -1},      -- / or x:\
    {1, drv,              -1},      -- /
    {1, drv & ':',        -1},      -- file /: or curdir
    {U, mf(W, TDIR & "x?z"), TDIR & "x?z"}, -- ? (exist) -- (skip DOSBox-Linux)
    {U, mf(W, TDIR & "x*z"), TDIR & "x*z"}, -- * (exist)
    {1, mf(1, tmpf), tmpf},
    {1, ntmpf,  -1},                -- path not found
    -- lfn
    {1, lfn_short_path("include#/get.e", 1), -1},
    {1,  lfn_long_path("include#/get.e", 1), -1},
    {not FD_LFN, lfn_short_path(mf(1, TDIR & "FN" & LFN), 1), -1},
    {FD_LFN,   lfn_long_path(TDIR & "FN" & LFN, 1), TDIR & "FN" & LFN},
    {FD_LFN, lfn_short_path("include/get.e", 1), EDIR & "include/get.e"},
    {FD_LFN,  lfn_long_path("include/get.e", 1), EDIR & "include/get.e"},
    {FD_LFN, lfn_short_path("./bin/ed.ex", 1),   EDIR & "bin/ed.ex"},
    {FD_LFN,  lfn_long_path("./bin/ed.ex", 1),   EDIR & "bin/ed.ex"},
    {FD_LFN, lfn_short_path("././bin/ed.ex", 1), EDIR & "bin/ed.ex"},
    {FD_LFN,  lfn_long_path("././bin/ed.ex", 1), EDIR & "bin/ed.ex"}
    }
    for i = 1 to length(s) do
	name = sp(bs(s[i][2]))
	name2 = sp(bs(s[i][3]))
	if sequence(name) then
	    x = full_filename(name)
	else
	    x = name
	end if
	ok = s[i][1] = equal(lower(x), lower(name2))
	p_(ok, "full_filename(\"%s\") = %s", 
		{name, iif(atom(name2), "-1", name2)})
    end for
    
    chdir_test() -- restore test dir
end procedure
line()
t_full_filename()


procedure t_slash_path()
    sequence s, name, name2
    integer v
    boolean ok

    count_tests += 1
    s = {
    {TRUE, ".",     "./"},
    {TRUE, "./",    "./"},
    {TRUE, "..",    "../"},
    {TRUE, "../",   "../"},
    {TRUE, "D:",    iif(UNIX, "D:/", "D:")},
    {TRUE, "D:/",   "D:/"},
    {TRUE, "/",     "/"},
    {TRUE, "X YZ/",  "X YZ/"},
    {TRUE, "X YZ",   "X YZ/"},
    ---
    {FALSE, "./",   "."},
    {FALSE, ".",    "."},
    {FALSE, "..",   ".."},
    {FALSE, "../",  ".."},
    {FALSE, "D:",   "D:"},
    {FALSE, "D:/",  iif(UNIX, "D:", "D:/")},
    {FALSE, "/",    "/"},
    {FALSE, "X YZ/", "X YZ"},
    {FALSE, "X YZ",  "X YZ"}
    }
    for i = 1 to length(s) do
	name = bs(s[i][2])
	name2 = bs(s[i][3])
	v = s[i][1]
	ok = equal(slash_path(name, v), name2)
	p_(ok, "slash_path(%s, %d) = %s", {name, v, name2})
    end for
end procedure
line()
t_slash_path()


procedure t_parse_path()
    sequence s, name, name2
    integer v
    boolean ok

    count_tests += 1
    s = { --- DOS syntax
    {FALSE, "C:\\DOC\\PROG\\c.pdf",
	    {"C", "C:\\DOC\\PROG\\", "\\DOC\\PROG\\", "c.pdf", "c", "pdf"}},
    {FALSE, "C:c.pdf",
	    {"C", "C:", "", "c.pdf", "c", "pdf"}},
    {FALSE, "C:\\pdf",
	    {"C", "C:\\", "\\", "pdf", "pdf", ""}},
    {FALSE, "C:\\DOC\\",
	    {"C", "C:\\DOC\\", "\\DOC\\", "", "", ""}},
    {FALSE, "c.pdf",
	    {"", "", "", "c.pdf", "c", "pdf"}},
    {FALSE, "c:",
	    {"c", "c:", "", "", "", ""}},
    {FALSE, "\\",
	    {"", "\\", "\\", "", "", ""}},
    {FALSE, "\\DOC\\",
	    {"", "\\DOC\\", "\\DOC\\", "", "", ""}},
    {FALSE, ":\\DOC\\c.pdf",
	    {"", ":\\DOC\\", ":\\DOC\\", "c.pdf", "c", "pdf"}}, -- illegal case
    -- unix syntax
    {TRUE, "/home/john/Doc/c d.pdf", 
	    {"", "/home/john/Doc/", "/home/john/Doc/", "c d.pdf", "c d", "pdf"}},
    {TRUE, "/c.pdf", 
	    {"", "/", "/", "c.pdf", "c", "pdf"}},
    {TRUE, "/pdf", 
	    {"", "/", "/", "pdf", "pdf", ""}},
    {TRUE, "/", 
	    {"", "/", "/", "", "", ""}},
    {TRUE, "/home/", 
	    {"", "/home/", "/home/", "", "", ""}},
    {TRUE, "c.pdf", 
	    {"", "", "", "c.pdf", "c", "pdf"}}
    }
    for i = 1 to length(s) do
	name = s[i][2]
	name2 = s[i][3]
	v = s[i][1]
	ok = equal(parse_path({v, name}), name2)
	p_(ok, "parse_path({%d, %s}) = %s", {v, name, join(name2, '|')})
	
	-- same but using default syntax:
	if (UNIX and v) or (NOT_UNIX and not v) then
	    ok = equal(parse_path(name), name2) 
	    p_(ok, "parse_path(%s) = %s", {name, join(name2, '|')})
	end if
    end for
end procedure
line()
t_parse_path()


procedure t_open_lib()
    atom v
    boolean ok

    count_tests += 1 -- libc
    count_tests += 1 -- libm
    if OS_DOS32 then
	p_(TRUE, "open_libc() and open_libm() not supported on DOS.", EMPTY)
    else
	v = open_libc()
	ok = iif(UNIX, v > 0, v = 0)
	p_(ok, "open_libc() = %d", v)
	
	v = open_libm()
	ok = iif(UNIX, v > 0, v = 0)
	p_(ok, "open_libm() = %d", v)
	
	printf(1, " OS_FREEBSD = %d\n", OS_FREEBSD)
	pause_test()
    end if
end procedure
t_open_lib()


procedure t_dos_system()
    sequence s, name, m, cs
    integer v, code, st
    boolean ok, test_mode

    count_tests += 1 -- system
    count_tests += 1 -- system_exec
    
    name = iif(UNIX, "exu", iif(OS_WIN32, "exwc", "ex")) &
	' ' & bs(INIT_DIR & "/modes.ex ")
    
    for mode = 0 to 261 do
	if ALL_MODES then
	    test_mode = (mode <= 19 or mode >= 256) -- test all graphics modes
	else
	    test_mode = (find(mode, {1,3,18,257}) > 0) -- mode-3 lines=28
	end if
	
	for routine = 1 to 2 * test_mode do
	    s = name & str(mode)
	    if routine = 1 then
		cs = dos_system_exec(s) -- = {exit_code, video_status}
		code = cs[1]
		st = cs[2]
		m = sprintf("dos_system_exec(%s) = %s", {s, str(cs)})
	    elsif routine = 2 and code = 0 then
		st = dos_system(s)       -- = video_status
		m = sprintf("  dos_system(%s) = %s", {s, str(st)})
	    end if
	
	    if routine = 2 and code != 0 then
		-- skip dos_system() if code != 0
	    elsif code = 0 then 
		delay(200) -- show the graphics mode
		v = graphics_mode(3) -- don't use (-1), we need 25x80 mode
		position(3, 1)
		ok = (mode != 3 and st = 1) or (mode = 3 and st = 2)
		p_(ok, m, EMPTY)
		if not PAUSE_TEST then
		    delay(200)
		end if
	    elsif code = 1 then -- ex/exu returns exit code 1 
		p_(FALSE, m & " -- Can't find or open 'mode.ex'", EMPTY)
	    elsif code = 2 then
		p_(FALSE, m & " -- Bad graphics mode", EMPTY)
	    elsif code = 3 then
		p_(TRUE, m & " -- (Not DOS platform)", EMPTY)
	    elsif code = 4 then
		p_(TRUE, m & " -- Cannot set mode", EMPTY)
	    end if
	end for
    end for
end procedure
t_dos_system()


procedure done()
    chdir_init() 
    if count_tests != TOTAL_TESTS then
	p_(FALSE, " %d TESTS DONE SUCCESSFULY (not %d)\n", 
		{count_tests, TOTAL_TESTS})
    else
	p_(TRUE, " *** %d TESTS DONE SUCCESSFULY ***\n", count_tests)
    end if
    
    if prompt_number("Remove test dir [0,1]? ", {0, 1}) = 1 then
	if not remove_test_dir() then
	    puts(1, "\n Can't remove test dir!\n")
	    pause()
	end if
    end if
    files(TEST_DIR) 
end procedure
line()
done()


-- End of file.
