another unsigned char cast in os2cp.c. code clean-up in os/2 geniconv.

This commit is contained in:
Ozkan Sezer 2021-12-17 07:33:10 +03:00
parent dac6516057
commit 48d1ef8fad
5 changed files with 152 additions and 140 deletions

View File

@ -25,34 +25,31 @@
Andrey Vasilkin, 2016. Andrey Vasilkin, 2016.
*/ */
#define INCL_DOSMODULEMGR /* Module Manager values */ #define INCL_DOSMODULEMGR /* Module Manager */
#define INCL_DOSERRORS /* Error values */ #define INCL_DOSERRORS /* Error values */
#include <os2.h> #include <os2.h>
#include "geniconv.h" #include "geniconv.h"
/*#define DEBUG*/ /*#define DEBUG*/
#ifdef DEBUG #ifdef DEBUG
# include <stdio.h> # include <stdio.h>
# define debug(s,...) printf(__func__"(): "##s"\n" ,##__VA_ARGS__) # define iconv_debug(s,...) printf(__func__"(): "##s"\n" ,##__VA_ARGS__)
#else #else
# define debug(s,...) do {} while (0) # define iconv_debug(s,...) do {} while (0)
#endif #endif
/* Exports from os2iconv.c */ /* Exports from os2iconv.c */
extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode); extern iconv_t _System os2_iconv_open (const char* tocode, const char* fromcode);
extern size_t _System os2_iconv(iconv_t cd, char* * inbuf, extern size_t _System os2_iconv (iconv_t cd,
size_t *inbytesleft, char* * outbuf, char **inbuf, size_t *inbytesleft,
size_t *outbytesleft); char **outbuf, size_t *outbytesleft);
extern int _System os2_iconv_close(iconv_t cd); extern int _System os2_iconv_close (iconv_t cd);
/* Functions pointers types */ /* Functions pointers types */
typedef iconv_t _System (*FNICONV_OPEN)(const char* tocode, const char* fromcode); typedef iconv_t (_System *FNICONV_OPEN)(const char*, const char*);
typedef size_t _System (*FNICONV)(iconv_t cd, char* * inbuf, typedef size_t (_System *FNICONV) (iconv_t, char **, size_t *, char **, size_t *);
size_t *inbytesleft, char* * outbuf, typedef int (_System *FNICONV_CLOSE)(iconv_t);
size_t *outbytesleft);
typedef int _System (*FNICONV_CLOSE)(iconv_t cd);
/* Used DLL module handle */ /* Used DLL module handle */
static HMODULE hmIconv = NULLHANDLE; static HMODULE hmIconv = NULLHANDLE;
@ -62,41 +59,42 @@ static FNICONV fn_iconv = NULL;
static FNICONV_CLOSE fn_iconv_close = NULL; static FNICONV_CLOSE fn_iconv_close = NULL;
static BOOL _loadDLL(PSZ pszName, PSZ pszIconvOpen, PSZ pszIconv, static BOOL _loadDLL(const char *dllname,
PSZ pszIconvClose) const char *sym_iconvopen,
const char *sym_iconv,
const char *sym_iconvclose)
{ {
ULONG ulRC; ULONG rc;
CHAR acError[256]; char error[256];
ulRC = DosLoadModule(acError, sizeof(acError), pszName, &hmIconv); rc = DosLoadModule(error, sizeof(error), dllname, &hmIconv);
if (ulRC != NO_ERROR) { if (rc != NO_ERROR) {
debug("DLL not loaded: %s", &acError); iconv_debug("DLL %s not loaded: %s", dllname, error);
return FALSE; return FALSE;
} }
do { rc = DosQueryProcAddr(hmIconv, 0, sym_iconvopen, (PFN *)&fn_iconv_open);
ulRC = DosQueryProcAddr(hmIconv, 0, pszIconvOpen, (PFN *)&fn_iconv_open); if (rc != NO_ERROR) {
if (ulRC != NO_ERROR) { iconv_debug("Error: cannot find entry %s in %s", sym_iconvopen, dllname);
debug("Error: cannot find entry %s in %s", pszIconvOpen, pszName); goto fail;
break; }
}
ulRC = DosQueryProcAddr(hmIconv, 0, pszIconv, (PFN *)&fn_iconv); rc = DosQueryProcAddr(hmIconv, 0, sym_iconv, (PFN *)&fn_iconv);
if (ulRC != NO_ERROR) { if (rc != NO_ERROR) {
debug("Error: cannot find entry %s in %s", pszIconv, pszName); iconv_debug("Error: cannot find entry %s in %s", sym_iconv, dllname);
break; goto fail;
} }
ulRC = DosQueryProcAddr(hmIconv, 0, pszIconvClose, (PFN *)&fn_iconv_close); rc = DosQueryProcAddr(hmIconv, 0, sym_iconvclose, (PFN *)&fn_iconv_close);
if (ulRC != NO_ERROR) { if (rc != NO_ERROR) {
debug("Error: cannot find entry %s in %s", pszIconvClose, pszName); iconv_debug("Error: cannot find entry %s in %s", sym_iconvclose, dllname);
break; goto fail;
} }
debug("DLL %s used", pszName); iconv_debug("DLL %s used", dllname);
return TRUE; return TRUE;
} while (FALSE);
fail:
DosFreeModule(hmIconv); DosFreeModule(hmIconv);
hmIconv = NULLHANDLE; hmIconv = NULLHANDLE;
return FALSE; return FALSE;
@ -104,15 +102,16 @@ static BOOL _loadDLL(PSZ pszName, PSZ pszIconvOpen, PSZ pszIconv,
static void _init(void) static void _init(void)
{ {
if (fn_iconv_open != NULL) /* Already was initialized */ if (fn_iconv_open != NULL) {
return; return; /* Already initialized */
}
/* Try to load kiconv.dll, iconv2.dll or iconv.dll */ /* Try to load kiconv.dll, iconv2.dll or iconv.dll */
if (!_loadDLL("KICONV", "_libiconv_open", "_libiconv", "_libiconv_close") && if (!_loadDLL("KICONV", "_libiconv_open", "_libiconv", "_libiconv_close") &&
!_loadDLL("ICONV2", "_libiconv_open", "_libiconv", "_libiconv_close") && !_loadDLL("ICONV2", "_libiconv_open", "_libiconv", "_libiconv_close") &&
!_loadDLL("ICONV", "_iconv_open", "_iconv", "_iconv_close") ) { !_loadDLL("ICONV", "_iconv_open", "_iconv", "_iconv_close") ) {
/* No DLL was loaded - use OS/2 conversion objects API */ /* No DLL was loaded - use OS/2 conversion objects API */
debug("Uni*() API used"); iconv_debug("Uni*() API used");
fn_iconv_open = os2_iconv_open; fn_iconv_open = os2_iconv_open;
fn_iconv = os2_iconv; fn_iconv = os2_iconv;
fn_iconv_close = os2_iconv_close; fn_iconv_close = os2_iconv_close;

View File

@ -58,27 +58,27 @@ size_t libiconv (iconv_t cd, char **inbuf, size_t *inbytesleft,
/* System codepage <-> UTF-8 /* System codepage <-> UTF-8
* *
* StrUTF8() * StrUTF8()
* Coverts string from system cp to UTF-8 (fToUTF8 is not 0) or from UTF-8 to * Converts string from system cp to UTF-8 (to_utf8 is not 0) or from UTF-8 to
* the system cp (fToUTF8 is 0). Converted ASCIIZ string will be placed at the * the system cp (to_utf8 is 0). Converted ASCIIZ string will be placed at the
* buffer pcDst, up to cbDst - 1 (for sys->utf8) or 2 (for utf8->sys) bytes. * buffer dst, up to c_dst - 1 (for sys->utf8) or 2 (for utf8->sys) bytes.
* Returns the number of bytes written into pcDst, not counting the terminating * Returns the number of bytes written into dst, not counting the terminating
* 0 byte(s) or -1 on error. * 0 byte(s) or -1 on error.
*/ */
int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc); int StrUTF8(int to_utf8, char *dst, int c_dst, char *src, int c_src);
/* StrUTF8New() /* StrUTF8New()
* Coverts string from system cp to UTF-8 (fToUTF8 is not 0) or from UTF-8 to * Converts string from system cp to UTF-8 (to_utf8 is not 0) or from UTF-8
* the system cp (fToUTF8 is 0). Memory for the new string is obtained by * to the system cp (to_utf8 is 0). Memory for the new string is obtained by
* using libc malloc(). * using libc malloc().
* Returns converted string, terminating two bytes 0 is appended to the result. * Returns converted string, terminating two bytes 0 is appended to the result.
* Returns null on error. * Returns null on error.
*/ */
char *StrUTF8New(int fToUTF8, char *pcStr, int cbStr); char *StrUTF8New(int to_utf8, char *str, int c_str);
/* StrUTF8Free() /* StrUTF8Free()
* Deallocates the memory block located by StrUTF8New() (just libc free()). * Deallocates the memory block allocated by StrUTF8New() (just libc free()).
*/ */
void StrUTF8Free(char *pszStr); void StrUTF8Free(char *str);
#endif /* GENICONV_H */ #endif /* GENICONV_H */

View File

@ -315,30 +315,30 @@ char *os2cpToName(unsigned long cp)
if (cp == SYSTEM_CP) { if (cp == SYSTEM_CP) {
ULONG aulCP[3]; ULONG aulCP[3];
ULONG cCP; ULONG cCP;
if (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR) {
if (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)
return NULL; return NULL;
}
cp = aulCP[0]; cp = aulCP[0];
} }
if (aCP2Name[0].ulCode > cp || aCP2Name[ulHi].ulCode < cp) if (aCP2Name[0].ulCode > cp || aCP2Name[ulHi].ulCode < cp) {
return NULL; return NULL;
}
if (aCP2Name[0].ulCode == cp) if (aCP2Name[0].ulCode == cp) {
return aCP2Name[0].pszName; return aCP2Name[0].pszName;
}
if (aCP2Name[ulHi].ulCode == cp) if (aCP2Name[ulHi].ulCode == cp) {
return aCP2Name[ulHi].pszName; return aCP2Name[ulHi].pszName;
}
while ((ulHi - ulLo) > 1) { while ((ulHi - ulLo) > 1) {
ulNext = (ulLo + ulHi) / 2; ulNext = (ulLo + ulHi) / 2;
if (aCP2Name[ulNext].ulCode < cp) if (aCP2Name[ulNext].ulCode < cp) {
ulLo = ulNext; ulLo = ulNext;
else if (aCP2Name[ulNext].ulCode > cp) } else if (aCP2Name[ulNext].ulCode > cp) {
ulHi = ulNext; ulHi = ulNext;
else { } else {
lFound = ulNext; lFound = ulNext;
break; break;
} }
@ -360,46 +360,51 @@ unsigned long os2cpFromName(char *cp)
if (cp == NULL) { if (cp == NULL) {
ULONG aulCP[3]; ULONG aulCP[3];
ULONG cCP; ULONG cCP;
return (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)? 0 : aulCP[0]; return (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)? 0 : aulCP[0];
} }
while (SDL_isspace(*cp)) while (SDL_isspace((unsigned char) *cp)) {
cp++; cp++;
}
pcEnd = SDL_strchr(cp, ' '); pcEnd = SDL_strchr(cp, ' ');
if (pcEnd == NULL) if (pcEnd == NULL) {
pcEnd = SDL_strchr(cp, '\0'); pcEnd = SDL_strchr(cp, '\0');
}
ulNext = pcEnd - cp; ulNext = pcEnd - cp;
if (ulNext >= sizeof(acBuf)) if (ulNext >= sizeof(acBuf)) {
return 0; return 0;
}
SDL_memcpy(acBuf, cp, ulNext); SDL_memcpy(acBuf, cp, ulNext);
acBuf[ulNext] = '\0'; acBuf[ulNext] = '\0';
SDL_strupr(acBuf); SDL_strupr(acBuf);
lCmp = SDL_strcmp(aName2CP[0].pszName, acBuf); lCmp = SDL_strcmp(aName2CP[0].pszName, acBuf);
if (lCmp > 0) if (lCmp > 0) {
return 0; return 0;
else if (lCmp == 0) }
if (lCmp == 0) {
return aName2CP[0].ulCode; return aName2CP[0].ulCode;
}
lCmp = SDL_strcmp(aName2CP[ulHi].pszName, acBuf); lCmp = SDL_strcmp(aName2CP[ulHi].pszName, acBuf);
if (lCmp < 0) if (lCmp < 0) {
return 0; return 0;
else if (lCmp == 0) }
if (lCmp == 0) {
return aName2CP[ulHi].ulCode; return aName2CP[ulHi].ulCode;
}
while ((ulHi - ulLo) > 1) { while ((ulHi - ulLo) > 1) {
ulNext = (ulLo + ulHi) / 2; ulNext = (ulLo + ulHi) / 2;
lCmp = SDL_strcmp(aName2CP[ulNext].pszName, acBuf); lCmp = SDL_strcmp(aName2CP[ulNext].pszName, acBuf);
if (lCmp < 0) if (lCmp < 0) {
ulLo = ulNext; ulLo = ulNext;
else if (lCmp > 0) } else if (lCmp > 0) {
ulHi = ulNext; ulHi = ulNext;
else { } else {
lFound = ulNext; lFound = ulNext;
break; break;
} }

View File

@ -103,27 +103,28 @@ static int uconv_open(const char *code, UconvObject *uobj)
if (rc != ULS_SUCCESS) { if (rc != ULS_SUCCESS) {
unsigned long cp = os2cpFromName((char *)code); unsigned long cp = os2cpFromName((char *)code);
char cp_name[16]; char cp_name[16];
if (cp != 0 && SDL_snprintf(cp_name, sizeof(cp_name), "IBM-%u", cp) > 0) {
if (cp != 0 && SDL_snprintf(cp_name, sizeof(cp_name), "IBM-%u", cp) > 0)
rc = _createUconvObj(cp_name, uobj); rc = _createUconvObj(cp_name, uobj);
}
} }
return rc; return rc;
} }
extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode) iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode)
{ {
UconvObject uo_tocode; UconvObject uo_tocode;
UconvObject uo_fromcode; UconvObject uo_fromcode;
int rc; int rc;
iuconv_obj *iuobj; iuconv_obj *iuobj;
if (tocode == NULL) if (tocode == NULL) {
tocode = ""; tocode = "";
}
if (fromcode == NULL) if (fromcode == NULL) {
fromcode = ""; fromcode = "";
}
if (SDL_strcasecmp(tocode, fromcode) != 0) { if (SDL_strcasecmp(tocode, fromcode) != 0) {
rc = uconv_open(fromcode, &uo_fromcode); rc = uconv_open(fromcode, &uo_fromcode);
@ -131,7 +132,6 @@ extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode)
errno = EINVAL; errno = EINVAL;
return (iconv_t)(-1); return (iconv_t)(-1);
} }
rc = uconv_open(tocode, &uo_tocode); rc = uconv_open(tocode, &uo_tocode);
if (rc != ULS_SUCCESS) { if (rc != ULS_SUCCESS) {
UniFreeUconvObject(uo_fromcode); UniFreeUconvObject(uo_fromcode);
@ -155,9 +155,9 @@ extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode)
return iuobj; return iuobj;
} }
extern size_t _System os2_iconv(iconv_t cd, char* * inbuf, size_t _System os2_iconv(iconv_t cd,
size_t *inbytesleft, char **inbuf, size_t *inbytesleft ,
char* * outbuf, size_t *outbytesleft) char **outbuf, size_t *outbytesleft)
{ {
UconvObject uo_tocode = ((iuconv_obj *)(cd))->uo_tocode; UconvObject uo_tocode = ((iuconv_obj *)(cd))->uo_tocode;
UconvObject uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode; UconvObject uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode;
@ -183,12 +183,12 @@ extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
DosRequestMutexSem(((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT); DosRequestMutexSem(((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT);
#endif #endif
if (uo_tocode && uo_fromcode && if (uo_tocode && uo_fromcode && (((iuconv_obj *)cd)->buf_len >> 1) < *inbytesleft) {
(((iuconv_obj *)cd)->buf_len >> 1) < *inbytesleft) { if (((iuconv_obj *)cd)->buf != NULL) {
if (((iuconv_obj *)cd)->buf != NULL)
SDL_free(((iuconv_obj *)cd)->buf); SDL_free(((iuconv_obj *)cd)->buf);
}
((iuconv_obj *)cd)->buf_len = *inbytesleft << 1; ((iuconv_obj *)cd)->buf_len = *inbytesleft << 1;
((iuconv_obj *)cd)->buf = (UniChar *)SDL_malloc(((iuconv_obj *)cd)->buf_len); ((iuconv_obj *)cd)->buf = (UniChar *) SDL_malloc(((iuconv_obj *)cd)->buf_len);
} }
if (uo_fromcode) { if (uo_fromcode) {
@ -205,8 +205,9 @@ extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
rc = UniUconvToUcs(uo_fromcode, (void **)inbuf, inbytesleft, rc = UniUconvToUcs(uo_fromcode, (void **)inbuf, inbytesleft,
uc_str, uc_str_len, &nonIdenticalConv); uc_str, uc_str_len, &nonIdenticalConv);
uc_buf_len = uc_buf_len << 1; uc_buf_len = uc_buf_len << 1;
if (!uo_tocode) if (!uo_tocode) {
*outbytesleft = uc_buf_len; *outbytesleft = uc_buf_len;
}
if (rc != ULS_SUCCESS) { if (rc != ULS_SUCCESS) {
errno = EILSEQ; errno = EILSEQ;
@ -216,8 +217,9 @@ extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
goto done; goto done;
} }
if (!uo_tocode) if (!uo_tocode) {
return nonIdenticalConv; return nonIdenticalConv;
}
uc_buf = ((iuconv_obj *)cd)->buf; uc_buf = ((iuconv_obj *)cd)->buf;
uc_buf_len = ((iuconv_obj *)cd)->buf_len - uc_buf_len; uc_buf_len = ((iuconv_obj *)cd)->buf_len - uc_buf_len;
@ -266,14 +268,16 @@ int _System os2_iconv_close(iconv_t cd)
#ifdef ICONV_THREAD_SAFE #ifdef ICONV_THREAD_SAFE
DosCloseMutexSem(((iuconv_obj *)cd)->hMtx); DosCloseMutexSem(((iuconv_obj *)cd)->hMtx);
#endif #endif
if (((iuconv_obj *)cd)->uo_tocode != NULL) if (((iuconv_obj *)cd)->uo_tocode != NULL) {
UniFreeUconvObject(((iuconv_obj *)cd)->uo_tocode); UniFreeUconvObject(((iuconv_obj *)cd)->uo_tocode);
if (((iuconv_obj *)cd)->uo_fromcode != NULL) }
if (((iuconv_obj *)cd)->uo_fromcode != NULL) {
UniFreeUconvObject(((iuconv_obj *)cd)->uo_fromcode); UniFreeUconvObject(((iuconv_obj *)cd)->uo_fromcode);
}
if (((iuconv_obj *)cd)->buf != NULL) if (((iuconv_obj *)cd)->buf != NULL) {
SDL_free(((iuconv_obj *)cd)->buf); SDL_free(((iuconv_obj *)cd)->buf);
}
SDL_free(cd); SDL_free(cd);
return 0; return 0;

View File

@ -30,40 +30,42 @@
#define SDL_free free #define SDL_free free
#endif #endif
int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc) int StrUTF8(int to_utf8, char *dst, int c_dst, char *src, int c_src)
{ {
size_t rc; size_t rc;
char *pcDstStart = pcDst; char *dststart = dst;
iconv_t cd; iconv_t cd;
char *pszToCP, *pszFromCP; char *tocp, *fromcp;
int fError = 0; int err = 0;
if (cbDst < 4) if (c_dst < 4) {
return -1; return -1;
if (fToUTF8) {
pszToCP = "UTF-8";
pszFromCP = "";
} else {
pszToCP = "";
pszFromCP = "UTF-8";
} }
cd = iconv_open(pszToCP, pszFromCP); if (to_utf8) {
if (cd == (iconv_t)-1) tocp = "UTF-8";
return -1; fromcp = "";
} else {
tocp = "";
fromcp = "UTF-8";
}
while (cbSrc > 0) { cd = iconv_open(tocp, fromcp);
rc = iconv(cd, &pcSrc, (size_t *)&cbSrc, &pcDst, (size_t *)&cbDst); if (cd == (iconv_t)-1) {
return -1;
}
while (c_src > 0) {
rc = iconv(cd, &src, (size_t *)&c_src, &dst, (size_t *)&c_dst);
if (rc == (size_t)-1) { if (rc == (size_t)-1) {
if (errno == EILSEQ) { if (errno == EILSEQ) {
/* Try to skip invalid character */ /* Try to skip invalid character */
pcSrc++; src++;
cbSrc--; c_src--;
continue; continue;
} }
fError = 1; err = 1;
break; break;
} }
} }
@ -71,45 +73,47 @@ int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc)
iconv_close(cd); iconv_close(cd);
/* Write trailing ZERO (1 byte for UTF-8, 2 bytes for the system cp) */ /* Write trailing ZERO (1 byte for UTF-8, 2 bytes for the system cp) */
if (fToUTF8) { if (to_utf8) {
if (cbDst < 1) { if (c_dst < 1) {
pcDst--; dst--;
fError = 1; /* The destination buffer overflow */ err = 1; /* The destination buffer overflow */
} }
*pcDst = '\0'; *dst = '\0';
} else { } else {
if (cbDst < 2) { if (c_dst < 2) {
pcDst -= (cbDst == 0)? 2 : 1; dst -= (c_dst == 0) ? 2 : 1;
fError = 1; /* The destination buffer overflow */ err = 1; /* The destination buffer overflow */
} }
*((short *)pcDst) = '\0'; *((short *)dst) = '\0';
} }
return (fError) ? -1 : (pcDst - pcDstStart); return (err) ? -1 : (dst - dststart);
} }
char *StrUTF8New(int fToUTF8, char *pcStr, int cbStr) char *StrUTF8New(int to_utf8, char *str, int c_str)
{ {
int cbNewStr = (((cbStr > 4)? cbStr : 4) + 1) * 2; int c_newstr = (((c_str > 4) ? c_str : 4) + 1) * 2;
char *pszNewStr = (char *) SDL_malloc(cbNewStr); char * newstr = (char *) SDL_malloc(c_newstr);
if (pszNewStr == NULL) if (newstr == NULL) {
return NULL; return NULL;
cbNewStr = StrUTF8(fToUTF8, pszNewStr, cbNewStr, pcStr, cbStr);
if (cbNewStr != -1) {
pcStr = (char *) SDL_realloc(pszNewStr, cbNewStr + ((fToUTF8)? 1 : sizeof(short)));
if (pcStr)
return pcStr;
} }
SDL_free(pszNewStr); c_newstr = StrUTF8(to_utf8, newstr, c_newstr, str, c_str);
if (c_newstr != -1) {
str = (char *) SDL_realloc(newstr, c_newstr + ((to_utf8) ? 1 : sizeof(short)));
if (str) {
return str;
}
}
SDL_free(newstr);
return NULL; return NULL;
} }
void StrUTF8Free(char *pszStr) void StrUTF8Free(char *str)
{ {
SDL_free(pszStr); SDL_free(str);
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */