diff --git a/qse/include/qse/cmn/chr.h b/qse/include/qse/cmn/chr.h index bceed31d..a1b1fd76 100644 --- a/qse/include/qse/cmn/chr.h +++ b/qse/include/qse/cmn/chr.h @@ -188,17 +188,13 @@ qse_wcint_t qse_towctype ( int qse_getwctypebyname ( const qse_wchar_t* name, - qse_wctype_t* id + qse_wctype_t* id ); int qse_getwctypebyxname ( const qse_wchar_t* name, qse_size_t len, - qse_wctype_t* id -); - -qse_wctype_t qse_getwctype ( - const qse_wchar_t* name + qse_wctype_t* id ); int qse_getmctypebyname ( @@ -209,25 +205,19 @@ int qse_getmctypebyname ( int qse_getmctypebyxname ( const qse_mchar_t* name, qse_size_t len, - qse_mctype_t* id + qse_mctype_t* id ); -qse_mctype_t qse_getmctype ( - const qse_mchar_t* name -); - -#ifdef QSE_CHAR_IS_MCHAR -# define qse_isctype(c,type) qse_ismctype(c,type) -# define qse_toctype(c,type) qse_ismctype(c,type) -# define qse_getctypebyname(name,id) qse_getmctypebyname(name,id) -# define qse_getctypebyxname(name,len,id) qse_getmctypebyxname(name,len,id) -# define qse_getctype(name) qse_getmctype(name) +#if defined(QSE_CHAR_IS_MCHAR) +# define qse_isctype(c,type) qse_ismctype(c,type) +# define qse_toctype(c,type) qse_ismctype(c,type) +# define qse_strtoctype(name,id) qse_mbstoctype(name,id) +# define qse_strntoctype(name,len,id) qse_mbsntoctype(name,len,id) #else -# define qse_isctype(c,type) qse_iswctype(c,type) -# define qse_toctype(c,type) qse_towctype(c,type) -# define qse_getctypebyname(name,id) qse_getwctypebyname(name,id) -# define qse_getctypebyxname(name,len,id) qse_getwctypebyxname(name,len,id) -# define qse_getctype(name) qse_getwctype(name) +# define qse_isctype(c,type) qse_iswctype(c,type) +# define qse_toctype(c,type) qse_towctype(c,type) +# define qse_strtoctype(name,id) qse_wcstoctype(name,id) +# define qse_strntoctype(name,len,id) qse_wcsntoctype(name,len,id) #endif #ifdef __cplusplus diff --git a/qse/include/qse/cmn/ipad.h b/qse/include/qse/cmn/ipad.h index 28938050..58b56db8 100644 --- a/qse/include/qse/cmn/ipad.h +++ b/qse/include/qse/cmn/ipad.h @@ -102,6 +102,50 @@ qse_size_t qse_ipad4towcs ( # define qse_ipad4tostr(ipad,ptr,len) qse_ipad4towcs(ipad,ptr,len) #endif +int qse_mbstoipad6 ( + const qse_mchar_t* mbs, + qse_ipad6_t* ipad +); + +int qse_mbsntoipad6 ( + const qse_mchar_t* mbs, + qse_size_t len, + qse_ipad6_t* ipad +); + +int qse_wcstoipad6 ( + const qse_wchar_t* wcs, + qse_ipad6_t* ipad +); + +int qse_wcsntoipad6 ( + const qse_wchar_t* wcs, + qse_size_t len, + qse_ipad6_t* ipad +); + +qse_size_t qse_ipad6tombs ( + const qse_ipad6_t* ipad, + qse_mchar_t* mbs, + qse_size_t len +); + +qse_size_t qse_ipad6towcs ( + const qse_ipad6_t* ipad, + qse_wchar_t* wcs, + qse_size_t len +); + +#if defined(QSE_CHAR_IS_MCHAR) +# define qse_strtoipad6(ptr,ipad) qse_mbstoipad6(ptr,ipad) +# define qse_strntoipad6(ptr,len,ipad) qse_mbsntoipad6(ptr,len,ipad) +# define qse_ipad6tostr(ipad,ptr,len) qse_ipad6tombs(ipad,ptr,len) +#else +# define qse_strtoipad6(ptr,ipad) qse_wcstoipad6(ptr,ipad) +# define qse_strntoipad6(ptr,len,ipad) qse_wcsntoipad6(ptr,len,ipad) +# define qse_ipad6tostr(ipad,ptr,len) qse_ipad6towcs(ipad,ptr,len) +#endif + #ifdef __cplusplus } #endif diff --git a/qse/include/qse/cmn/nwad.h b/qse/include/qse/cmn/nwad.h index 2f64336c..cf4ec12c 100644 --- a/qse/include/qse/cmn/nwad.h +++ b/qse/include/qse/cmn/nwad.h @@ -25,28 +25,83 @@ #include #include +typedef struct qse_nwad_t qse_nwad_t; + struct qse_nwad_t { enum { - QSE_NWAD_IP4, - QSE_NWAD_IP6 + QSE_NWAD_IN4, + QSE_NWAD_IN6 } type; union { struct { - qse_ipad4_t addr; qse_uint16_t port; - } ip4; + qse_ipad4_t addr; + } in4; struct { - qse_ipad6_t addr; qse_uint16_t port; - } ip6; + qse_ipad6_t addr; + qse_uint32_t scope; + } in6; } u; }; +#ifdef __cplusplus +extern "C" { +#endif + +int qse_mbstonwad ( + const qse_mchar_t* mbs, + qse_nwad_t* nwad +); + +int qse_mbsntonwad ( + const qse_mchar_t* mbs, + qse_size_t len, + qse_nwad_t* nwad +); + +int qse_wcstonwad ( + const qse_wchar_t* wcs, + qse_nwad_t* nwad +); + +int qse_wcsntonwad ( + const qse_wchar_t* wcs, + qse_size_t len, + qse_nwad_t* nwad +); + +qse_size_t qse_nwadtombs ( + const qse_nwad_t* nwad, + qse_mchar_t* mbs, + qse_size_t len +); + +qse_size_t qse_nwadtowcs ( + const qse_nwad_t* nwad, + qse_wchar_t* wcs, + qse_size_t len +); + +#if defined(QSE_CHAR_IS_MCHAR) +# define qse_strtonwad(ptr,nwad) qse_mbstonwad(ptr,nwad) +# define qse_strntonwad(ptr,len,nwad) qse_mbsntonwad(ptr,len,nwad) +# define qse_nwadtostr(nwad,ptr,len) qse_nwadtombs(nwad,ptr,len) +#else +# define qse_strtonwad(ptr,nwad) qse_wcstonwad(ptr,nwad) +# define qse_strntonwad(ptr,len,nwad) qse_wcsntonwad(ptr,len,nwad) +# define qse_nwadtostr(nwad,ptr,len) qse_nwadtowcs(nwad,ptr,len) +#endif + +#ifdef __cplusplus +} +#endif + #endif diff --git a/qse/lib/cmn/chr.c b/qse/lib/cmn/chr.c index 8cfe232c..1c6c86af 100644 --- a/qse/lib/cmn/chr.c +++ b/qse/lib/cmn/chr.c @@ -247,7 +247,7 @@ static struct wtab_t { QSE_WT("xdigit"), QSE_WCTYPE_XDIGIT } }; -int qse_getwctypebyname (const qse_wchar_t* name, qse_wctype_t* id) +int qse_wcstoctype (const qse_wchar_t* name, qse_wctype_t* id) { int left = 0, right = QSE_COUNTOF(wtab) - 1, mid; while (left <= right) @@ -278,7 +278,7 @@ int qse_getwctypebyname (const qse_wchar_t* name, qse_wctype_t* id) return -1; } -int qse_getwctypebyxname (const qse_wchar_t* name, qse_size_t len, qse_wctype_t* id) +int qse_wcsntoctype (const qse_wchar_t* name, qse_size_t len, qse_wctype_t* id) { int left = 0, right = QSE_COUNTOF(wtab) - 1, mid; while (left <= right) @@ -309,12 +309,6 @@ int qse_getwctypebyxname (const qse_wchar_t* name, qse_size_t len, qse_wctype_t* return -1; } -qse_wctype_t qse_getwctype (const qse_wchar_t* name) -{ - qse_wctype_t id; - return (qse_getwctypebyname(name,&id) <= -1)? ((qse_wctype_t)0): id; -} - static struct mtab_t { const qse_mchar_t* name; @@ -335,7 +329,7 @@ static struct mtab_t { QSE_MT("xdigit"), QSE_MCTYPE_XDIGIT } }; -int qse_getmctypebyname (const qse_mchar_t* name, qse_mctype_t* id) +int qse_mbstoctype (const qse_mchar_t* name, qse_mctype_t* id) { int left = 0, right = QSE_COUNTOF(mtab) - 1, mid; while (left <= right) @@ -366,7 +360,7 @@ int qse_getmctypebyname (const qse_mchar_t* name, qse_mctype_t* id) return -1; } -int qse_getmctypebyxname (const qse_mchar_t* name, qse_size_t len, qse_mctype_t* id) +int qse_mbsntoctype (const qse_mchar_t* name, qse_size_t len, qse_mctype_t* id) { int left = 0, right = QSE_COUNTOF(mtab) - 1, mid; while (left <= right) @@ -397,9 +391,3 @@ int qse_getmctypebyxname (const qse_mchar_t* name, qse_size_t len, qse_mctype_t* return -1; } -qse_mctype_t qse_getmctype (const qse_mchar_t* name) -{ - qse_mctype_t id; - return (qse_getmctypebyname(name,&id) <= -1)? ((qse_mctype_t)0): id; -} - diff --git a/qse/lib/cmn/ipad.c b/qse/lib/cmn/ipad.c index c9d33304..7d3ea237 100644 --- a/qse/lib/cmn/ipad.c +++ b/qse/lib/cmn/ipad.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "mem.h" #if 0 @@ -227,148 +228,20 @@ qse_size_t qse_ipad4towcs ( return p - buf; } -#if 0 -int qse_strtoipad6 (const qse_char_t* src, qse_ipad6_t* ipad) +int qse_mbstoipad6 (const qse_mchar_t* src, qse_ipad6_t* ipad) { -#if 0 - static const qse_char_t xdigits_l[] = QSE_T("0123456789abcdef"), - xdigits_u[] = QSE_T("0123456789ABCDEF"); - const qse_char_t* xdigits; -#endif - - qse_ipad6_t tmp; - qse_byte_t* tp, * endp, * colonp; - const qse_char_t* curtok; - qse_char_t ch; - int saw_xdigit; - unsigned int val; - - QSE_MEMSET (&tmp, 0, QSE_SIZEOF(tmp)); - tp = &tmp.value[0]; - endp = &tmp.value[QSE_COUNTOF(tmp.value)]; - colonp = QSE_NULL; - - /* Leading :: requires some special handling. */ - if (*src == QSE_T(':')) - { - if (*++src != QSE_T(':')) return -1; - } - - curtok = src; - saw_xdigit = 0; - val = 0; - while ((ch = *src++) != QSE_T('\0')) - { - #if 0 - const char *pch; - if ((pch = qse_strchr((xdigits = xdigits_l), ch)) == QSE_NULL) - pch = qse_strchr((xdigits = xdigits_u), ch); - if (pch != QSE_NULL) - { - val <<= 4; - val |= (pch - xdigits); - if (val > 0xffff) return -1; - saw_xdigit = 1; - continue; - } - #endif - int v1; - if (ch >= QSE_T('0') && ch <= QSE_T('9')) - v1 = ch - QSE_T('0'); - else if (ch >= QSE_T('A') && ch <= QSE_T('F')) - v1 = ch - QSE_T('A') + 10; - else if (ch >= QSE_T('a') && ch <= QSE_T('f')) - v1 = ch - QSE_T('a') + 10; - else v1 = -1; - if (v1 >= 0) - { - val <<= 4; - val |= v1; - if (val > 0xffff) return -1; - saw_xdigit = 1; - continue; - } - - if (ch == QSE_T(':')) - { - curtok = src; - if (!saw_xdigit) - { - if (colonp) return -1; - colonp = tp; - continue; - } - else if (*src == QSE_T('\0')) - { - /* a colon can't be the last character */ - return -1; - } - - if (tp + QSE_SIZEOF(qse_uint16_t) > endp) return -1; - *tp++ = (qse_byte_t) (val >> 8) & 0xff; - *tp++ = (qse_byte_t) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - #if 0 - if (ch == QSE_T('.') && ((tp + NS_INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) - { - tp += NS_INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - #endif - if (ch == QSE_T('.') && ((tp + QSE_SIZEOF(qse_ipad4_t)) <= endp) && - qse_strtoipad4(curtok, (qse_ipad4_t*)tp) == 0) - { - tp += QSE_SIZEOF(qse_ipad4_t); - saw_xdigit = 0; - break; - } - - return -1; - } - - if (saw_xdigit) - { - if (tp + QSE_SIZEOF(qse_uint16_t) > endp) return -1; - *tp++ = (qse_byte_t) (val >> 8) & 0xff; - *tp++ = (qse_byte_t) val & 0xff; - } - if (colonp != QSE_NULL) - { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - qse_size_t n = tp - colonp; - qse_size_t i; - - for (i = 1; i <= n; i++) - { - endp[-i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - - if (tp != endp) return -1; - - *ipad = tmp; - return 0; + return qse_mbsntoipad6 (src, qse_mbslen(src), ipad); } -int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad) +int qse_mbsntoipad6 (const qse_mchar_t* src, qse_size_t len, qse_ipad6_t* ipad) { qse_ipad6_t tmp; - qse_byte_t* tp, * endp, * colonp; - const qse_char_t* curtok; - qse_char_t ch; + qse_uint8_t* tp, * endp, * colonp; + const qse_mchar_t* curtok; + qse_mchar_t ch; int saw_xdigit; unsigned int val; - const qse_char_t* src_end; + const qse_mchar_t* src_end; src_end = src + len; @@ -378,10 +251,10 @@ int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad) colonp = QSE_NULL; /* Leading :: requires some special handling. */ - if (src < src_end && *src == QSE_T(':')) + if (src < src_end && *src == QSE_MT(':')) { src++; - if (src >= src_end || *src != QSE_T(':')) return -1; + if (src >= src_end || *src != QSE_MT(':')) return -1; } curtok = src; @@ -394,12 +267,12 @@ int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad) ch = *src++; - if (ch >= QSE_T('0') && ch <= QSE_T('9')) - v1 = ch - QSE_T('0'); - else if (ch >= QSE_T('A') && ch <= QSE_T('F')) - v1 = ch - QSE_T('A') + 10; - else if (ch >= QSE_T('a') && ch <= QSE_T('f')) - v1 = ch - QSE_T('a') + 10; + if (ch >= QSE_MT('0') && ch <= QSE_MT('9')) + v1 = ch - QSE_MT('0'); + else if (ch >= QSE_MT('A') && ch <= QSE_MT('F')) + v1 = ch - QSE_MT('A') + 10; + else if (ch >= QSE_MT('a') && ch <= QSE_MT('f')) + v1 = ch - QSE_MT('a') + 10; else v1 = -1; if (v1 >= 0) { @@ -410,7 +283,7 @@ int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad) continue; } - if (ch == QSE_T(':')) + if (ch == QSE_MT(':')) { curtok = src; if (!saw_xdigit) @@ -425,15 +298,15 @@ int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad) return -1; } - *tp++ = (qse_byte_t) (val >> 8) & 0xff; - *tp++ = (qse_byte_t) val & 0xff; + *tp++ = (qse_uint8_t)(val >> 8) & 0xff; + *tp++ = (qse_uint8_t)val & 0xff; saw_xdigit = 0; val = 0; continue; } - if (ch == QSE_T('.') && ((tp + QSE_SIZEOF(qse_ipad4_t)) <= endp) && - qse_strxtoipad4(curtok, src_end - curtok, (qse_ipad4_t*)tp) == 0) + if (ch == QSE_MT('.') && ((tp + QSE_SIZEOF(qse_ipad4_t)) <= endp) && + qse_mbsntoipad4(curtok, src_end - curtok, (qse_ipad4_t*)tp) == 0) { tp += QSE_SIZEOF(qse_ipad4_t); saw_xdigit = 0; @@ -446,8 +319,8 @@ int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad) if (saw_xdigit) { if (tp + QSE_SIZEOF(qse_uint16_t) > endp) return -1; - *tp++ = (qse_byte_t) (val >> 8) & 0xff; - *tp++ = (qse_byte_t) val & 0xff; + *tp++ = (qse_uint8_t)(val >> 8) & 0xff; + *tp++ = (qse_uint8_t)val & 0xff; } if (colonp != QSE_NULL) { @@ -472,8 +345,126 @@ int qse_strxtoipad6 (const qse_char_t* src, qse_size_t len, qse_ipad6_t* ipad) return 0; } -qse_size_t qse_ipad6tostrx ( - const qse_ipad6_t* ipad, qse_char_t* buf, qse_size_t size) + +int qse_wcstoipad6 (const qse_wchar_t* src, qse_ipad6_t* ipad) +{ + return qse_wcsntoipad6 (src, qse_wcslen(src), ipad); +} + +int qse_wcsntoipad6 (const qse_wchar_t* src, qse_size_t len, qse_ipad6_t* ipad) +{ + qse_ipad6_t tmp; + qse_uint8_t* tp, * endp, * colonp; + const qse_wchar_t* curtok; + qse_wchar_t ch; + int saw_xdigit; + unsigned int val; + const qse_wchar_t* src_end; + + src_end = src + len; + + QSE_MEMSET (&tmp, 0, QSE_SIZEOF(tmp)); + tp = &tmp.value[0]; + endp = &tmp.value[QSE_COUNTOF(tmp.value)]; + colonp = QSE_NULL; + + /* Leading :: requires some special handling. */ + if (src < src_end && *src == QSE_WT(':')) + { + src++; + if (src >= src_end || *src != QSE_WT(':')) return -1; + } + + curtok = src; + saw_xdigit = 0; + val = 0; + + while (src < src_end) + { + int v1; + + ch = *src++; + + if (ch >= QSE_WT('0') && ch <= QSE_WT('9')) + v1 = ch - QSE_WT('0'); + else if (ch >= QSE_WT('A') && ch <= QSE_WT('F')) + v1 = ch - QSE_WT('A') + 10; + else if (ch >= QSE_WT('a') && ch <= QSE_WT('f')) + v1 = ch - QSE_WT('a') + 10; + else v1 = -1; + if (v1 >= 0) + { + val <<= 4; + val |= v1; + if (val > 0xffff) return -1; + saw_xdigit = 1; + continue; + } + + if (ch == QSE_WT(':')) + { + curtok = src; + if (!saw_xdigit) + { + if (colonp) return -1; + colonp = tp; + continue; + } + else if (src >= src_end) + { + /* a colon can't be the last character */ + return -1; + } + + *tp++ = (qse_uint8_t)(val >> 8) & 0xff; + *tp++ = (qse_uint8_t)val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + + if (ch == QSE_WT('.') && ((tp + QSE_SIZEOF(qse_ipad4_t)) <= endp) && + qse_wcsntoipad4(curtok, src_end - curtok, (qse_ipad4_t*)tp) == 0) + { + tp += QSE_SIZEOF(qse_ipad4_t); + saw_xdigit = 0; + break; + } + + return -1; + } + + if (saw_xdigit) + { + if (tp + QSE_SIZEOF(qse_uint16_t) > endp) return -1; + *tp++ = (qse_uint8_t)(val >> 8) & 0xff; + *tp++ = (qse_uint8_t)val & 0xff; + } + if (colonp != QSE_NULL) + { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + qse_size_t n = tp - colonp; + qse_size_t i; + + for (i = 1; i <= n; i++) + { + endp[-i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + + if (tp != endp) return -1; + + *ipad = tmp; + return 0; +} + +qse_size_t qse_ipad6tombs ( + const qse_ipad6_t* ipad, qse_mchar_t* buf, qse_size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough @@ -485,7 +476,7 @@ qse_size_t qse_ipad6tostrx ( #define IP6ADDR_NWORDS (QSE_SIZEOF(ipad->value) / QSE_SIZEOF(qse_uint16_t)) - qse_char_t tmp[QSE_COUNTOF(QSE_T("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))], *tp; + qse_mchar_t tmp[QSE_COUNTOF(QSE_MT("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))], *tp; struct { int base, len; } best, cur; qse_uint16_t words[IP6ADDR_NWORDS]; int i; @@ -542,12 +533,12 @@ qse_size_t qse_ipad6tostrx ( if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { - if (i == best.base) *tp++ = QSE_T(':'); + if (i == best.base) *tp++ = QSE_MT(':'); continue; } /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) *tp++ = QSE_T(':'); + if (i != 0) *tp++ = QSE_MT(':'); /* Is this address an encapsulated IPv4? ipv4-compatible or ipv4-mapped */ if (i == 6 && best.base == 0 && @@ -555,21 +546,124 @@ qse_size_t qse_ipad6tostrx ( { qse_ipad4_t ipad4; QSE_MEMCPY (&ipad4.value, ipad->value+12, QSE_SIZEOF(ipad4.value)); - tp += qse_ipad4tostrx (&ipad4, tp, QSE_SIZEOF(tmp) - (tp - tmp)); + tp += qse_ipad4tombs (&ipad4, tp, QSE_COUNTOF(tmp) - (tp - tmp)); break; } - tp += qse_uint16tostr_lower (words[i], tp, QSE_SIZEOF(tmp) - (tp - tmp), 16, QSE_T('\0')); + tp += qse_fmtuintmaxtombs ( + tp, QSE_COUNTOF(tmp) - (tp - tmp), + words[i], 16, 0, QSE_WT('\0'), QSE_NULL); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && - (best.base + best.len) == IP6ADDR_NWORDS) *tp++ = QSE_T(':'); - *tp++ = QSE_T('\0'); + (best.base + best.len) == IP6ADDR_NWORDS) *tp++ = QSE_MT(':'); + *tp++ = QSE_MT('\0'); - return qse_strxcpy (buf, size, tmp); + return qse_mbsxcpy (buf, size, tmp); + +#undef IP6ADDR_NWORDS +} + +qse_size_t qse_ipad6towcs ( + const qse_ipad6_t* ipad, qse_wchar_t* buf, qse_size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + +#define IP6ADDR_NWORDS (QSE_SIZEOF(ipad->value) / QSE_SIZEOF(qse_uint16_t)) + + qse_wchar_t tmp[QSE_COUNTOF(QSE_MT("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))], *tp; + struct { int base, len; } best, cur; + qse_uint16_t words[IP6ADDR_NWORDS]; + int i; + + if (size <= 0) return 0; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + QSE_MEMSET (words, 0, QSE_SIZEOF(words)); + for (i = 0; i < QSE_SIZEOF(ipad->value); i++) + words[i / 2] |= (ipad->value[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + + for (i = 0; i < IP6ADDR_NWORDS; i++) + { + if (words[i] == 0) + { + if (cur.base == -1) + { + cur.base = i; + cur.len = 1; + } + else + { + cur.len++; + } + } + else + { + if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) best = cur; + } + if (best.base != -1 && best.len < 2) best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < IP6ADDR_NWORDS; i++) + { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) + { + if (i == best.base) *tp++ = QSE_MT(':'); + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) *tp++ = QSE_MT(':'); + + /* Is this address an encapsulated IPv4? ipv4-compatible or ipv4-mapped */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) + { + qse_ipad4_t ipad4; + QSE_MEMCPY (&ipad4.value, ipad->value+12, QSE_SIZEOF(ipad4.value)); + tp += qse_ipad4towcs (&ipad4, tp, QSE_COUNTOF(tmp) - (tp - tmp)); + break; + } + + tp += qse_fmtuintmaxtowcs ( + tp, QSE_COUNTOF(tmp) - (tp - tmp), + words[i], 16, 0, QSE_WT('\0'), QSE_NULL); + } + + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && + (best.base + best.len) == IP6ADDR_NWORDS) *tp++ = QSE_MT(':'); + *tp++ = QSE_MT('\0'); + + return qse_wcsxcpy (buf, size, tmp); #undef IP6ADDR_NWORDS } -#endif diff --git a/qse/lib/cmn/nwad.c b/qse/lib/cmn/nwad.c index 55684eef..c8517772 100644 --- a/qse/lib/cmn/nwad.c +++ b/qse/lib/cmn/nwad.c @@ -18,20 +18,519 @@ License along with QSE. If not, see . */ -/* Copyright (c) 1996-1999 by Internet Software Consortium - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - #include +#include +#include +#include +#include "mem.h" + +#if 0 +int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad) +{ + const qse_mchar_t* p; + qse_mcstr_t tmp; + qse_nwad_t tmpad; + + QSE_MEMSET (&tmpad, 0, QSE_SIZEOF(tmpad)); + + p = str; + if (*p == QSE_MT('[')) + { + /* IPv6 address */ + tmp.ptr = ++p; /* skip [ and remember the position */ + while (*p != QSE_MT('\0') && *p != QSE_MT('%') && *p != QSE_MT(']')) p++; + + if (*p == QSE_MT('\0')) return -1; + + tmp.len = p - tmp.ptr; + if (*p == QSE_MT('%')) + { + /* handle scope id */ + qse_uint32_t x; + + p++; /* skip % */ + + if (!(*p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1; + tmpad.u.in6.scope = 0; + do + { + x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0')); + if (x < tmpad.u.in6.scope) return -1; /* overflow */ + tmpad.u.in6.scope = x; + p++; + } + while (*p >= QSE_MT('0') && *p <= QSE_MT('9')); + + if (*p != QSE_MT(']')) return -1; + } + p++; /* skip ] */ + + if (qse_mbsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) return -1; + tmpad.type = QSE_NWAD_IN6; + } + else + { + /* host name or IPv4 address */ + tmp.ptr = p; + while (*p != QSE_MT('\0') && *p != QSE_MT(':')) p++; + tmp.len = p - tmp.ptr; + + if (qse_mbsntoipad4 (tmp.ptr, tmp.len, &tmpad.u.in4.addr) <= -1) + { + /* check if it is an IPv6 address not enclosed in []. + * the port number can't be specified in this format. */ + + while (*p != QSE_MT('\0') && *p != QSE_MT('%')) p++; + tmp.len = p - tmp.ptr; + + if (qse_mbsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) + return -1; + + if (*p == QSE_MT('%')) + { + /* handle scope id */ + qse_uint32_t x; + + p++; /* skip % */ + if (!(*p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1; + tmpad.u.in6.scope = 0; + do + { + x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0')); + if (x < tmpad.u.in6.scope) return -1; /* overflow */ + tmpad.u.in6.scope = x; + p++; + } + while (*p >= QSE_MT('0') && *p <= QSE_MT('9')); + } + + if (*p != QSE_MT('\0')) return -1; + + tmpad.type = QSE_NWAD_IN6; + goto done; + } + + tmpad.type = QSE_NWAD_IN4; + } + + if (*p == QSE_MT(':')) + { + /* port number */ + qse_uint32_t port = 0; + + p++; /* skip : */ + + for (tmp.ptr = p; *p >= QSE_MT('0') && *p <= QSE_MT('9'); p++) + port = port * 10 + (*p - QSE_MT('0')); + + tmp.len = p - tmp.ptr; + if (tmp.len <= 0 || tmp.len >= 6 || + port > QSE_TYPE_MAX(qse_uint16_t)) return -1; + + if (tmpad.type == QSE_NWAD_IN4) + tmpad.u.in4.port = qse_hton16 (port); + else + tmpad.u.in6.port = qse_hton16 (port); + } + +done: + if (nwad) *nwad = tmpad; + return 0; +} +#endif + +int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad) +{ + return qse_mbsntonwad (str, qse_mbslen(str), nwad); +} + +int qse_mbsntonwad (const qse_mchar_t* str, qse_size_t len, qse_nwad_t* nwad) +{ + const qse_mchar_t* p; + const qse_mchar_t* end; + qse_mcstr_t tmp; + qse_nwad_t tmpad; + + QSE_MEMSET (&tmpad, 0, QSE_SIZEOF(tmpad)); + + p = str; + end = str + len; + + if (p >= end) return -1; + + if (*p == QSE_MT('[')) + { + /* IPv6 address */ + tmp.ptr = ++p; /* skip [ and remember the position */ + while (p < end && *p != QSE_MT('%') && *p != QSE_MT(']')) p++; + + if (p >= end) return -1; + + tmp.len = p - tmp.ptr; + if (*p == QSE_MT('%')) + { + /* handle scope id */ + qse_uint32_t x; + + p++; /* skip % */ + + if (!(p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1; + tmpad.u.in6.scope = 0; + do + { + x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0')); + if (x < tmpad.u.in6.scope) return -1; /* overflow */ + tmpad.u.in6.scope = x; + p++; + } + while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9')); + + if (p >= end || *p != QSE_MT(']')) return -1; + } + p++; /* skip ] */ + + if (qse_mbsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) return -1; + tmpad.type = QSE_NWAD_IN6; + } + else + { + /* host name or IPv4 address */ + tmp.ptr = p; + while (p < end && *p != QSE_MT(':')) p++; + tmp.len = p - tmp.ptr; + + if (qse_mbsntoipad4 (tmp.ptr, tmp.len, &tmpad.u.in4.addr) <= -1) + { + if (p >= end || *p != QSE_MT(':')) return -1; + + /* check if it is an IPv6 address not enclosed in []. + * the port number can't be specified in this format. */ + + while (p < end && *p != QSE_MT('%')) p++; + tmp.len = p - tmp.ptr; + + if (qse_mbsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) + return -1; + + if (p < end && *p == QSE_MT('%')) + { + /* handle scope id */ + qse_uint32_t x; + + p++; /* skip % */ + if (!(p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1; + tmpad.u.in6.scope = 0; + do + { + x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0')); + if (x < tmpad.u.in6.scope) return -1; /* overflow */ + tmpad.u.in6.scope = x; + p++; + } + while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9')); + } + + if (p < end) return -1; + + tmpad.type = QSE_NWAD_IN6; + goto done; + } + + tmpad.type = QSE_NWAD_IN4; + } + + if (p < end && *p == QSE_MT(':')) + { + /* port number */ + qse_uint32_t port = 0; + + p++; /* skip : */ + + tmp.ptr = p; + while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9')) + { + port = port * 10 + (*p - QSE_MT('0')); + p++; + } + + tmp.len = p - tmp.ptr; + if (tmp.len <= 0 || tmp.len >= 6 || + port > QSE_TYPE_MAX(qse_uint16_t)) return -1; + + if (tmpad.type == QSE_NWAD_IN4) + tmpad.u.in4.port = qse_hton16 (port); + else + tmpad.u.in6.port = qse_hton16 (port); + } + +done: + if (nwad) *nwad = tmpad; + return 0; +} + +int qse_wcstonwad (const qse_wchar_t* str, qse_nwad_t* nwad) +{ + return qse_wcsntonwad (str, qse_wcslen(str), nwad); +} + +int qse_wcsntonwad (const qse_wchar_t* str, qse_size_t len, qse_nwad_t* nwad) +{ + const qse_wchar_t* p; + const qse_wchar_t* end; + qse_wcstr_t tmp; + qse_nwad_t tmpad; + + QSE_MEMSET (&tmpad, 0, QSE_SIZEOF(tmpad)); + + p = str; + end = str + len; + + if (p >= end) return -1; + + if (*p == QSE_WT('[')) + { + /* IPv6 address */ + tmp.ptr = ++p; /* skip [ and remember the position */ + while (p < end && *p != QSE_WT('%') && *p != QSE_WT(']')) p++; + + if (p >= end) return -1; + + tmp.len = p - tmp.ptr; + if (*p == QSE_WT('%')) + { + /* handle scope id */ + qse_uint32_t x; + + p++; /* skip % */ + + if (!(p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'))) return -1; + tmpad.u.in6.scope = 0; + do + { + x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0')); + if (x < tmpad.u.in6.scope) return -1; /* overflow */ + tmpad.u.in6.scope = x; + p++; + } + while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9')); + + if (p >= end || *p != QSE_WT(']')) return -1; + } + p++; /* skip ] */ + + if (qse_wcsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) return -1; + tmpad.type = QSE_NWAD_IN6; + } + else + { + /* host name or IPv4 address */ + tmp.ptr = p; + while (p < end && *p != QSE_WT(':')) p++; + tmp.len = p - tmp.ptr; + + if (qse_wcsntoipad4 (tmp.ptr, tmp.len, &tmpad.u.in4.addr) <= -1) + { + if (p >= end || *p != QSE_WT(':')) return -1; + + /* check if it is an IPv6 address not enclosed in []. + * the port number can't be specified in this format. */ + + while (p < end && *p != QSE_WT('%')) p++; + tmp.len = p - tmp.ptr; + + if (qse_wcsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) + return -1; + + if (p < end && *p == QSE_WT('%')) + { + /* handle scope id */ + qse_uint32_t x; + + p++; /* skip % */ + if (!(p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'))) return -1; + tmpad.u.in6.scope = 0; + do + { + x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0')); + if (x < tmpad.u.in6.scope) return -1; /* overflow */ + tmpad.u.in6.scope = x; + p++; + } + while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9')); + } + + if (p < end) return -1; + + tmpad.type = QSE_NWAD_IN6; + goto done; + } + + tmpad.type = QSE_NWAD_IN4; + } + + if (p < end && *p == QSE_WT(':')) + { + /* port number */ + qse_uint32_t port = 0; + + p++; /* skip : */ + + tmp.ptr = p; + while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9')) + { + port = port * 10 + (*p - QSE_WT('0')); + p++; + } + + tmp.len = p - tmp.ptr; + if (tmp.len <= 0 || tmp.len >= 6 || + port > QSE_TYPE_MAX(qse_uint16_t)) return -1; + + if (tmpad.type == QSE_NWAD_IN4) + tmpad.u.in4.port = qse_hton16 (port); + else + tmpad.u.in6.port = qse_hton16 (port); + } + +done: + if (nwad) *nwad = tmpad; + return 0; +} + +qse_size_t qse_nwadtombs (const qse_nwad_t* nwad, qse_mchar_t* buf, qse_size_t len) +{ + qse_size_t xlen = 0; + + switch (nwad->type) + { + case QSE_NWAD_IN4: + if (xlen + 1 < len) + { + xlen = qse_ipad4tombs (&nwad->u.in4.addr, buf, len); + if (xlen + 1 < len && nwad->u.in4.port != 0) + { + buf[xlen++] = QSE_MT(':'); + if (xlen + 1 < len) + { + xlen += qse_fmtuintmaxtombs ( + &buf[xlen], len - xlen, + qse_ntoh16(nwad->u.in4.port), + 10, 0, QSE_WT('\0'), QSE_NULL); + } + } + } + break; + + case QSE_NWAD_IN6: + if (xlen + 1 < len) + { + if (nwad->u.in6.port != 0) buf[xlen++] = QSE_MT('['); + + if (xlen + 1 < len) + { + xlen += qse_ipad6tombs (&nwad->u.in6.addr, buf, len); + if (xlen + 1 < len && nwad->u.in6.scope != 0) + { + buf[xlen++] = QSE_MT('%'); + if (xlen + 1 < len) + { + xlen += qse_fmtuintmaxtombs ( + &buf[xlen], len - xlen, + nwad->u.in6.scope, 10, 0, QSE_WT('\0'), QSE_NULL); + } + } + + if (xlen + 1 < len && nwad->u.in6.port != 0) + { + buf[xlen++] = QSE_MT(']'); + if (xlen + 1 < len) + { + buf[xlen++] = QSE_MT(':'); + if (xlen + 1 < len) + { + xlen += qse_fmtuintmaxtombs ( + &buf[xlen], len - xlen, + qse_ntoh16(nwad->u.in6.port), + 10, 0, QSE_WT('\0'), QSE_NULL); + } + } + } + } + + } + break; + + } + + if (xlen + 1 < len) buf[xlen] = QSE_MT('\0'); + return xlen; +} + +qse_size_t qse_nwadtowcs (const qse_nwad_t* nwad, qse_wchar_t* buf, qse_size_t len) +{ + qse_size_t xlen = 0; + + switch (nwad->type) + { + case QSE_NWAD_IN4: + if (xlen + 1 < len) + { + xlen = qse_ipad4towcs (&nwad->u.in4.addr, buf, len); + if (xlen + 1 < len && nwad->u.in4.port != 0) + { + buf[xlen++] = QSE_WT(':'); + if (xlen + 1 < len) + { + xlen += qse_fmtuintmaxtowcs ( + &buf[xlen], len - xlen, + qse_ntoh16(nwad->u.in4.port), + 10, 0, QSE_WT('\0'), QSE_NULL); + } + } + } + break; + + case QSE_NWAD_IN6: + if (xlen + 1 < len) + { + if (nwad->u.in6.port != 0) buf[xlen++] = QSE_WT('['); + + if (xlen + 1 < len) + { + xlen += qse_ipad6towcs (&nwad->u.in6.addr, &buf[xlen], len - xlen); + if (xlen + 1 < len && nwad->u.in6.scope != 0) + { + buf[xlen++] = QSE_WT('%'); + if (xlen + 1 < len) + { + xlen += qse_fmtuintmaxtowcs ( + &buf[xlen], len - xlen, + nwad->u.in6.scope, 10, 0, QSE_WT('\0'), QSE_NULL); + } + } + + if (xlen + 1 < len && nwad->u.in6.port != 0) + { + buf[xlen++] = QSE_WT(']'); + if (xlen + 1 < len) + { + buf[xlen++] = QSE_WT(':'); + if (xlen + 1 < len) + { + xlen += qse_fmtuintmaxtowcs ( + &buf[xlen], len - xlen, + qse_ntoh16(nwad->u.in6.port), + 10, 0, QSE_WT('\0'), QSE_NULL); + } + } + } + } + + } + break; + + } + + if (xlen < len) buf[xlen] = QSE_WT('\0'); + return xlen; +} diff --git a/qse/lib/cmn/tre-parse.c b/qse/lib/cmn/tre-parse.c index 623b8676..e30f2fab 100644 --- a/qse/lib/cmn/tre-parse.c +++ b/qse/lib/cmn/tre-parse.c @@ -295,7 +295,7 @@ tre_parse_bracket_items(tre_parse_ctx_t *ctx, int negate, /* END QSE */ len = MIN(endptr - re - 2, 63); - if (qse_getctypebyxname (re + 2, len, &class) <= -1) status = REG_ECTYPE; + if (qse_strntoctype (re + 2, len, &class) <= -1) status = REG_ECTYPE; /* Optimize character classes for 8 bit character sets. */ #if defined(QSE_CHAR_IS_MCHAR) diff --git a/qse/samples/cmn/Makefile.am b/qse/samples/cmn/Makefile.am index 77368df9..82865c07 100644 --- a/qse/samples/cmn/Makefile.am +++ b/qse/samples/cmn/Makefile.am @@ -23,6 +23,7 @@ bin_PROGRAMS = \ main02 \ mbwc01 \ mbwc02 \ + nwad01 \ oht \ path01 \ pio \ @@ -62,6 +63,7 @@ main01_SOURCES = main01.c main02_SOURCES = main02.c mbwc01_SOURCES = mbwc01.c mbwc02_SOURCES = mbwc02.c +nwad01_SOURCES = nwad01.c oht_SOURCES = oht.c path01_SOURCES = path01.c pio_SOURCES = pio.c diff --git a/qse/samples/cmn/Makefile.in b/qse/samples/cmn/Makefile.in index ead75bbb..fd6cd449 100644 --- a/qse/samples/cmn/Makefile.in +++ b/qse/samples/cmn/Makefile.in @@ -38,10 +38,11 @@ bin_PROGRAMS = chr01$(EXEEXT) env$(EXEEXT) dll$(EXEEXT) fio01$(EXEEXT) \ fio02$(EXEEXT) fma$(EXEEXT) fmt01$(EXEEXT) fmt02$(EXEEXT) \ fs01$(EXEEXT) htb$(EXEEXT) ipad01$(EXEEXT) lda$(EXEEXT) \ main01$(EXEEXT) main02$(EXEEXT) mbwc01$(EXEEXT) \ - mbwc02$(EXEEXT) oht$(EXEEXT) path01$(EXEEXT) pio$(EXEEXT) \ - pma$(EXEEXT) rex01$(EXEEXT) rbt$(EXEEXT) sio01$(EXEEXT) \ - sio02$(EXEEXT) sio03$(EXEEXT) sll$(EXEEXT) slmb01$(EXEEXT) \ - str01$(EXEEXT) time$(EXEEXT) tre01$(EXEEXT) xma$(EXEEXT) + mbwc02$(EXEEXT) nwad01$(EXEEXT) oht$(EXEEXT) path01$(EXEEXT) \ + pio$(EXEEXT) pma$(EXEEXT) rex01$(EXEEXT) rbt$(EXEEXT) \ + sio01$(EXEEXT) sio02$(EXEEXT) sio03$(EXEEXT) sll$(EXEEXT) \ + slmb01$(EXEEXT) str01$(EXEEXT) time$(EXEEXT) tre01$(EXEEXT) \ + xma$(EXEEXT) @WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS) subdir = samples/cmn DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in @@ -125,6 +126,10 @@ am_mbwc02_OBJECTS = mbwc02.$(OBJEXT) mbwc02_OBJECTS = $(am_mbwc02_OBJECTS) mbwc02_LDADD = $(LDADD) mbwc02_DEPENDENCIES = $(am__DEPENDENCIES_2) +am_nwad01_OBJECTS = nwad01.$(OBJEXT) +nwad01_OBJECTS = $(am_nwad01_OBJECTS) +nwad01_LDADD = $(LDADD) +nwad01_DEPENDENCIES = $(am__DEPENDENCIES_2) am_oht_OBJECTS = oht.$(OBJEXT) oht_OBJECTS = $(am_oht_OBJECTS) oht_LDADD = $(LDADD) @@ -203,21 +208,23 @@ SOURCES = $(chr01_SOURCES) $(dll_SOURCES) $(env_SOURCES) \ $(fmt01_SOURCES) $(fmt02_SOURCES) $(fs01_SOURCES) \ $(htb_SOURCES) $(ipad01_SOURCES) $(lda_SOURCES) \ $(main01_SOURCES) $(main02_SOURCES) $(mbwc01_SOURCES) \ - $(mbwc02_SOURCES) $(oht_SOURCES) $(path01_SOURCES) \ - $(pio_SOURCES) $(pma_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) \ - $(sio01_SOURCES) $(sio02_SOURCES) $(sio03_SOURCES) \ - $(sll_SOURCES) $(slmb01_SOURCES) $(str01_SOURCES) \ - $(time_SOURCES) $(tre01_SOURCES) $(xma_SOURCES) + $(mbwc02_SOURCES) $(nwad01_SOURCES) $(oht_SOURCES) \ + $(path01_SOURCES) $(pio_SOURCES) $(pma_SOURCES) $(rbt_SOURCES) \ + $(rex01_SOURCES) $(sio01_SOURCES) $(sio02_SOURCES) \ + $(sio03_SOURCES) $(sll_SOURCES) $(slmb01_SOURCES) \ + $(str01_SOURCES) $(time_SOURCES) $(tre01_SOURCES) \ + $(xma_SOURCES) DIST_SOURCES = $(chr01_SOURCES) $(dll_SOURCES) $(env_SOURCES) \ $(fio01_SOURCES) $(fio02_SOURCES) $(fma_SOURCES) \ $(fmt01_SOURCES) $(fmt02_SOURCES) $(fs01_SOURCES) \ $(htb_SOURCES) $(ipad01_SOURCES) $(lda_SOURCES) \ $(main01_SOURCES) $(main02_SOURCES) $(mbwc01_SOURCES) \ - $(mbwc02_SOURCES) $(oht_SOURCES) $(path01_SOURCES) \ - $(pio_SOURCES) $(pma_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) \ - $(sio01_SOURCES) $(sio02_SOURCES) $(sio03_SOURCES) \ - $(sll_SOURCES) $(slmb01_SOURCES) $(str01_SOURCES) \ - $(time_SOURCES) $(tre01_SOURCES) $(xma_SOURCES) + $(mbwc02_SOURCES) $(nwad01_SOURCES) $(oht_SOURCES) \ + $(path01_SOURCES) $(pio_SOURCES) $(pma_SOURCES) $(rbt_SOURCES) \ + $(rex01_SOURCES) $(sio01_SOURCES) $(sio02_SOURCES) \ + $(sio03_SOURCES) $(sll_SOURCES) $(slmb01_SOURCES) \ + $(str01_SOURCES) $(time_SOURCES) $(tre01_SOURCES) \ + $(xma_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -390,6 +397,7 @@ main01_SOURCES = main01.c main02_SOURCES = main02.c mbwc01_SOURCES = mbwc01.c mbwc02_SOURCES = mbwc02.c +nwad01_SOURCES = nwad01.c oht_SOURCES = oht.c path01_SOURCES = path01.c pio_SOURCES = pio.c @@ -530,6 +538,9 @@ mbwc01$(EXEEXT): $(mbwc01_OBJECTS) $(mbwc01_DEPENDENCIES) mbwc02$(EXEEXT): $(mbwc02_OBJECTS) $(mbwc02_DEPENDENCIES) @rm -f mbwc02$(EXEEXT) $(LINK) $(mbwc02_OBJECTS) $(mbwc02_LDADD) $(LIBS) +nwad01$(EXEEXT): $(nwad01_OBJECTS) $(nwad01_DEPENDENCIES) + @rm -f nwad01$(EXEEXT) + $(LINK) $(nwad01_OBJECTS) $(nwad01_LDADD) $(LIBS) oht$(EXEEXT): $(oht_OBJECTS) $(oht_DEPENDENCIES) @rm -f oht$(EXEEXT) $(LINK) $(oht_OBJECTS) $(oht_LDADD) $(LIBS) @@ -598,6 +609,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main02.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbwc01.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbwc02.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nwad01.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path01.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Po@am__quote@ diff --git a/qse/samples/cmn/ipad01.c b/qse/samples/cmn/ipad01.c index 312c095f..b367ec4a 100644 --- a/qse/samples/cmn/ipad01.c +++ b/qse/samples/cmn/ipad01.c @@ -8,7 +8,7 @@ # include #endif -static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) +static int test_ipad4 (void) { qse_ipad4_t ipad4; qse_char_t buf[32]; @@ -93,6 +93,99 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) return 0; } +static int test_ipad6 (void) +{ + qse_ipad6_t ipad6; + qse_char_t buf[32]; + qse_mchar_t mbsbuf[32]; + qse_wchar_t wcsbuf[32]; + qse_size_t i; + + static qse_char_t* ipstr[] = + { + QSE_T("::"), + QSE_T("::1"), + QSE_T("fe80::f27b:cbff:fea3:f40c"), + QSE_T("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + QSE_T("2001:db8:1234:ffff:ffff:ffff:ffff:ffff"), + QSE_T("::ffff:0:0"), + QSE_T("::ffff:192.168.1.1") + }; + + static qse_mchar_t* ipstr_mbs[] = + { + QSE_MT("::"), + QSE_MT("::1"), + QSE_MT("fe80::f27b:cbff:fea3:f40c"), + QSE_MT("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + QSE_MT("2001:db8:1234:ffff:ffff:ffff:ffff:ffff"), + QSE_MT("::ffff:0:0"), + QSE_MT("::ffff:192.168.1.1") + }; + + static qse_wchar_t* ipstr_wcs[] = + { + QSE_WT("::"), + QSE_WT("::1"), + QSE_WT("fe80::f27b:cbff:fea3:f40c"), + QSE_WT("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + QSE_WT("2001:db8:1234:ffff:ffff:ffff:ffff:ffff"), + QSE_WT("::ffff:0:0"), + QSE_WT("::ffff:192.168.1.1") + }; + + for (i = 0; i < QSE_COUNTOF(ipstr); i++) + { + if (qse_strtoipad6 (ipstr[i], &ipad6) <= -1) + { + qse_printf (QSE_T("Failed to convert %s\n"), ipstr[i]); + } + else + { + qse_ipad6tostr (&ipad6, buf, QSE_COUNTOF(buf)); + qse_printf (QSE_T("Converted [%s] to [%s]\n"), ipstr[i], buf); + } + } + + qse_printf (QSE_T("-------------------\n")); + for (i = 0; i < QSE_COUNTOF(ipstr_mbs); i++) + { + if (qse_mbstoipad6 (ipstr_mbs[i], &ipad6) <= -1) + { + qse_printf (QSE_T("Failed to convert %hs\n"), ipstr_mbs[i]); + } + else + { + qse_ipad6tombs (&ipad6, mbsbuf, QSE_COUNTOF(mbsbuf)); + qse_printf (QSE_T("Converted [%hs] to [%hs]\n"), ipstr_mbs[i], mbsbuf); + } + } + + qse_printf (QSE_T("-------------------\n")); + for (i = 0; i < QSE_COUNTOF(ipstr_wcs); i++) + { + if (qse_wcstoipad6 (ipstr_wcs[i], &ipad6) <= -1) + { + qse_printf (QSE_T("Failed to convert %ls\n"), ipstr_wcs[i]); + } + else + { + qse_ipad6towcs (&ipad6, wcsbuf, QSE_COUNTOF(wcsbuf)); + qse_printf (QSE_T("Converted [%ls] to [%ls]\n"), ipstr_wcs[i], wcsbuf); + } + } + + return 0; +} + +static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) +{ + test_ipad4 (); + qse_printf (QSE_T("==============\n")); + test_ipad6 (); + return 0; +} + int qse_main (int argc, qse_achar_t* argv[], qse_achar_t* envp[]) { #if defined(_WIN32) diff --git a/qse/samples/cmn/nwad01.c b/qse/samples/cmn/nwad01.c new file mode 100644 index 00000000..e07b0dad --- /dev/null +++ b/qse/samples/cmn/nwad01.c @@ -0,0 +1,166 @@ +#include +#include +#include +#include + +#include +#if defined(_WIN32) +# include +#endif + +static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) +{ + qse_nwad_t nwad; + qse_char_t buf[64]; + qse_mchar_t mbsbuf[64]; + qse_wchar_t wcsbuf[64]; + qse_size_t i; + + static qse_char_t* ipstr[] = + { + QSE_T("192.168.1.1"), + QSE_T("255.255.255.255"), + QSE_T("4.3.0.0"), + QSE_T("4.3.0.0X"), + QSE_T("65.1234.11.34"), + QSE_T("65.123.11.34"), + QSE_T("1.1.1.1"), + QSE_T("::"), + QSE_T("::1"), + QSE_T("fe80::f27b:cbff:fea3:f40c"), + QSE_T("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + QSE_T("2001:db8:1234:ffff:ffff:ffff:ffff:ffff"), + QSE_T("::ffff:0:0"), + QSE_T("::ffff:192.168.1.1"), + QSE_T("::ffff:192.168.1.1%88"), + QSE_T("[::]:10"), + QSE_T("[::1]:20"), + QSE_T("[fe80::f27b:cbff:fea3:f40c]:30"), + QSE_T("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:60"), + QSE_T("[2001:db8:1234:ffff:ffff:ffff:ffff:ffff]:50"), + QSE_T("[::ffff:0:0]:60"), + QSE_T("[::ffff:192.168.1.1]:70"), + QSE_T("[::ffff:192.168.1.1%999]:70") + }; + + static qse_mchar_t* ipstr_mbs[] = + { + QSE_MT("192.168.1.1"), + QSE_MT("255.255.255.255"), + QSE_MT("4.3.0.0"), + QSE_MT("4.3.0.0X"), + QSE_MT("65.1234.11.34"), + QSE_MT("65.123.11.34"), + QSE_MT("1.1.1.1"), + QSE_MT("::"), + QSE_MT("::1"), + QSE_MT("fe80::f27b:cbff:fea3:f40c"), + QSE_MT("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + QSE_MT("2001:db8:1234:ffff:ffff:ffff:ffff:ffff"), + QSE_MT("::ffff:0:0"), + QSE_MT("::ffff:192.168.1.1"), + QSE_MT("::ffff:192.168.1.1%88"), + QSE_MT("[::]:10"), + QSE_MT("[::1]:20"), + QSE_MT("[fe80::f27b:cbff:fea3:f40c]:30"), + QSE_MT("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:60"), + QSE_MT("[2001:db8:1234:ffff:ffff:ffff:ffff:ffff]:50"), + QSE_MT("[::ffff:0:0]:60"), + QSE_MT("[::ffff:192.168.1.1]:70"), + QSE_MT("[::ffff:192.168.1.1%999]:70") + }; + + static qse_wchar_t* ipstr_wcs[] = + { + QSE_WT("192.168.1.1"), + QSE_WT("255.255.255.255"), + QSE_WT("4.3.0.0"), + QSE_WT("4.3.0.0X"), + QSE_WT("65.1234.11.34"), + QSE_WT("65.123.11.34"), + QSE_WT("1.1.1.1"), + QSE_WT("::"), + QSE_WT("::1"), + QSE_WT("fe80::f27b:cbff:fea3:f40c"), + QSE_WT("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + QSE_WT("2001:db8:1234:ffff:ffff:ffff:ffff:ffff"), + QSE_WT("::ffff:0:0"), + QSE_WT("::ffff:192.168.1.1"), + QSE_WT("::ffff:192.168.1.1%88"), + QSE_WT("[::]:10"), + QSE_WT("[::1]:20"), + QSE_WT("[fe80::f27b:cbff:fea3:f40c]:30"), + QSE_WT("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:60"), + QSE_WT("[2001:db8:1234:ffff:ffff:ffff:ffff:ffff]:50"), + QSE_WT("[::ffff:0:0]:60"), + QSE_WT("[::ffff:192.168.1.1]:70"), + QSE_WT("[::ffff:192.168.1.1%999]:70") + }; + + for (i = 0; i < QSE_COUNTOF(ipstr); i++) + { + if (qse_strtonwad (ipstr[i], &nwad) <= -1) + { + qse_printf (QSE_T("Failed to convert %s\n"), ipstr[i]); + } + else + { + qse_nwadtostr (&nwad, buf, QSE_COUNTOF(buf)); + qse_printf (QSE_T("Converted <%s> to <%s>\n"), ipstr[i], buf); + } + } + + qse_printf (QSE_T("-------------------\n")); + for (i = 0; i < QSE_COUNTOF(ipstr_mbs); i++) + { + if (qse_mbstonwad (ipstr_mbs[i], &nwad) <= -1) + { + qse_printf (QSE_T("Failed to convert %hs\n"), ipstr_mbs[i]); + } + else + { + qse_nwadtombs (&nwad, mbsbuf, QSE_COUNTOF(mbsbuf)); + qse_printf (QSE_T("Converted <%hs> to <%hs>\n"), ipstr_mbs[i], mbsbuf); + } + } + + qse_printf (QSE_T("-------------------\n")); + for (i = 0; i < QSE_COUNTOF(ipstr_wcs); i++) + { + if (qse_wcstonwad (ipstr_wcs[i], &nwad) <= -1) + { + qse_printf (QSE_T("Failed to convert %ls\n"), ipstr_wcs[i]); + } + else + { + qse_nwadtowcs (&nwad, wcsbuf, QSE_COUNTOF(wcsbuf)); + qse_printf (QSE_T("Converted <%ls> to <%ls>\n"), ipstr_wcs[i], wcsbuf); + } + } + + return 0; +} + +int qse_main (int argc, qse_achar_t* argv[], qse_achar_t* envp[]) +{ +#if defined(_WIN32) + char locale[100]; + UINT codepage = GetConsoleOutputCP(); + if (codepage == CP_UTF8) + { + /*SetConsoleOUtputCP (CP_UTF8);*/ + qse_setdflcmgr (qse_utf8cmgr); + } + else + { + sprintf (locale, ".%u", (unsigned int)codepage); + setlocale (LC_ALL, locale); + qse_setdflcmgr (qse_slmbcmgr); + } +#else + setlocale (LC_ALL, ""); + qse_setdflcmgr (qse_slmbcmgr); +#endif + return qse_runmainwithenv (argc, argv, envp, test_main); +} +