* fixed an issue in parsing an expression like "a++ ++b" or "1 ++b"

* added _WIN32 code handling QSE_PIO_MBSCMD
* fixed various _WIN32 issues in qse_env_t
* added untested OS2 code handling QSE_PIO_MBSCMD
This commit is contained in:
2011-08-12 09:11:02 +00:00
parent cfe85ecc60
commit f843a6e003
13 changed files with 497 additions and 834 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c 521 2011-07-25 08:25:13Z hyunghwan.chung $
* $Id: parse.c 540 2011-08-11 15:11:02Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -4141,22 +4141,27 @@ static qse_awk_nde_t* parse_increment (
opcode2 = MATCH(awk,TOK_PLUSPLUS)? QSE_AWK_INCOP_PLUS:
MATCH(awk,TOK_MINUSMINUS)? QSE_AWK_INCOP_MINUS: -1;
if (opcode1 != -1 && opcode2 != -1)
{
/* both prefix and postfix increment operator.
* not allowed */
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_EPREPST, xloc);
return QSE_NULL;
if ((awk->option & QSE_AWK_EXPLICIT) && !(awk->option & QSE_AWK_IMPLICIT))
{
if (opcode1 != -1 && opcode2 != -1)
{
/* both prefix and postfix increment operator.
* not allowed */
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_EPREPST, xloc);
return QSE_NULL;
}
}
else if (opcode1 == -1 && opcode2 == -1)
if (opcode1 == -1 && opcode2 == -1)
{
/* no increment operators */
return left;
}
else if (opcode1 != -1)
{
/* prefix increment operator */
/* prefix increment operator.
* ignore a potential postfix operator */
type = QSE_AWK_NDE_EXP_INCPRE;
opcode = opcode1;
}
@ -4175,9 +4180,18 @@ static qse_awk_nde_t* parse_increment (
if (!is_var(left) && left->type != QSE_AWK_NDE_POS)
{
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_EINCDECOPR, xloc);
return QSE_NULL;
if (type == QSE_AWK_NDE_EXP_INCPST)
{
/* For an expression like 1 ++y,
* left is 1. so we leave ++ for y. */
return left;
}
else
{
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_EINCDECOPR, xloc);
return QSE_NULL;
}
}
nde = (qse_awk_nde_exp_t*)

View File

@ -23,6 +23,10 @@
#include <qse/cmn/str.h>
#include "mem.h"
#if defined(_WIN32)
# include <windows.h>
#endif
#define STRSIZE 4096
#define ARRSIZE 128
@ -207,7 +211,7 @@ static int add_envstrw (qse_env_t* env, const qse_wchar_t* nv)
return 0;
}
static int deletem (qse_env_t* env, const qse_wchar_t* name)
static int deletew (qse_env_t* env, const qse_wchar_t* name)
{
qse_size_t i;
@ -224,7 +228,7 @@ static int deletem (qse_env_t* env, const qse_wchar_t* name)
/* bingo */
qse_size_t len, rem;
len = qse_mbslen (vp) + 1;
len = qse_wcslen (vp) + 1;
rem = env->str.len - (vp + len - env->str.ptr) + 1;
QSE_MEMCPY (vp, vp + len, rem * QSE_SIZEOF(*vp));
env->str.len -= len;
@ -416,7 +420,7 @@ int qse_env_deletem (qse_env_t* env, const qse_mchar_t* name)
}
#if defined(_WIN32)
static qse_char_t* getenv (const qse_char_t* name, int* free)
static qse_char_t* get_env (qse_env_t* env, const qse_char_t* name, int* free)
{
DWORD n;
@ -449,7 +453,7 @@ static qse_char_t* getenv (const qse_char_t* name, int* free)
# error IMPLEMENT THIS
#else
static qse_mchar_t* getenv (const qse_mchar_t* name, int* free)
static qse_mchar_t* get_env (qse_env_t* env, const qse_mchar_t* name, int* free)
{
extern char** environ;
char** p = environ;
@ -473,13 +477,16 @@ static qse_mchar_t* getenv (const qse_mchar_t* name, int* free)
int qse_env_insertsysw (qse_env_t* env, const qse_wchar_t* name)
{
#if defined(_WIN32) && defined(QSE_CHAR_IS_WCHAR)
int ret, free;
qse_wchar_t* v;
int free;
int ret = -1;
v = getenv (name, &free);
if (v == QSE_NULL) return 0;
ret = insertw (env, name, v);
if (free) QSE_MMGR_FREE (env->mmgr, v);
v = get_env (env, name, &free);
if (v)
{
ret = insertw (env, name, v);
if (free) QSE_MMGR_FREE (env->mmgr, v);
}
return ret;
#else
/* convert wchar to mchar */
@ -513,13 +520,16 @@ int qse_env_insertsysm (qse_env_t* env, const qse_mchar_t* name)
return ret;
#else
int ret, free;
qse_mchar_t* v;
int free;
int ret = -1;
v = getenv (name, &free);
if (v == QSE_NULL) return -1;
ret = insertm (env, name, v);
if (free) QSE_MMGR_FREE (env->mmgr, v);
v = get_env (env, name, &free);
if (v)
{
ret = insertm (env, name, v);
if (free) QSE_MMGR_FREE (env->mmgr, v);
}
return ret;
#endif
}
@ -536,14 +546,24 @@ static int load_curenv (qse_env_t* env)
#if defined(QSE_CHAR_IS_WCHAR)
while (*envstr != QSE_WT('\0'))
{
if (add_envstrw (env, envstr) <= -1) { ret = -1; goto done; }
envstr += qse_wcslen(evnstr) + 1;
/* It seems that entries like the followings exist in the
* environment variable string.
* - =::=::\
* - =C:=C:\Documents and Settings\Administrator
* - =ExitCode=00000000
*
* So entries beginning with = are excluded.
*/
if (*envstr != QSE_WT('=') &&
add_envstrw (env, envstr) <= -1) { ret = -1; goto done; }
envstr += qse_wcslen (envstr) + 1;
}
#else
while (*envstr != QSE_MT('\0'))
{
if (add_envstrm (env, envstr) <= -1) { ret = -1; goto done; }
envstr += qse_mbslen(evnstr) + 1;
if (*envstr != QSE_MT('=') &&
add_envstrm (env, envstr) <= -1) { ret = -1; goto done; }
envstr += qse_mbslen (envstr) + 1;
}
#endif

View File

@ -1,5 +1,5 @@
/*
* $Id: pio.c 539 2011-08-10 16:18:35Z hyunghwan.chung $
* $Id: pio.c 540 2011-08-11 15:11:02Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -244,19 +244,66 @@ qse_pio_t* qse_pio_init (
* takes the entire command line */
{
const qse_char_t* dupcmd;
qse_char_t* dupcmd;
BOOL x;
if (oflags & QSE_PIO_SHELL)
{
qse_size_t reqlen;
#if defined(QSE_CHAR_IS_WCHAR)
if (oflags & QSE_PIO_MBSCMD)
{
const qse_mchar_t* mbs = (const qse_mchar_t*)cmd;
qse_size_t ll = qse_mbstowcslen (mbs, &reqlen);
if (mbs[ll] != QSE_MT('\0')) goto oops; /* illegal sequence */
}
else
{
#endif
reqlen = qse_strlen(cmd);
#if defined(QSE_CHAR_IS_WCHAR)
}
#endif
reqlen++; /* increment for a terminating null */
dupcmd = QSE_MMGR_ALLOC (
mmgr, (11+qse_strlen(cmd)+1 )*QSE_SIZEOF(qse_char_t));
mmgr, (11 + reqlen) * QSE_SIZEOF(*dupcmd)
);
if (dupcmd == QSE_NULL) goto oops;
qse_strcpy (dupcmd, QSE_T("cmd.exe /c "));
qse_strcpy (&dupcmd[11], cmd);
#if defined(QSE_CHAR_IS_WCHAR)
if (oflags & QSE_PIO_MBSCMD)
{
qse_mbstowcs ((const qse_mchar_t*)cmd, &dupcmd[11], &reqlen);
}
else
{
#endif
qse_strcpy (&dupcmd[11], cmd);
#if defined(QSE_CHAR_IS_WCHAR)
}
#endif
}
else
{
#if defined(QSE_CHAR_IS_WCHAR)
if (oflags & QSE_PIO_MBSCMD)
{
dupcmd = qse_mbstowcsdup ((const qse_mchar_t*)cmd, mmgr);
}
else
{
#endif
/* CreateProcess requires command buffer to be read-write. */
dupcmd = qse_strdup (cmd, mmgr);
#if defined(QSE_CHAR_IS_WCHAR)
}
#endif
if (dupcmd == QSE_NULL) goto oops;
}
else dupcmd = cmd;
x = CreateProcess (
QSE_NULL, /* LPCTSTR lpApplicationName */
@ -275,7 +322,7 @@ qse_pio_t* qse_pio_init (
&procinfo /* LPPROCESS_INFORMATION lpProcessInformation */
);
if (dupcmd != cmd) QSE_MMGR_FREE (mmgr, dupcmd);
QSE_MMGR_FREE (mmgr, dupcmd);
if (x == FALSE) goto oops;
}
@ -459,11 +506,18 @@ qse_pio_t* qse_pio_init (
#ifdef QSE_CHAR_IS_MCHAR
mn = qse_strlen(cmd);
#else
n = qse_wcstombslen (cmd, &mn);
if (cmd[n] != QSE_WT('\0')) goto oops; /* illegal sequence found */
if (oflags & QSE_PIO_MBSCMD)
{
mn = qse_mbslen((const qse_mchar_t*)cmd);
}
else
{
n = qse_wcstombslen (cmd, &mn);
if (cmd[n] != QSE_WT('\0')) goto oops; /* illegal sequence found */
}
#endif
cmd_line = QSE_MMGR_ALLOC (
mmgr, ((11+mn+1+1) * QSE_SIZEOF(qse_mchar_t)));
mmgr, ((11+mn+1+1) * QSE_SIZEOF(*cmd_line)));
if (cmd_line == QSE_NULL) goto oops;
qse_mbscpy (cmd_line, QSE_MT("cmd.exe")); /* cmd.exe\0/c */
@ -471,8 +525,15 @@ qse_pio_t* qse_pio_init (
#ifdef QSE_CHAR_IS_MCHAR
qse_mbscpy (&cmd_line[11], cmd);
#else
mn = mn + 1; /* update the buffer size */
n = qse_wcstombs (cmd, &cmd_line[11], &mn);
if (oflags & QSE_PIO_MBSCMD)
{
qse_mbscpy (&cmd_line[11], (const qse_mchar_t*)cmd);
}
else
{
mn = mn + 1; /* update the buffer size */
n = qse_wcstombs (cmd, &cmd_line[11], &mn);
}
#endif
cmd_line[11+mn+1] = QSE_MT('\0'); /* additional \0 after \0 */
@ -487,15 +548,24 @@ qse_pio_t* qse_pio_init (
cmd_line = qse_strdup2 (cmd, QSE_T(" "), pio->mmgr);
if (cmd_line == QSE_NULL) goto oops;
#else
qse_size_t n, mn;
n = qse_wcstombslen (cmd, &mn);
if (cmd[n] != QSE_T('\0')) goto oops; /* illegal sequence in cmd */
mn = mn + 1;
cmd_line = QSE_MMGR_ALLOC (pio->mmgr, mn * QSE_SIZEOF(qse_char_t));
if (cmd_line == QSE_NULL) goto oops;
if (oflags & QSE_PIO_MBSCMD)
{
qse_size_t mn = qse_mbslen((const qse_mchar_t*)cmd);
cmd_line = qse_mbsdup2 ((const qse_mchar_t*)cmd, QSE_MT(" "), pio->mmgr);
if (cmd_line == QSE_NULL) goto oops;
}
else
{
qse_size_t n, mn;
n = qse_wcstombslen (cmd, &mn);
if (cmd[n] != QSE_T('\0')) goto oops; /* illegal sequence in cmd */
mn = mn + 1;
cmd_line = QSE_MMGR_ALLOC (pio->mmgr, mn * QSE_SIZEOF(qse_char_t));
if (cmd_line == QSE_NULL) goto oops;
qse_wcstombs (cmd, cmd_line, &mn);
qse_wcstombs (cmd, cmd_line, &mn);
}
#endif
/* TODO: enhance this part by:

View File

@ -716,14 +716,20 @@ void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* ctx)
#ifdef QSE_XMA_ENABLE_STAT
dumper (ctx, QSE_T("== statistics ==\n"));
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
#if (QSE_SIZEOF_SIZE_T == QSE_SIZEOF_LONG)
dumper (ctx, QSE_T("total = %lu\n"), (unsigned long)xma->stat.total);
dumper (ctx, QSE_T("alloc = %lu\n"), (unsigned long)xma->stat.alloc);
dumper (ctx, QSE_T("avail = %lu\n"), (unsigned long)xma->stat.avail);
#else
#elif (QSE_SIZEOF_SIZE_T == QSE_SIZEOF_LONG_LONG)
dumper (ctx, QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total);
dumper (ctx, QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc);
dumper (ctx, QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail);
#elif (QSE_SIZEOF_SIZE_T == QSE_SIZEOF_INT)
dumper (ctx, QSE_T("total = %u\n"), (unsigned int)xma->stat.total);
dumper (ctx, QSE_T("alloc = %u\n"), (unsigned int)xma->stat.alloc);
dumper (ctx, QSE_T("avail = %u\n"), (unsigned int)xma->stat.avail);
#else
# error weird size of qse_size_t. unsupported platform
#endif
#endif
@ -731,14 +737,20 @@ void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* ctx)
dumper (ctx, QSE_T(" size avail address\n"));
for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next)
{
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
dumper (ctx, QSE_T(" %-18lu %-5d %p\n"),
(unsigned long)tmp->size, tmp->avail, tmp
#if (QSE_SIZEOF_SIZE_T == QSE_SIZEOF_LONG)
dumper (ctx, QSE_T(" %-18lu %-5u %p\n"),
(unsigned long)tmp->size, (unsigned int)tmp->avail, tmp
);
#elif (QSE_SIZEOF_SIZE_T == QSE_SIZEOF_LONG_LONG)
dumper (ctx, QSE_T(" %-18llu %-5u %p\n"),
(unsigned long long)tmp->size, (unsigned int)tmp->avail, tmp
);
#elif (QSE_SIZEOF_SIZE_T == QSE_SIZEOF_INT)
dumper (ctx, QSE_T(" %-18u %-5u %p\n"),
(unsigned int)tmp->size, (unsigned int)tmp->avail, tmp
);
#else
dumper (ctx, QSE_T(" %-18llu %-5d %p\n"),
(unsigned long long)tmp->size, tmp->avail, tmp
);
# error weird size of qse_size_t. unsupported platform
#endif
if (tmp->avail) fsum += tmp->size;
else asum += tmp->size;
@ -749,21 +761,31 @@ void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* ctx)
#endif
dumper (ctx, QSE_T("---------------------------------------\n"));
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
#if (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_LONG)
dumper (ctx, QSE_T("Allocated blocks: %18lu bytes\n"), (unsigned long)asum);
dumper (ctx, QSE_T("Available blocks: %18lu bytes\n"), (unsigned long)fsum);
#else
#elif (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_LONG_LONG)
dumper (ctx, QSE_T("Allocated blocks: %18llu bytes\n"), (unsigned long long)asum);
dumper (ctx, QSE_T("Available blocks: %18llu bytes\n"), (unsigned long long)fsum);
#elif (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_INT)
dumper (ctx, QSE_T("Allocated blocks: %18u bytes\n"), (unsigned int)asum);
dumper (ctx, QSE_T("Available blocks: %18u bytes\n"), (unsigned int)fsum);
#else
# error weird size of qse_ulong_t. unsupported platform
#endif
#ifdef QSE_XMA_ENABLE_STAT
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
#if (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_LONG)
dumper (ctx, QSE_T("Internal use : %18lu bytes\n"), (unsigned long)isum);
dumper (ctx, QSE_T("Total : %18lu bytes\n"), (unsigned long)(asum + fsum + isum));
#else
#elif (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_LONG_LONG)
dumper (ctx, QSE_T("Internal use : %18llu bytes\n"), (unsigned long long)isum);
dumper (ctx, QSE_T("Total : %18llu bytes\n"), (unsigned long long)(asum + fsum + isum));
#elif (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_INT)
dumper (ctx, QSE_T("Internal use : %18u bytes\n"), (unsigned int)isum);
dumper (ctx, QSE_T("Total : %18u bytes\n"), (unsigned int)(asum + fsum + isum));
#else
# error weird size of qse_ulong_t. unsupported platform
#endif
#endif