intl/icu/source/extra/uconv/uwmsg.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/extra/uconv/uwmsg.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,264 @@
     1.4 +/*
     1.5 +**********************************************************************
     1.6 +* Copyright (C) 1998-2012, International Business Machines Corporation
     1.7 +* and others.  All Rights Reserved.
     1.8 +**********************************************************************
     1.9 +*
    1.10 +* File uwmsg.c
    1.11 +*
    1.12 +* Modification History:
    1.13 +*
    1.14 +*   Date        Name        Description
    1.15 +*   06/14/99    stephen     Creation.
    1.16 +*******************************************************************************
    1.17 +*/
    1.18 +
    1.19 +#include "unicode/ucnv.h"
    1.20 +#include "unicode/ustring.h"
    1.21 +#include "unicode/umsg.h"
    1.22 +#include "unicode/uwmsg.h"
    1.23 +#include "unicode/ures.h"
    1.24 +#include "unicode/putil.h"
    1.25 +#include "cstring.h"
    1.26 +
    1.27 +#include <stdlib.h>
    1.28 +#include <stdarg.h>
    1.29 +#include <stdio.h>
    1.30 +#include <string.h>
    1.31 +
    1.32 +#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
    1.33 +
    1.34 +#define BUF_SIZE 128
    1.35 +
    1.36 +/* Print a ustring to the specified FILE* in the default codepage */
    1.37 +static void
    1.38 +uprint(const UChar *s,
    1.39 +       int32_t sourceLen,
    1.40 +       FILE *f,
    1.41 +       UErrorCode *status)
    1.42 +{
    1.43 +    /* converter */
    1.44 +    UConverter *converter;
    1.45 +    char buf [BUF_SIZE];
    1.46 +    const UChar *mySource;
    1.47 +    const UChar *mySourceEnd;
    1.48 +    char *myTarget;
    1.49 +    int32_t arraySize;
    1.50 +
    1.51 +    if(s == 0) return;
    1.52 +
    1.53 +    /* set up the conversion parameters */
    1.54 +    mySource     = s;
    1.55 +    mySourceEnd  = mySource + sourceLen;
    1.56 +    myTarget     = buf;
    1.57 +    arraySize    = BUF_SIZE;
    1.58 +
    1.59 +    /* open a default converter */
    1.60 +    converter = ucnv_open(0, status);
    1.61 +
    1.62 +    /* if we failed, clean up and exit */
    1.63 +    if(U_FAILURE(*status)) goto finish;
    1.64 +
    1.65 +    /* perform the conversion */
    1.66 +    do {
    1.67 +        /* reset the error code */
    1.68 +        *status = U_ZERO_ERROR;
    1.69 +
    1.70 +        /* perform the conversion */
    1.71 +        ucnv_fromUnicode(converter, &myTarget,  myTarget + arraySize,
    1.72 +            &mySource, mySourceEnd, NULL,
    1.73 +            TRUE, status);
    1.74 +
    1.75 +        /* Write the converted data to the FILE* */
    1.76 +        fwrite(buf, sizeof(char), myTarget - buf, f);
    1.77 +
    1.78 +        /* update the conversion parameters*/
    1.79 +        myTarget     = buf;
    1.80 +        arraySize    = BUF_SIZE;
    1.81 +    }
    1.82 +    while(*status == U_BUFFER_OVERFLOW_ERROR); 
    1.83 +
    1.84 +finish:
    1.85 +
    1.86 +    /* close the converter */
    1.87 +    ucnv_close(converter);
    1.88 +}
    1.89 +
    1.90 +static UResourceBundle *gBundle = NULL;
    1.91 +
    1.92 +U_STRING_DECL(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38);
    1.93 +
    1.94 +U_CFUNC UResourceBundle *u_wmsg_setPath(const char *path, UErrorCode *err)
    1.95 +{
    1.96 +  if(U_FAILURE(*err))
    1.97 +  {
    1.98 +    return 0;
    1.99 +  }
   1.100 +
   1.101 +  if(gBundle != NULL)
   1.102 +  {
   1.103 +    *err = U_ILLEGAL_ARGUMENT_ERROR;
   1.104 +    return 0;
   1.105 +  }
   1.106 +  else
   1.107 +  {
   1.108 +    UResourceBundle *b = NULL;
   1.109 +    b = ures_open(path, NULL, err);
   1.110 +    if(U_FAILURE(*err))
   1.111 +    {
   1.112 +         return 0;
   1.113 +    }
   1.114 +
   1.115 +    gBundle = b;
   1.116 +
   1.117 +    U_STRING_INIT(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38);
   1.118 +  }
   1.119 +  
   1.120 +  return gBundle;
   1.121 +}
   1.122 +
   1.123 +/* Format a message and print it's output to fp */
   1.124 +U_CFUNC int u_wmsg(FILE *fp, const char *tag, ... )
   1.125 +{
   1.126 +    const UChar *msg;
   1.127 +    int32_t      msgLen;
   1.128 +    UErrorCode  err = U_ZERO_ERROR;
   1.129 +#if !UCONFIG_NO_FORMATTING
   1.130 +    va_list ap;
   1.131 +#endif
   1.132 +    UChar   result[4096];
   1.133 +    int32_t resultLength = LENGTHOF(result);
   1.134 +
   1.135 +    if(gBundle == NULL)
   1.136 +    {
   1.137 +#if 0
   1.138 +        fprintf(stderr, "u_wmsg: No path set!!\n"); /* FIXME: codepage?? */
   1.139 +#endif
   1.140 +        return -1;
   1.141 +    }
   1.142 +
   1.143 +    msg = ures_getStringByKey(gBundle, tag, &msgLen, &err);
   1.144 +
   1.145 +    if(U_FAILURE(err))
   1.146 +    {
   1.147 +        return -1;
   1.148 +    }
   1.149 +
   1.150 +#if UCONFIG_NO_FORMATTING
   1.151 +    resultLength = sizeof(gNoFormatting) / U_SIZEOF_UCHAR;
   1.152 +    if((msgLen + resultLength) <= LENGTHOF(result)) {
   1.153 +        memcpy(result, msg, msgLen * U_SIZEOF_UCHAR);
   1.154 +        memcpy(result + msgLen, gNoFormatting, resultLength);
   1.155 +        resultLength += msgLen;
   1.156 +        uprint(result, resultLength, fp, &err);
   1.157 +    } else {
   1.158 +        uprint(msg,msgLen, fp, &err);
   1.159 +    }
   1.160 +#else
   1.161 +    va_start(ap, tag);
   1.162 +
   1.163 +    resultLength = u_vformatMessage(uloc_getDefault(), msg, msgLen, result, resultLength, ap, &err);
   1.164 +
   1.165 +    va_end(ap);
   1.166 +
   1.167 +    if(U_FAILURE(err))
   1.168 +    {
   1.169 +#if 0
   1.170 +        fprintf(stderr, "u_wmsg: failed to format %s:%s, err %s\n",
   1.171 +            uloc_getDefault(),
   1.172 +            tag,
   1.173 +            u_errorName(err));
   1.174 +#endif
   1.175 +        err = U_ZERO_ERROR;
   1.176 +        uprint(msg,msgLen, fp, &err);
   1.177 +        return -1;
   1.178 +    }
   1.179 +
   1.180 +    uprint(result, resultLength, fp, &err);
   1.181 +#endif
   1.182 +
   1.183 +    if(U_FAILURE(err))
   1.184 +    {
   1.185 +#if 0
   1.186 +        fprintf(stderr, "u_wmsg: failed to print %s: %s, err %s\n",
   1.187 +            uloc_getDefault(),
   1.188 +            tag,
   1.189 +            u_errorName(err));
   1.190 +#endif
   1.191 +        return -1;
   1.192 +    }
   1.193 +
   1.194 +    return 0;
   1.195 +}
   1.196 +
   1.197 +/* these will break if the # of messages change. simply add or remove 0's .. */
   1.198 +UChar **gInfoMessages = NULL;
   1.199 +
   1.200 +UChar **gErrMessages = NULL;
   1.201 +
   1.202 +static const UChar *fetchErrorName(UErrorCode err)
   1.203 +{
   1.204 +    if (!gInfoMessages) {
   1.205 +        gInfoMessages = (UChar **)malloc((U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*));
   1.206 +        memset(gInfoMessages, 0, (U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*));
   1.207 +    }
   1.208 +    if (!gErrMessages) {
   1.209 +        gErrMessages = (UChar **)malloc(U_ERROR_LIMIT*sizeof(UChar*));
   1.210 +        memset(gErrMessages, 0, U_ERROR_LIMIT*sizeof(UChar*));
   1.211 +    }
   1.212 +    if(err>=0)
   1.213 +        return gErrMessages[err];
   1.214 +    else
   1.215 +        return gInfoMessages[err-U_ERROR_WARNING_START];
   1.216 +}
   1.217 +
   1.218 +U_CFUNC const UChar *u_wmsg_errorName(UErrorCode err)
   1.219 +{
   1.220 +    UChar *msg;
   1.221 +    int32_t msgLen;
   1.222 +    UErrorCode subErr = U_ZERO_ERROR;
   1.223 +    const char *textMsg = NULL;
   1.224 +
   1.225 +    /* try the cache */
   1.226 +    msg = (UChar*)fetchErrorName(err);
   1.227 +
   1.228 +    if(msg)
   1.229 +    {
   1.230 +        return msg;
   1.231 +    }
   1.232 +
   1.233 +    if(gBundle == NULL)
   1.234 +    {
   1.235 +        msg = NULL;
   1.236 +    }
   1.237 +    else
   1.238 +    {
   1.239 +        const char *errname = u_errorName(err);
   1.240 +        if (errname) {
   1.241 +            msg = (UChar*)ures_getStringByKey(gBundle, errname, &msgLen, &subErr);
   1.242 +            if(U_FAILURE(subErr))
   1.243 +            {
   1.244 +                msg = NULL;
   1.245 +            }
   1.246 +        }
   1.247 +    }
   1.248 +
   1.249 +    if(msg == NULL)  /* Couldn't find it anywhere.. */
   1.250 +    {
   1.251 +        char error[128];
   1.252 +        textMsg = u_errorName(err);
   1.253 +        if (!textMsg) {
   1.254 +            sprintf(error, "UNDOCUMENTED ICU ERROR %d", err);
   1.255 +            textMsg = error;
   1.256 +        }
   1.257 +        msg = (UChar*)malloc((strlen(textMsg)+1)*sizeof(msg[0]));
   1.258 +        u_charsToUChars(textMsg, msg, (int32_t)(strlen(textMsg)+1));
   1.259 +    }
   1.260 +
   1.261 +    if(err>=0)
   1.262 +        gErrMessages[err] = msg;
   1.263 +    else
   1.264 +        gInfoMessages[err-U_ERROR_WARNING_START] = msg;
   1.265 +
   1.266 +    return msg;
   1.267 +}

mercurial