added OS/2 code into time.c

started writing OS/2 code into pio.c
fixed minor issues in fio.c
This commit is contained in:
2011-03-19 09:07:21 +00:00
parent b69285fc36
commit 20a989ecaf
20 changed files with 2073 additions and 144 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: fio.c 400 2011-03-16 08:37:06Z hyunghwan.chung $
* $Id: fio.c 402 2011-03-18 15:07:21Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -90,6 +90,10 @@ qse_fio_t* qse_fio_init (
QSE_MEMSET (fio, 0, QSE_SIZEOF(*fio));
fio->mmgr = mmgr;
/* store the flags for later use though only OS/2 needs
* this at this moment */
fio->flags = flags;
#if defined(_WIN32)
if (flags & QSE_FIO_HANDLE)
{
@ -172,9 +176,17 @@ qse_fio_t* qse_fio_init (
{
APIRET ret;
ULONG action_taken = 0;
ULONG open_action, open_mode;
ULONG open_action, open_mode, open_attr;
LONGLONG zero;
#ifdef QSE_CHAR_IS_MCHAR
const qse_mchar_t* path_mb = path;
#else
qse_mchar_t path_mb[CCHMAXPATH];
if (qse_wcstombs_strict (path,
path_mb, QSE_COUNTOF(path_mb)) == -1) return QSE_NULL;
#endif
zero.ulLo = 0;
zero.ulHi = 0;
@ -202,18 +214,33 @@ qse_fio_t* qse_fio_init (
open_action = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
}
open_mode = OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE;
open_mode = OPEN_FLAGS_NOINHERIT;
if (flags & QSE_FIO_SYNC)
open_mode |= OPEN_FLAGS_WRITE_THROUGH;
if ((flags & QSE_FIO_NOSHRD) && (flags & QSE_FIO_NOSHWR))
open_mode |= OPEN_SHARE_DENYREADWRITE;
else if (flags & QSE_FIO_NOSHRD)
open_mode |= OPEN_SHARE_DENYREAD;
else if (flags & QSE_FIO_NOSHWR)
open_mode |= OPEN_SHARE_DENYWRITE;
else
open_mode |= OPEN_SHARE_DENYNONE;
if ((flags & QSE_FIO_READ) &&
(flags & QSE_FIO_WRITE)) open_mode |= OPEN_ACCESS_READWRITE;
else if (flags & QSE_FIO_READ) open_mode |= OPEN_ACCESS_READONLY;
else if (flags & QSE_FIO_WRITE) open_mode |= OPEN_ACCESS_WRITEONLY;
open_attr = (mode & QSE_FIO_WUSR)? FILE_NORMAL: FILE_READONLY;
ret = DosOpenL (
path, /* file name */
path_mb, /* file name */
&handle, /* file handle */
&action_taken, /* store action taken */
zero, /* size */
FILE_NORMAL, /* attribute */
open_attr, /* attribute */
open_action, /* action if it exists */
open_mode, /* open mode */
0L
@ -416,7 +443,7 @@ qse_fio_off_t qse_fio_seek (
int qse_fio_truncate (qse_fio_t* fio, qse_fio_off_t size)
{
#ifdef _WIN32
#if defined(_WIN32)
LARGE_INTEGER x;
x.QuadPart = size;
@ -485,6 +512,17 @@ static qse_ssize_t fio_write (qse_fio_t* fio, const void* data, qse_size_t size)
qse_ssize_t qse_fio_write (qse_fio_t* fio, const void* data, qse_size_t size)
{
#if defined(__OS2__)
if (fio->flags & QSE_FIO_APPEND)
{
/* i do this on a best-effort basis */
LONGLONG pos, newpos;
pos.ulLo = (ULONG)0;
pos.ulHi = (ULONG)0;
DosSetFilePtrL (fio->handle, pos, FILE_END, &newpos);
}
#endif
if (fio->tio == QSE_NULL)
return fio_write (fio, data, size);
else
@ -498,7 +536,7 @@ qse_ssize_t qse_fio_flush (qse_fio_t* fio)
}
#ifdef _WIN32
#if defined(_WIN32)
static int get_devname_from_handle (
HANDLE handle, qse_char_t* buf, qse_size_t len)
@ -657,10 +695,8 @@ static qse_ssize_t fio_input (int cmd, void* arg, void* buf, qse_size_t size)
{
qse_fio_t* fio = (qse_fio_t*)arg;
QSE_ASSERT (fio != QSE_NULL);
if (cmd == QSE_TIO_IO_DATA)
{
return fio_read (fio, buf, size);
}
if (cmd == QSE_TIO_IO_DATA) return fio_read (fio, buf, size);
/* take no actions for OPEN and CLOSE as they are handled
* by fio */
@ -671,10 +707,7 @@ static qse_ssize_t fio_output (int cmd, void* arg, void* buf, qse_size_t size)
{
qse_fio_t* fio = (qse_fio_t*)arg;
QSE_ASSERT (fio != QSE_NULL);
if (cmd == QSE_TIO_IO_DATA)
{
return fio_write (fio, buf, size);
}
if (cmd == QSE_TIO_IO_DATA) return fio_write (fio, buf, size);
/* take no actions for OPEN and CLOSE as they are handled
* by fio */

View File

@ -1,5 +1,5 @@
/*
* $Id: pio.c 400 2011-03-16 08:37:06Z hyunghwan.chung $
* $Id: pio.c 402 2011-03-18 15:07:21Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -26,6 +26,7 @@
# include <windows.h>
# include <tchar.h>
#elif defined(__OS2__)
# define INCL_DOSQUEUES
# define INCL_DOSPROCESS
# define INCL_DOSERRORS
# include <os2.h>
@ -95,7 +96,6 @@ qse_pio_t* qse_pio_init (
int i, minidx = -1, maxidx = -1;
#if defined(_WIN32)
SECURITY_ATTRIBUTES secattr;
PROCESS_INFORMATION procinfo;
@ -105,6 +105,12 @@ qse_pio_t* qse_pio_init (
BOOL x;
#elif defined(__OS2__)
/* TODO: implmenet this for os/2 */
APIRET rc;
ULONG pipe_size = 4096;
UCHAR load_error[CCHMAXPATH] = { 0 };
RESULTCODES child_rc;
HFILE old_in, old_out, old_err;
HFILE std_in, std_out, std_err;
#else
qse_pio_pid_t pid;
#endif
@ -114,7 +120,7 @@ qse_pio_t* qse_pio_init (
QSE_MEMSET (pio, 0, QSE_SIZEOF(*pio));
pio->mmgr = mmgr;
#ifdef _WIN32
#if defined(_WIN32)
/* http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx */
secattr.nLength = QSE_SIZEOF(secattr);
@ -165,6 +171,8 @@ qse_pio_t* qse_pio_init (
maxidx = 5;
}
if (maxidx == -1) goto oops;
if ((oflags & QSE_PIO_INTONUL) ||
(oflags & QSE_PIO_OUTTONUL) ||
(oflags & QSE_PIO_ERRTONUL))
@ -210,7 +218,7 @@ qse_pio_t* qse_pio_init (
if (oflags & QSE_PIO_OUTTOERR) startup.hStdOutput = handle[5];
}
if (oflags & QSE_PIO_INTONUL) startup.hStdOutput = windevnul;
if (oflags & QSE_PIO_INTONUL) startup.hStdInput = windevnul;
if (oflags & QSE_PIO_OUTTONUL) startup.hStdOutput = windevnul;
if (oflags & QSE_PIO_ERRTONUL) startup.hStdError = windevnul;
@ -274,8 +282,113 @@ qse_pio_t* qse_pio_init (
CloseHandle (procinfo.hThread);
pio->child = procinfo.hProcess;
#elif defined(__OS2__)
/* TODO: implement this for OS/2 */
if (oflags & QSE_PIO_WRITEIN)
{
ULONG state;
/* child reads, parent writes */
if (DosCreatePipe (
&handle[0], &handle[1], pipe_size) != NO_ERROR) goto oops;
/* don't inherit write handle */
if (DosQueryFHState (handle[1], &state) != NO_ERROR) goto oops;
state &= 0x7F88; /* this & operation as shown in the ibm documents */
if (DosSetFHState (handle[1], state | OPEN_FLAGS_NOINHERIT) != NO_ERROR) goto oops;
minidx = 0; maxidx = 1;
}
if (oflags & QSE_PIO_READOUT)
{
ULONG state;
/* child writes, parent reads */
if (DosCreatePipe (
&handle[2], &handle[3], pipe_size) != NO_ERROR) goto oops;
/* don't inherit read handle */
if (DosQueryFHState (handle[2], &state) != NO_ERROR) goto oops;
state &= 0x7F88; /* this & operation as shown in the ibm documents */
if (DosSetFHState (handle[2], state | OPEN_FLAGS_NOINHERIT) != NO_ERROR) goto oops;
if (minidx == -1) minidx = 2;
maxidx = 3;
}
if (oflags & QSE_PIO_READERR)
{
ULONG state;
/* child writes, parent reads */
if (DosCreatePipe (
&handle[4], &handle[5], pipe_size) != NO_ERROR) goto oops;
/* don't inherit read handle */
if (DosQueryFHState (handle[4], &state) != NO_ERROR) goto oops;
state &= 0x7F88; /* this & operation as shown in the ibm documents */
if (DosSetFHState (handle[4], state | OPEN_FLAGS_NOINHERIT) != NO_ERROR) goto oops;
if (minidx == -1) minidx = 4;
maxidx = 5;
}
if (maxidx == -1) goto oops;
old_in = old_out = old_err = 0xFFFFFFFFFF;
std_in = 0; std_out = 1; std_err = 2;
/* TODO: error handling ... */
if (oflags & QSE_PIO_WRITEIN)
{
DosDupHandle (std_in, &old_in); /* store the original */
DosDupHandle (handle[0], &std_in); /* substitute a pipe handle */
}
if (oflags & QSE_PIO_READOUT)
{
DosDupHandle (std_out, &old_out);
DosDupHandle (handle[3], &std_out);
if (oflags & QSE_PIO_ERRTOOUT) DosDupHandle (handle[3], &std_err);
}
if (oflags & QSE_PIO_READERR)
{
DosDupHandle (std_err, &old_err);
DosDupHandle (handle[5], &std_err);
if (oflags & QSE_PIO_OUTTOERR) DosDupHandle (handle[5], &std_out);
}
/*
if (oflags & QSE_PIO_INTONUL) startup.hStdOutput = os2devnul;
if (oflags & QSE_PIO_OUTTONUL) startup.hStdOutput = os2devnul;
if (oflags & QSE_PIO_ERRTONUL) startup.hStdError = os2devnul;
*/
if (oflags & QSE_PIO_DROPIN) DosClose (std_in);
if (oflags & QSE_PIO_DROPOUT) DosClose (std_out);
if (oflags & QSE_PIO_DROPERR) DosClose (std_err);
rc = DosExecPgm (
&load_error,
QSE_SIZEOF(load_error),
EXEC_ASYNCRESULT,
NULL,
NULL,
&child_rc,
cmd /* TODO: mchar... */
);
if (rc != NO_ERROR) goto oops;
/* restore file handles to the original for this parent */
DosDupHandle (old_in, &std_in);
DosDupHandle (old_out, &std_out);
DosDupHandle (old_err, &std_err);
pio->child = child_rc.codeTerminate;
#else
if (oflags & QSE_PIO_WRITEIN)
@ -312,7 +425,7 @@ qse_pio_t* qse_pio_init (
extern char** environ;
int fcnt = 0;
#ifndef QSE_CHAR_IS_MCHAR
qse_size_t n, mn, wl;
qse_size_t n, mn, wl;
qse_char_t* wcmd = QSE_NULL;
qse_mchar_t buf[64];
#endif
@ -431,7 +544,7 @@ qse_pio_t* qse_pio_init (
#else
if (oflags & QSE_PIO_SHELL)
{
n = qse_wcstombslen (cmd, &mn);
n = qse_wcstombslen (cmd, &mn);
if (cmd[n] != QSE_WT('\0'))
{
/* cmd has illegal sequence */
@ -599,7 +712,7 @@ qse_pio_t* qse_pio_init (
return pio;
oops:
#ifdef _WIN32
#if defined(_WIN32)
if (windevnul != INVALID_HANDLE_VALUE) CloseHandle (windevnul);
if (dup != QSE_NULL) QSE_MMGR_FREE (mmgr, dup);
#endif
@ -608,14 +721,15 @@ oops:
{
if (tio[i] != QSE_NULL) qse_tio_close (tio[i]);
}
#if defined(_WIN32)
for (i = minidx; i < maxidx; i++) CloseHandle (handle[i]);
#elif defined(__OS2__)
/* TODO: */
for (i = minidx; i < maxidx; i++) DosClose (handle[i]);
#else
for (i = minidx; i < maxidx; i++) QSE_CLOSE (handle[i]);
#endif
return QSE_NULL;
}
@ -859,8 +973,7 @@ int qse_pio_wait (qse_pio_t* pio)
DWORD ecode, w;
if (pio->child == QSE_PIO_PID_NIL)
{
{
pio->errnum = QSE_PIO_ECHILD;
return -1;
}
@ -908,8 +1021,42 @@ int qse_pio_wait (qse_pio_t* pio)
return ecode;
#elif defined(__OS2__)
/* TODO: implement this */
return -1;
APIRET rc;
RESULTCODES child_rc;
PID ppid;
if (pio->child == QSE_PIO_PID_NIL)
{
pio->errnum = QSE_PIO_ECHILD;
return -1;
}
rc = DosWaitChild (
DCWA_PROCESS,
((pio->option & QSE_PIO_WAIT_NOBLOCK)? DCWW_NOWAIT: DCWW_WAIT),
&child_rc,
&ppid,
pio->child
);
if (rc == ERROR_CHILD_NOT_COMPLETE)
{
/* the child process is still alive */
return 255 + 1;
}
if (rc != NO_ERROR)
{
/* WAIT_FAILED, WAIT_ABANDONED */
pio->errnum = QSE_PIO_ESUBSYS;
return -1;
}
/* close handle here to emulate waitpid() as much as possible. */
DosClose (pio->child);
pio->child = QSE_PIO_PID_NIL;
return child_rc.codeResult;
#else
int opt = 0;
int ret = -1;

View File

@ -1,5 +1,5 @@
/*
* $Id: sio.c 401 2011-03-16 15:17:25Z hyunghwan.chung $
* $Id: sio.c 402 2011-03-18 15:07:21Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -77,7 +77,7 @@ static qse_sio_t __sio_out =
{
QSE_NULL,
0,
#ifdef _WIN32
#if defined(_WIN32)
(HANDLE)STD_OUTPUT_HANDLE,
#elif defined(__OS2__)
(HFILE)1,
@ -115,7 +115,7 @@ static qse_sio_t __sio_err =
{
QSE_NULL,
0,
#ifdef _WIN32
#if defined(_WIN32)
(HANDLE)STD_ERROR_HANDLE,
#elif defined(__OS2__)
(HFILE)2,
@ -331,7 +331,7 @@ static qse_ssize_t __sio_input (int cmd, void* arg, void* buf, qse_size_t size)
if (cmd == QSE_TIO_IO_DATA)
{
#ifdef _WIN32
#if defined(_WIN32)
/* TODO: I hate this way of adjusting the handle value
* Is there any good ways to do it statically? */
HANDLE h = sio->fio.handle;
@ -360,7 +360,7 @@ static qse_ssize_t __sio_output (int cmd, void* arg, void* buf, qse_size_t size)
if (cmd == QSE_TIO_IO_DATA)
{
#ifdef _WIN32
#if defined(_WIN32)
/* TODO: I hate this way of adjusting the handle value
* Is there any good ways to do it statically? */
HANDLE h = sio->fio.handle;

View File

@ -1,5 +1,5 @@
/*
* $Id: str_cnv.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
* $Id: str_cnv.c 402 2011-03-18 15:07:21Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -247,7 +247,8 @@ qse_size_t qse_wcstombslen (const qse_wchar_t* wcs, qse_size_t* mbslen)
p++; mlen += n;
}
/* this length excludes the terminating null character. */
/* this length holds the number of resulting multi-byte characters
* excluding the terminating null character */
*mbslen = mlen;
/* returns the number of characters handled.
@ -310,6 +311,8 @@ qse_size_t qse_wcstombs (
mbs += n; rem -= n; p++;
}
/* update mbslen to the length of the mbs string converted excluding
* terminating null */
*mbslen -= rem;
/* null-terminate the multibyte sequence if it has sufficient space */
@ -358,15 +361,15 @@ int qse_mbstowcs_strict (
/* wcs not big enough to be null-terminated.
* if it has been null-terminated properly,
* wn should be less than wcslen. */
return -1;
}
return -1;
}
if (mbs[n] != QSE_MT('\0'))
{
/* incomplete sequence or invalid sequence */
return -1;
}
return 0;
return 0;
}
int qse_wcstombs_strict (

View File

@ -1,5 +1,5 @@
/*
* $Id: time.c 400 2011-03-16 08:37:06Z hyunghwan.chung $
* $Id: time.c 402 2011-03-18 15:07:21Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -24,14 +24,17 @@
#if defined(_WIN32)
# include <windows.h>
#elif defined(__OS2__)
# define INCL_DOSDATETIME
# define INCL_DOSERRORS
# include <os2.h>
#else
# include "syscall.h"
# include <sys/time.h>
#endif
#include <time.h>
#ifdef _WIN32
#if defined(_WIN32)
#define WIN_EPOCH_YEAR (1601)
#define WIN_EPOCH_MON (1)
#define WIN_EPOCH_DAY (1)
@ -89,9 +92,33 @@ int qse_gettime (qse_ntime_t* t)
*t = ((qse_ntime_t)(*((qse_int64_t*)&ft)) / (10 * 1000));
*t -= EPOCH_DIFF_MSECS;
return 0;
#elif defined(__OS2__)
/* TODO: implement this */
return -1;
APIRET rc;
DATETIME dt;
qse_btime_t bt;
/* Can I use DosQuerySysInfo(QSV_TIME_LOW) and
* DosQuerySysInfo(QSV_TIME_HIGH) for this instead?
* Maybe, resolution too low as it returns values
* in seconds. */
rc = DosGetDateTime (&dt);
if (rc != NO_ERROR) return -1;
bt.year = dt.year - 1900;
bt.mon = dt.month - 1;
bt.mday = dt.day;
bt.hour = dt.hours;
bt.min = dt.minutes;
bt.sec = dt.seconds;
bt.msec = dt.hundredths * 10;
bt.isdst = -1;
if (qse_timelocal (&bt, t) <= -1) return -1;
return 0;
#else
struct timeval tv;
int n;
@ -99,8 +126,8 @@ int qse_gettime (qse_ntime_t* t)
n = QSE_GETTIMEOFDAY (&tv, QSE_NULL);
if (n == -1) return -1;
*t = (qse_ntime_t)tv.tv_sec*QSE_MSECS_PER_SEC +
(qse_ntime_t)tv.tv_usec/QSE_USECS_PER_MSEC;
*t = (qse_ntime_t)tv.tv_sec * QSE_MSECS_PER_SEC +
(qse_ntime_t)tv.tv_usec / QSE_USECS_PER_MSEC;
return 0;
#endif
}
@ -116,8 +143,24 @@ int qse_settime (qse_ntime_t t)
if (SetSystemTime(&st) == FALSE) return -1;
return 0;
#elif defined(__OS2__)
/* TODO: implement this */
return -1;
APIRET rc;
DATETIME dt;
qse_btime_t bt;
if (qse_localtime (t, &bt) <= -1) return -1;
QSE_MEMSET (&dt, 0, QSE_SIZEOF(dt));
dt.year = bt.year + 1900;
dt.month = bt.mon + 1;
dt.day = bt.mday;
dt.hours = bt.hour;
dt.minutes = bt.min;
dt.seconds = bt.sec;
dt.hundredths = bt.msec / 10;
rc = DosSetDateTime (&dt);
return (rc != NO_ERROR)? -1: 0;
#else
struct timeval tv;
int n;
@ -226,6 +269,12 @@ int qse_localtime (qse_ntime_t nt, qse_btime_t* bt)
#if defined(_WIN32)
tm = localtime (&t);
#elif defined(__OS2__)
# if defined(__WATCOMC__)
struct tm btm;
tm = _localtime (&t, &btm);
# else
# error Please support other compilers that I didn't try.
# endif
#else
struct tm btm;
tm = localtime_r (&t, &btm);
@ -252,8 +301,7 @@ int qse_localtime (qse_ntime_t nt, qse_btime_t* bt)
int qse_timegm (const qse_btime_t* bt, qse_ntime_t* nt)
{
#if 0
#ifdef _WIN32
#if defined(_WIN32)
/* TODO: verify qse_timegm for WIN32 */
SYSTEMTIME st;
FILETIME ft;
@ -272,6 +320,8 @@ int qse_timegm (const qse_btime_t* bt, qse_ntime_t* nt)
*nt -= EPOCH_DIFF_MSECS;
return 0;
#elif defined(__OS2__)
# error NOT IMPLEMENTED YET
#else
/* TODO: qse_timegm - remove dependency on timegm */

View File

@ -21,14 +21,16 @@
#include "scm.h"
static int eval_entity (qse_scm_t* scm);
#if 0
static int save (qse_scm_t* scm, qse_scm_ent_t* )
{
}
static int leave (qse_scm_t* scm)
{
}
}
#endif
int qse_scm_dolambda (qse_scm_t* scm)
{
@ -52,10 +54,10 @@ int qse_scm_doquote (qse_scm_t* scm)
static int define_finish (qse_scm_t* scm)
{
qse_scm_ent_t* var = scm->e.cod;
// qse_scm_ent_t* var = scm->e.cod;
//set var in the environemtn....
leave (scm);
//leave (scm);
return 0;
}
@ -95,7 +97,7 @@ int qse_scm_dodefine (qse_scm_t* scm)
return -1;
}
save car...
// save car...
// let it jump to EVAL and come back to DEFINE_FINISH...
scm->e.cod = PAIR_CAR(cdr);
@ -114,23 +116,23 @@ int qse_scm_dobegin (qse_scm_t* scm)
qse_scm_ent_t* car, * cdr;
if (IS_SMALLINT(scm.e.cod) || TYPE(scm.e.cod) != QSE_SCM_ENT_PAIR)
if (IS_SMALLINT(scm, scm->e.cod) || TYPE(scm->e.cod) != QSE_SCM_ENT_PAIR)
{
/* (begin (+ x y) . 30) */
qse_scm_seterror (scm, QSE_SCM_EARGBAD, QSE_NULL, QSE_NULL);
return -1;
}
car = PAIR_CAR(scm.e.cod);
cdr = PAIR_CDR(scm.e.cod);
car = PAIR_CAR(scm->e.cod);
cdr = PAIR_CDR(scm->e.cod);
if (!IS_NIL(cdr))
if (!IS_NIL(scm,cdr))
{
save (BEGIN... cdr);
//save (BEGIN... cdr);
}
scm.e.cod = car;
scm.e.op = eval_entity;
scm->e.cod = car;
scm->e.op = eval_entity;
return 0;
}