From 68ad99eca7d4101b622d892b904b9059f8dccc74 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 28 Mar 2021 18:12:07 +0000 Subject: [PATCH] added hcl_dupucstr(), hcl_dupbcstr() --- lib/hcl.h | 32 +++++++++++++++---- lib/std.c | 80 ++++++++++++++++++++++++++++++++++++++++++---- lib/utl.c | 96 +++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 160 insertions(+), 48 deletions(-) diff --git a/lib/hcl.h b/lib/hcl.h index a96a083..7558f9e 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -2542,6 +2542,9 @@ HCL_EXPORT int hcl_convutobcstr ( # define hcl_dupbtooocstrwithheadroom(hcl,hrb,bcs,oocslen) hcl_dupbtoucstrwithheadroom(hcl,hrb,bcs,oocslen) # define hcl_dupootobcstr(hcl,oocs,bcslen) hcl_duputobcstr(hcl,oocs,bcslen) # define hcl_dupbtooocstr(hcl,bcs,oocslen) hcl_dupbtoucstr(hcl,bcs,oocslen) + +# define hcl_dupootoucstr(hcl,oocs,ucslen) hcl_dupucstr(hcl,oocs,ucslen) +# define hcl_duputooocstr(hcl,ucs,oocslen) hcl_dupucstr(hcl,ucs,oocslen) #else # define hcl_dupootoucharswithheadroom(hcl,hrb,oocs,oocslen,ucslen) hcl_dupbtoucharswithheadroom(hcl,hrb,oocs,oocslen,ucslen) # define hcl_duputooocharswithheadroom(hcl,hrb,ucs,ucslen,oocslen) hcl_duputobcharswithheadroom(hcl,hrb,ucs,ucslen,oocslen) @@ -2552,6 +2555,9 @@ HCL_EXPORT int hcl_convutobcstr ( # define hcl_duputooocstrwithheadroom(hcl,hrb,ucs,oocslen) hcl_duputobcstrwithheadroom(hcl,hrb,ucs,oocslen) # define hcl_dupootoucstr(hcl,oocs,ucslen) hcl_dupbtoucstr(hcl,oocs,ucslen) # define hcl_duputooocstr(hcl,ucs,oocslen) hcl_duputobcstr(hcl,ucs,oocslen) + +# define hcl_dupootobcstr(hcl,oocs,bcslen) hcl_dupbcstr(hcl,oocs,bcslen) +# define hcl_dupbtooocstr(hcl,bcs,oocslen) hcl_dupbcstr(hcl,bcs,oocslen) #endif @@ -2615,20 +2621,34 @@ HCL_EXPORT hcl_bch_t* hcl_duputobcstr ( #if defined(HCL_OOCH_IS_UCH) # define hcl_dupoochars(hcl,oocs,oocslen) hcl_dupuchars(hcl,oocs,oocslen) +# define hcl_dupoocstr(hcl,oocs,oocslen) hcl_dupucstr(hcl,oocs,oocslen) #else # define hcl_dupoochars(hcl,oocs,oocslen) hcl_dupbchars(hcl,oocs,oocslen) +# define hcl_dupoocstr(hcl,oocs,oocslen) hcl_dupbcstr(hcl,oocs,oocslen) #endif HCL_EXPORT hcl_uch_t* hcl_dupuchars ( - hcl_t* hcl, - const hcl_uch_t* ucs, - hcl_oow_t ucslen + hcl_t* hcl, + const hcl_uch_t* ucs, + hcl_oow_t ucslen ); HCL_EXPORT hcl_bch_t* hcl_dupbchars ( - hcl_t* hcl, - const hcl_bch_t* bcs, - hcl_oow_t bcslen + hcl_t* hcl, + const hcl_bch_t* bcs, + hcl_oow_t bcslen +); + +HCL_EXPORT hcl_uch_t* hcl_dupucstr ( + hcl_t* hcl, + const hcl_uch_t* ucs, + hcl_oow_t* ucslen +); + +HCL_EXPORT hcl_bch_t* hcl_dupbcstr ( + hcl_t* hcl, + const hcl_bch_t* bcs, + hcl_oow_t* bcslen ); /* ========================================================================= diff --git a/lib/std.c b/lib/std.c index 1189f6f..cdd5edd 100644 --- a/lib/std.c +++ b/lib/std.c @@ -71,9 +71,22 @@ # include # include # include - # include +# include /* some types for socket.h */ +# include /* for socketpair */ +# include +# include /* FIONBIO */ +# include /* for SOCEXXX error codes */ + +# define BSD_SELECT +# if defined(TCPV40HDRS) +# include +# else +# include +# endif + +# define USE_SELECT /* fake XPOLLXXX values */ # define XPOLLIN (1 << 0) # define XPOLLOUT (1 << 1) @@ -252,6 +265,13 @@ # define MUTEX_UNLOCK(x) #endif +#if defined(USE_SELECT) +struct select_fd_t +{ + int fd; + int events; +}; +#endif typedef struct xtn_t xtn_t; struct xtn_t @@ -548,8 +568,9 @@ static void log_write (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hc tmp = localtime(&now); #endif - #if defined(__BORLANDC__) - /* the borland compiler doesn't handle %z properly - it showed 00 all the time */ + #if defined(__BORLANDC__) || defined(__IBMC__) + /* the borland compiler doesn't handle %z properly - it showed 00 all the time. + * the visualage compiler 3.0 doesn't support %z */ tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp); #else tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp); @@ -758,6 +779,19 @@ static hcl_errnum_t os2err_to_errnum (APIRET errcode) return HCL_ESYSERR; } } +static hcl_errnum_t os2sockerr_to_errnum (int errcode) +{ + switch (errcode) + { + case SOCEPERM: return HCL_EPERM; + case SOCENOENT: return HCL_ENOENT; + case SOCEINTR: return HCL_EINTR; + case SOCEACCES: return HCL_EACCES; + case SOCEINVAL: return HCL_EINVAL; + case SOCENOMEM: return HCL_ESYSMEM; + case SOCEPIPE: return HCL_EPIPE; + } +} #endif #if defined(macintosh) @@ -789,6 +823,13 @@ static hcl_errnum_t _syserrstrb (hcl_t* hcl, int syserr_type, int syserr_code, h { switch (syserr_type) { + case 2: + #if defined(__OS2__) + if (buf) hcl_copy_bcstr (buf, len, sock_strerror(syserr_code)); + return os2sockerr_to_errnum(syserr_code); + #endif + /* fall thru for other platforms */ + case 1: #if defined(_WIN32) if (buf) @@ -804,12 +845,17 @@ static hcl_errnum_t _syserrstrb (hcl_t* hcl, int syserr_type, int syserr_code, h return winerr_to_errnum(syserr_code); #elif defined(__OS2__) /* TODO: convert code to string */ - if (buf) hcl_copy_bcstr (buf, len, "system error"); + if (buf) + { + char tmp[64]; + sprintf (tmp, "system error %d\n", (int)syserr_code); + hcl_copy_bcstr (buf, len, tmp); + } return os2err_to_errnum(syserr_code); #elif defined(macintosh) /* TODO: convert code to string */ if (buf) hcl_copy_bcstr (buf, len, "system error"); - return os2err_to_errnum(syserr_code); + return macerr_to_errnum(syserr_code); #else /* in other systems, errno is still the native system error code. * fall thru */ @@ -2127,8 +2173,13 @@ static void vm_muxwait (hcl_t* hcl, const hcl_ntime_t* dur, hcl_vmprim_muxwait_c if (n <= -1) { + #if defined(__OS2__) + hcl_seterrwithsyserr (hcl, 2, sock_errno()); + HCL_DEBUG2 (hcl, "Warning: multiplexer wait failure - %d, %js\n", sock_errno(), hcl_geterrmsg(hcl)); + #else hcl_seterrwithsyserr (hcl, 0, errno); HCL_DEBUG2 (hcl, "Warning: multiplexer wait failure - %d, %js\n", errno, hcl_geterrmsg(hcl)); + #endif } else { @@ -2704,12 +2755,16 @@ static void cb_opt_set (hcl_t* hcl, hcl_option_t id, const void* value) static int open_pipes (hcl_t* hcl, int p[2]) { +#if defined(_WIN32) + u_long flags; +#else int flags; +#endif #if defined(_WIN32) if (_pipe(p, 256, _O_BINARY | _O_NOINHERIT) == -1) #elif defined(__OS2__) - if (_pipe(p, 256, 10) == -1) + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, p) == -1) #elif defined(HAVE_PIPE2) && defined(O_CLOEXEC) && defined(O_NONBLOCK) if (pipe2(p, O_CLOEXEC | O_NONBLOCK) == -1) #else @@ -2720,7 +2775,15 @@ static int open_pipes (hcl_t* hcl, int p[2]) return -1; } -#if defined(HAVE_PIPE2) && defined(O_CLOEXEC) && defined(O_NONBLOCK) +#if defined(_WIN32) + flags = 1; + ioctl (p[0], FIONBIO, &flags); + ioctl (p[1], FIONBIO, &flags); +#elif defined(__OS2__) + flags = 1; /* don't block */ + ioctl (p[0], FIONBIO, &flags, HCL_SIZEOF(flags)); + ioctl (p[1], FIONBIO, &flags, HCL_SIZEOF(flags)); +#elif defined(HAVE_PIPE2) && defined(O_CLOEXEC) && defined(O_NONBLOCK) /* do nothing */ #else #if defined(FD_CLOEXEC) @@ -2745,6 +2808,9 @@ static void close_pipes (hcl_t* hcl, int p[2]) #if defined(_WIN32) _close (p[0]); _close (p[1]); +#elif defined(__OS2__) + soclose (p[0]); + soclose (p[1]); #else close (p[0]); close (p[1]); diff --git a/lib/utl.c b/lib/utl.c index a4dea60..e26e575 100644 --- a/lib/utl.c +++ b/lib/utl.c @@ -83,7 +83,7 @@ int hcl_comp_uchars (const hcl_uch_t* str1, hcl_oow_t len1, const hcl_uch_t* str while (str1 < end1) { c1 = *str1; - if (str2 < end2) + if (str2 < end2) { c2 = *str2; if (c1 > c2) return 1; @@ -105,7 +105,7 @@ int hcl_comp_bchars (const hcl_bch_t* str1, hcl_oow_t len1, const hcl_bch_t* str while (str1 < end1) { c1 = *str1; - if (str2 < end2) + if (str2 < end2) { c2 = *str2; if (c1 > c2) return 1; @@ -155,10 +155,10 @@ int hcl_comp_uchars_ucstr (const hcl_uch_t* str1, hcl_oow_t len, const hcl_uch_t { /* for "abc\0" of length 4 vs "abc", the fourth character * of the first string is equal to the terminating null of - * the second string. the first string is still considered + * the second string. the first string is still considered * bigger */ const hcl_uch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + while (str1 < end && *str2 != '\0') { if (*str1 != *str2) return ((hcl_uchu_t)*str1 > (hcl_uchu_t)*str2)? 1: -1; str1++; str2++; @@ -169,7 +169,7 @@ int hcl_comp_uchars_ucstr (const hcl_uch_t* str1, hcl_oow_t len, const hcl_uch_t int hcl_comp_uchars_bcstr (const hcl_uch_t* str1, hcl_oow_t len, const hcl_bch_t* str2) { const hcl_uch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + while (str1 < end && *str2 != '\0') { if (*str1 != *str2) return ((hcl_uchu_t)*str1 > (hcl_bchu_t)*str2)? 1: -1; str1++; str2++; @@ -180,7 +180,7 @@ int hcl_comp_uchars_bcstr (const hcl_uch_t* str1, hcl_oow_t len, const hcl_bch_t int hcl_comp_bchars_bcstr (const hcl_bch_t* str1, hcl_oow_t len, const hcl_bch_t* str2) { const hcl_bch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + while (str1 < end && *str2 != '\0') { if (*str1 != *str2) return ((hcl_bchu_t)*str1 > (hcl_bchu_t)*str2)? 1: -1; str1++; str2++; @@ -191,7 +191,7 @@ int hcl_comp_bchars_bcstr (const hcl_bch_t* str1, hcl_oow_t len, const hcl_bch_t int hcl_comp_bchars_ucstr (const hcl_bch_t* str1, hcl_oow_t len, const hcl_uch_t* str2) { const hcl_bch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + while (str1 < end && *str2 != '\0') { if (*str1 != *str2) return ((hcl_bchu_t)*str1 > (hcl_uchu_t)*str2)? 1: -1; str1++; str2++; @@ -429,18 +429,18 @@ hcl_oow_t hcl_byte_to_bcstr (hcl_uint8_t byte, hcl_bch_t* buf, hcl_oow_t size, i radix_char = (flagged_radix & HCL_BYTE_TO_BCSTR_LOWERCASE)? 'a': 'A'; if (radix < 2 || radix > 36 || size <= 0) return 0; - do + do { - hcl_uint8_t digit = byte % radix; + hcl_uint8_t digit = byte % radix; if (digit < 10) *p++ = digit + '0'; else *p++ = digit + radix_char - 10; byte /= radix; } while (byte > 0); - if (fill != '\0') + if (fill != '\0') { - while (size - 1 > p - tmp) + while (size - 1 > p - tmp) { *bp++ = fill; size--; @@ -462,7 +462,7 @@ HCL_INLINE int hcl_conv_bchars_to_uchars_with_cmgr (const hcl_bch_t* bcs, hcl_oo if (ucs) { - /* destination buffer is specified. + /* destination buffer is specified. * copy the conversion result to the buffer */ hcl_uch_t* q, * qend; @@ -526,7 +526,7 @@ HCL_INLINE int hcl_conv_bchars_to_uchars_with_cmgr (const hcl_bch_t* bcs, hcl_oo /* no destination buffer is specified. perform conversion * but don't copy the result. the caller can call this function * without a buffer to find the required buffer size, allocate - * a buffer with the size and call this function again with + * a buffer with the size and call this function again with * the buffer. */ hcl_uch_t w; @@ -598,13 +598,13 @@ HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (const hcl_uch_t* ucs, hcl_oo { const hcl_uch_t* p = ucs; const hcl_uch_t* end = ucs + *ucslen; - int ret = 0; + int ret = 0; if (bcs) { hcl_oow_t rem = *bcslen; - while (p < end) + while (p < end) { hcl_oow_t n; @@ -615,12 +615,12 @@ HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (const hcl_uch_t* ucs, hcl_oo } n = cmgr->uctobc (*p, bcs, rem); - if (n == 0) + if (n == 0) { ret = -1; break; /* illegal character */ } - if (n > rem) + if (n > rem) { ret = -2; /* buffer too small */ break; @@ -628,7 +628,7 @@ HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (const hcl_uch_t* ucs, hcl_oo bcs += n; rem -= n; p++; } - *bcslen -= rem; + *bcslen -= rem; } else { @@ -640,7 +640,7 @@ HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (const hcl_uch_t* ucs, hcl_oo hcl_oow_t n; n = cmgr->uctobc (*p, bcsbuf, HCL_COUNTOF(bcsbuf)); - if (n == 0) + if (n == 0) { ret = -1; break; /* illegal character */ @@ -652,7 +652,7 @@ HCL_INLINE int hcl_conv_uchars_to_bchars_with_cmgr (const hcl_uch_t* ucs, hcl_oo p++; mlen += n; } - /* this length excludes the terminating null character. + /* this length excludes the terminating null character. * this function doesn't even null-terminate the result. */ *bcslen = mlen; } @@ -679,14 +679,14 @@ HCL_INLINE int hcl_conv_ucstr_to_bcstr_with_cmgr (const hcl_uch_t* ucs, hcl_oow_ ret = -2; break; } - + n = cmgr->uctobc (*p, bcs, rem); - if (n == 0) + if (n == 0) { ret = -1; break; /* illegal character */ } - if (n > rem) + if (n > rem) { ret = -2; break; /* buffer too small */ @@ -697,13 +697,13 @@ HCL_INLINE int hcl_conv_ucstr_to_bcstr_with_cmgr (const hcl_uch_t* ucs, hcl_oow_ /* update bcslen to the length of the bcs string converted excluding * terminating null */ - *bcslen -= rem; + *bcslen -= rem; /* null-terminate the multibyte sequence if it has sufficient space */ if (rem > 0) *bcs = '\0'; - else + else { - /* if ret is -2 and cs[cslen] == '\0', + /* if ret is -2 and cs[cslen] == '\0', * this means that the bcs buffer was lacking one * slot for the terminating null */ ret = -2; /* buffer too small */ @@ -719,7 +719,7 @@ HCL_INLINE int hcl_conv_ucstr_to_bcstr_with_cmgr (const hcl_uch_t* ucs, hcl_oow_ hcl_oow_t n; n = cmgr->uctobc (*p, bcsbuf, HCL_COUNTOF(bcsbuf)); - if (n == 0) + if (n == 0) { ret = -1; break; /* illegal character */ @@ -731,7 +731,7 @@ HCL_INLINE int hcl_conv_ucstr_to_bcstr_with_cmgr (const hcl_uch_t* ucs, hcl_oow_ p++; mlen += n; } - /* this length holds the number of resulting multi-byte characters + /* this length holds the number of resulting multi-byte characters * excluding the terminating null character */ *bcslen = mlen; } @@ -848,7 +848,7 @@ HCL_INLINE hcl_uch_t* hcl_dupbtoucharswithheadroom (hcl_t* hcl, hcl_oow_t headro hcl_uch_t* ptr; inlen = bcslen; - if (hcl_convbtouchars (hcl, bcs, &inlen, HCL_NULL, &outlen) <= -1) + if (hcl_convbtouchars (hcl, bcs, &inlen, HCL_NULL, &outlen) <= -1) { /* note it's also an error if no full conversion is made in this function */ return HCL_NULL; @@ -862,10 +862,10 @@ HCL_INLINE hcl_uch_t* hcl_dupbtoucharswithheadroom (hcl_t* hcl, hcl_oow_t headro ptr = (hcl_uch_t*)((hcl_oob_t*)ptr + headroom_bytes); hcl_convbtouchars (hcl, bcs, &inlen, ptr, &outlen); - /* hcl_convbtouchars() doesn't null-terminate the target. + /* hcl_convbtouchars() doesn't null-terminate the target. * but in hcl_dupbtouchars(), i allocate space. so i don't mind * null-terminating it with 1 extra character overhead */ - ptr[outlen] = '\0'; + ptr[outlen] = '\0'; if (ucslen) *ucslen = outlen; return ptr; } @@ -881,7 +881,7 @@ HCL_INLINE hcl_bch_t* hcl_duputobcharswithheadroom (hcl_t* hcl, hcl_oow_t headro hcl_bch_t* ptr; inlen = ucslen; - if (hcl_convutobchars(hcl, ucs, &inlen, HCL_NULL, &outlen) <= -1) + if (hcl_convutobchars(hcl, ucs, &inlen, HCL_NULL, &outlen) <= -1) { /* note it's also an error if no full conversion is made in this function */ return HCL_NULL; @@ -912,7 +912,7 @@ HCL_INLINE hcl_uch_t* hcl_dupbtoucstrwithheadroom (hcl_t* hcl, hcl_oow_t headroo hcl_oow_t inlen, outlen; hcl_uch_t* ptr; - if (hcl_convbtoucstr(hcl, bcs, &inlen, HCL_NULL, &outlen) <= -1) + if (hcl_convbtoucstr(hcl, bcs, &inlen, HCL_NULL, &outlen) <= -1) { /* note it's also an error if no full conversion is made in this function */ return HCL_NULL; @@ -937,7 +937,7 @@ HCL_INLINE hcl_bch_t* hcl_duputobcstrwithheadroom (hcl_t* hcl, hcl_oow_t headroo hcl_oow_t inlen, outlen; hcl_bch_t* ptr; - if (hcl_convutobcstr (hcl, ucs, &inlen, HCL_NULL, &outlen) <= -1) + if (hcl_convutobcstr (hcl, ucs, &inlen, HCL_NULL, &outlen) <= -1) { /* note it's also an error if no full conversion is made in this function */ return HCL_NULL; @@ -984,6 +984,32 @@ hcl_bch_t* hcl_dupbchars (hcl_t* hcl, const hcl_bch_t* bcs, hcl_oow_t bcslen) return ptr; } +hcl_uch_t* hcl_dupucstr (hcl_t* hcl, const hcl_uch_t* ucs, hcl_oow_t* ucslen) +{ + hcl_oow_t len; + hcl_uch_t* ptr; + + len = hcl_count_ucstr(ucs); + ptr = hcl_dupuchars(hcl, ucs, len); + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; + + if (ucslen) *ucslen = len; + return ptr; +} + +hcl_bch_t* hcl_dupbcstr (hcl_t* hcl, const hcl_bch_t* bcs, hcl_oow_t* bcslen) +{ + hcl_oow_t len; + hcl_bch_t* ptr; + + len = hcl_count_bcstr(bcs); + ptr = hcl_dupbchars(hcl, bcs, len); + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; + + if (bcslen) *bcslen = len; + return ptr; +} + /* ----------------------------------------------------------------------- */ void hcl_add_ntime (hcl_ntime_t* z, const hcl_ntime_t* x, const hcl_ntime_t* y) @@ -1084,7 +1110,7 @@ void hcl_sub_ntime (hcl_ntime_t* z, const hcl_ntime_t* x, const hcl_ntime_t* y) xs = HCL_TYPE_MIN(hcl_ntime_sec_t); ns = 0; } - } + } else { xs = xs - ys;