added QSE_FIO_TEMPORARY.

added qse_rand31()
fixed a minor bug in handling QSE_FMTINTMAX_ZEROLEAD
This commit is contained in:
2011-11-16 15:18:46 +00:00
parent e15fcd0c14
commit df28fde9ef
18 changed files with 645 additions and 302 deletions

View File

@ -325,26 +325,42 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
for (i = 0; i < len; i++)
{
/* TODO: maybe more de-escaping?? */
if (ptr[i] == QSE_T('\n'))
PUT_SRCSTR (awk, QSE_T("\\n"));
else if (ptr[i] == QSE_T('\r'))
PUT_SRCSTR (awk, QSE_T("\\r"));
else if (ptr[i] == QSE_T('\f'))
PUT_SRCSTR (awk, QSE_T("\\f"));
else if (ptr[i] == QSE_T('\b'))
PUT_SRCSTR (awk, QSE_T("\\b"));
else if (ptr[i] == QSE_T('\v'))
PUT_SRCSTR (awk, QSE_T("\\v"));
else if (ptr[i] == QSE_T('\a'))
PUT_SRCSTR (awk, QSE_T("\\a"));
else if (ptr[i] == QSE_T('\0'))
PUT_SRCSTR (awk, QSE_T("\\0"));
else if (ptr[i] == QSE_T('\"'))
PUT_SRCSTR (awk, QSE_T("\\\""));
else if (ptr[i] == QSE_T('\\'))
PUT_SRCSTR (awk, QSE_T("\\\\"));
else
PUT_SRCSTRX (awk, &ptr[i], 1);
switch (ptr[i])
{
case QSE_T('\n'):
PUT_SRCSTR (awk, QSE_T("\\n"));
break;
case QSE_T('\r'):
PUT_SRCSTR (awk, QSE_T("\\r"));
break;
case QSE_T('\t'):
PUT_SRCSTR (awk, QSE_T("\\t"));
break;
case QSE_T('\f'):
PUT_SRCSTR (awk, QSE_T("\\f"));
break;
case QSE_T('\b'):
PUT_SRCSTR (awk, QSE_T("\\b"));
break;
case QSE_T('\v'):
PUT_SRCSTR (awk, QSE_T("\\v"));
break;
case QSE_T('\a'):
PUT_SRCSTR (awk, QSE_T("\\a"));
break;
case QSE_T('\0'):
PUT_SRCSTR (awk, QSE_T("\\0"));
break;
case QSE_T('\"'):
PUT_SRCSTR (awk, QSE_T("\\\""));
break;
case QSE_T('\\'):
PUT_SRCSTR (awk, QSE_T("\\\\"));
break;
default:
PUT_SRCSTRX (awk, &ptr[i], 1);
break;
}
}
PUT_SRCSTR (awk, QSE_T("\""));
break;

View File

@ -19,6 +19,7 @@ noinst_HEADERS = \
tre-stack.h
libqsecmn_la_SOURCES = \
alg-rand.c \
alg-search.c \
alg-sort.c \
assert.c \

View File

@ -75,19 +75,19 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libqsecmn_la_DEPENDENCIES =
am_libqsecmn_la_OBJECTS = alg-search.lo alg-sort.lo assert.lo chr.lo \
chr-cnv.lo dll.lo env.lo gdl.lo htb.lo lda.lo fio.lo fma.lo \
fmt.lo main.lo mem.lo oht.lo opt.lo path-basename.lo \
path-canon.lo pio.lo pma.lo rbt.lo rex.lo sio.lo sll.lo \
stdio.lo str-beg.lo str-cat.lo str-chr.lo str-cnv.lo \
str-cmp.lo str-cpy.lo str-del.lo str-dup.lo str-dynm.lo \
str-dynw.lo str-end.lo str-excl.lo str-fcpy.lo str-fnmat.lo \
str-incl.lo str-len.lo str-pac.lo str-pbrk.lo str-put.lo \
str-rev.lo str-rot.lo str-set.lo str-spl.lo str-spn.lo \
str-str.lo str-subst.lo str-tok.lo str-trm.lo str-word.lo \
time.lo tio.lo tio-get.lo tio-put.lo tre.lo tre-ast.lo \
tre-compile.lo tre-match-backtrack.lo tre-match-parallel.lo \
tre-parse.lo tre-stack.lo utf8.lo xma.lo
am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \
assert.lo chr.lo chr-cnv.lo dll.lo env.lo gdl.lo htb.lo lda.lo \
fio.lo fma.lo fmt.lo main.lo mem.lo oht.lo opt.lo \
path-basename.lo path-canon.lo pio.lo pma.lo rbt.lo rex.lo \
sio.lo sll.lo stdio.lo str-beg.lo str-cat.lo str-chr.lo \
str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo str-dup.lo \
str-dynm.lo str-dynw.lo str-end.lo str-excl.lo str-fcpy.lo \
str-fnmat.lo str-incl.lo str-len.lo str-pac.lo str-pbrk.lo \
str-put.lo str-rev.lo str-rot.lo str-set.lo str-spl.lo \
str-spn.lo str-str.lo str-subst.lo str-tok.lo str-trm.lo \
str-word.lo time.lo tio.lo tio-get.lo tio-put.lo tre.lo \
tre-ast.lo tre-compile.lo tre-match-backtrack.lo \
tre-match-parallel.lo tre-parse.lo tre-stack.lo utf8.lo xma.lo
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -288,6 +288,7 @@ noinst_HEADERS = \
tre-stack.h
libqsecmn_la_SOURCES = \
alg-rand.c \
alg-search.c \
alg-sort.c \
assert.c \
@ -441,6 +442,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mmgr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdMmgr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-rand.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-sort.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assert.Plo@am__quote@

23
qse/lib/cmn/alg-rand.c Normal file
View File

@ -0,0 +1,23 @@
#include <qse/cmn/alg.h>
/* Park-Miller "minimal standard" 31 bit
* pseudo-random number generator, implemented
* with David G. Carta's optimisation: with
* 32 bit math and wihtout division.
*/
qse_uint32_t qse_rand31 (qse_uint32_t seed)
{
qse_uint32_t hi, lo;
if (seed == 0) seed++;
lo = 16807 * (seed & 0xFFFF);
hi = 16807 * (seed >> 16);
lo += (hi & 0x7FFF) << 16;
lo += hi >> 15;
if (lo > 0x7FFFFFFFul) lo -= 0x7FFFFFFFul;
return lo;
}

View File

@ -20,6 +20,9 @@
#include <qse/cmn/fio.h>
#include <qse/cmn/str.h>
#include <qse/cmn/fmt.h>
#include <qse/cmn/alg.h>
#include <qse/cmn/time.h>
#include "mem.h"
#if defined(_WIN32)
@ -90,15 +93,68 @@ int qse_fio_init (
{
qse_fio_hnd_t handle;
qse_uint32_t temp_no;
qse_char_t* temp_ptr;
qse_size_t temp_tries;
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
QSE_MEMSET (fio, 0, QSE_SIZEOF(*fio));
fio->mmgr = mmgr;
/* store the flags for later use though only OS/2 needs
/* Store the flags for later use though only OS/2 needs
* this at this moment */
fio->flags = flags;
if (flags & QSE_FIO_TEMPORARY)
{
qse_ntime_t now;
QSE_ASSERTX (
(flags & QSE_FIO_HANDLE) == 0,
"QSE_FIO_TEMPORARY and QSE_FIO_HANDLE are mutually exclusive"
);
temp_no = 0;
for (temp_ptr = path; *temp_ptr; temp_ptr++)
temp_no += *temp_ptr;
/* The path name template must be at least 4 characters long
* excluding the terminating null. this function fails if not */
if (temp_ptr - path < 4) return -1;
qse_gettime (&now);
temp_no += (now & 0xFFFFFFFFlu);
temp_tries = 0;
temp_ptr -= 4;
retry_temporary:
temp_tries++;
/* Fails after 5000 tries. 5000 randomly chosen */
if (temp_tries > 5000) return -1;
/* Generate the next random number to use to make a
* new path name */
temp_no = qse_rand31 (temp_no);
/*
* You must not pass a constant string for a path name
* when QSE_FIO_TEMPORARY is set, because it changes
* the path name with a random number generated
*/
qse_fmtuintmax (
temp_ptr,
4,
temp_no % 0x10000,
16 | QSE_FMTUINTMAX_NOTRUNC | QSE_FMTUINTMAX_NONULL,
4,
QSE_T('\0'),
QSE_NULL
);
}
#if defined(_WIN32)
if (flags & QSE_FIO_HANDLE)
{
@ -107,7 +163,7 @@ int qse_fio_init (
else
{
DWORD desired_access = 0;
DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
DWORD creation_disposition = 0;
DWORD flag_and_attr = FILE_ATTRIBUTE_NORMAL;
@ -141,6 +197,8 @@ int qse_fio_init (
share_mode &= ~FILE_SHARE_READ;
if (flags & QSE_FIO_NOSHWR)
share_mode &= ~FILE_SHARE_WRITE;
if (flags & QSE_FIO_NOSHDL)
share_mode &= ~FILE_SHARE_DELETE;
if (!(mode & QSE_FIO_WUSR))
flag_and_attr = FILE_ATTRIBUTE_READONLY;
@ -162,7 +220,11 @@ int qse_fio_init (
creation_disposition, flag_and_attr, 0
);
}
if (handle == INVALID_HANDLE_VALUE) return -1;
if (handle == INVALID_HANDLE_VALUE)
{
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
return -1;
}
/* some special check */
if (GetFileType(handle) == FILE_TYPE_UNKNOWN)
@ -258,7 +320,11 @@ int qse_fio_init (
0L
);
if (ret != NO_ERROR) return -1;
if (ret != NO_ERROR)
{
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
return -1;
}
}
#elif defined(__DOS__)
@ -308,7 +374,11 @@ int qse_fio_init (
oflags,
permission
);
if (handle <= -1) return -1;
if (handle <= -1)
{
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
return -1;
}
}
#else
@ -367,7 +437,11 @@ int qse_fio_init (
handle = QSE_OPEN (path_mb, desired_access, mode);
}
if (handle == -1) return -1;
if (handle == -1)
{
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
return -1;
}
/* set some file access hints */
#if defined(POSIX_FADV_RANDOM)

View File

@ -60,14 +60,16 @@ static int fmt_unsigned_to_mbs (
}
else
{
qse_uintmax_t v = value;
/* store the resulting numeric string into 'tmp' first */
p = tmp;
do
{
*p++ = xbasestr[value % base];
value /= base;
*p++ = xbasestr[v % base];
v /= base;
}
while (value > 0);
while (v > 0);
/* reslen is the length of the resulting string without padding. */
reslen = (int)(p - tmp);
@ -87,8 +89,10 @@ static int fmt_unsigned_to_mbs (
else
{
preczero = 0;
if (base_and_flags & QSE_FMTINTMAXTOMBS_ZEROLEAD)
if ((base_and_flags & QSE_FMTINTMAXTOMBS_ZEROLEAD) && value != 0)
{
/* if value is zero, 0 is emitted from it.
* so ZEROLEAD don't need to add another 0. */
preczero++;
reslen++;
}
@ -319,14 +323,16 @@ static int fmt_unsigned_to_wcs (
}
else
{
qse_uintmax_t v = value;
/* store the resulting numeric string into 'tmp' first */
p = tmp;
do
{
*p++ = xbasestr[value % base];
value /= base;
*p++ = xbasestr[v % base];
v /= base;
}
while (value > 0);
while (v > 0);
/* reslen is the length of the resulting string without padding. */
reslen = (int)(p - tmp);
@ -346,8 +352,10 @@ static int fmt_unsigned_to_wcs (
else
{
preczero = 0;
if (base_and_flags & QSE_FMTINTMAXTOWCS_ZEROLEAD)
if ((base_and_flags & QSE_FMTINTMAXTOWCS_ZEROLEAD) && value != 0)
{
/* if value is zero, 0 is emitted from it.
* so ZEROLEAD don't need to add another 0. */
preczero++;
reslen++;
}

View File

@ -724,11 +724,11 @@ qse_dir_ent_t* qse_dir_read (qse_dir_t* dir, int flags)
QSE_SECNSEC_TO_MSEC(st.st_ctimespec.tv_sec,st.st_ctimespec.tv_nsec);
#else
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
dir->ent.time.create = st.st_birthtime * QSE_MSEC_PER_SEC;
dir->ent.time.create = st.st_birthtime * QSE_MSECS_PER_SEC;
#endif
dir->ent.time.access = st.st_atime * QSE_MSEC_PER_SEC;
dir->ent.time.modify = st.st_mtime * QSE_MSEC_PER_SEC;
dir->ent.time.change = st.st_ctime * QSE_MSEC_PER_SEC;
dir->ent.time.access = st.st_atime * QSE_MSECS_PER_SEC;
dir->ent.time.modify = st.st_mtime * QSE_MSECS_PER_SEC;
dir->ent.time.change = st.st_ctime * QSE_MSECS_PER_SEC;
#endif
dir->ent.flags |= QSE_DIR_ENT_TIME;
}