~ubuntu-branches/ubuntu/trusty/python3.3/trusty

« back to all changes in this revision

Viewing changes to Modules/_decimal/_decimal.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-19 08:46:55 UTC
  • mfrom: (22.1.15 sid)
  • Revision ID: package-import@ubuntu.com-20131119084655-pueqfadzs5v1xf53
Tags: 3.3.3-1
* Python 3.3.3 release.
* Update to 20131119 from the 3.3 branch.
* Regenerate the patches.
* Update the symbols files.
* Fix test support when the running kernel doesn't handle port reuse.
* libpython3.3-minimal replaces libpython3.3-stdlib (<< 3.2.3-7).
  Closes: #725240.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3096
3096
    return res;
3097
3097
}
3098
3098
 
 
3099
/* Return a duplicate of src, copy embedded null characters. */
 
3100
static char *
 
3101
dec_strdup(const char *src, Py_ssize_t size)
 
3102
{
 
3103
    char *dest = PyMem_Malloc(size+1);
 
3104
    if (dest == NULL) {
 
3105
        return NULL;
 
3106
    }
 
3107
 
 
3108
    memcpy(dest, src, size);
 
3109
    dest[size] = '\0';
 
3110
    return dest;
 
3111
}
 
3112
 
 
3113
static void
 
3114
dec_replace_fillchar(char *dest)
 
3115
{
 
3116
     while (*dest != '\0') {
 
3117
         if (*dest == '\xff') *dest = '\0';
 
3118
         dest++;
 
3119
     }
 
3120
}
 
3121
 
3099
3122
/* Convert decimal_point or thousands_sep, which may be multibyte or in
3100
3123
   the range [128, 255], to a UTF8 string. */
3101
3124
static PyObject *
3131
3154
    PyObject *dot = NULL;
3132
3155
    PyObject *sep = NULL;
3133
3156
    PyObject *grouping = NULL;
3134
 
    PyObject *fmt = NULL;
3135
3157
    PyObject *fmtarg;
3136
3158
    PyObject *context;
3137
3159
    mpd_spec_t spec;
3138
 
    char *decstring= NULL;
 
3160
    char *fmt;
 
3161
    char *decstring = NULL;
3139
3162
    uint32_t status = 0;
3140
 
    size_t n;
 
3163
    int replace_fillchar = 0;
 
3164
    Py_ssize_t size;
3141
3165
 
3142
3166
 
3143
3167
    CURRENT_CONTEXT(context);
3146
3170
    }
3147
3171
 
3148
3172
    if (PyUnicode_Check(fmtarg)) {
3149
 
        fmt = PyUnicode_AsUTF8String(fmtarg);
 
3173
        fmt = PyUnicode_AsUTF8AndSize(fmtarg, &size);
3150
3174
        if (fmt == NULL) {
3151
3175
            return NULL;
3152
3176
        }
 
3177
        if (size > 0 && fmt[0] == '\0') {
 
3178
            /* NUL fill character: must be replaced with a valid UTF-8 char
 
3179
               before calling mpd_parse_fmt_str(). */
 
3180
            replace_fillchar = 1;
 
3181
            fmt = dec_strdup(fmt, size);
 
3182
            if (fmt == NULL) {
 
3183
                return NULL;
 
3184
            }
 
3185
            fmt[0] = '_';
 
3186
        }
3153
3187
    }
3154
3188
    else {
3155
3189
        PyErr_SetString(PyExc_TypeError,
3157
3191
        return NULL;
3158
3192
    }
3159
3193
 
3160
 
    if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt),
3161
 
                           CtxCaps(context))) {
 
3194
    if (!mpd_parse_fmt_str(&spec, fmt, CtxCaps(context))) {
3162
3195
        PyErr_SetString(PyExc_ValueError,
3163
3196
            "invalid format string");
3164
3197
        goto finish;
3165
3198
    }
 
3199
    if (replace_fillchar) {
 
3200
        /* In order to avoid clobbering parts of UTF-8 thousands separators or
 
3201
           decimal points when the substitution is reversed later, the actual
 
3202
           placeholder must be an invalid UTF-8 byte. */
 
3203
        spec.fill[0] = '\xff';
 
3204
        spec.fill[1] = '\0';
 
3205
    }
 
3206
 
3166
3207
    if (override) {
3167
3208
        /* Values for decimal_point, thousands_sep and grouping can
3168
3209
           be explicitly specified in the override dict. These values
3199
3240
        }
3200
3241
    }
3201
3242
    else {
3202
 
        n = strlen(spec.dot);
 
3243
        size_t n = strlen(spec.dot);
3203
3244
        if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) {
3204
3245
            /* fix locale dependent non-ascii characters */
3205
3246
            dot = dotsep_as_utf8(spec.dot);
3231
3272
        }
3232
3273
        goto finish;
3233
3274
    }
3234
 
    result = PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL);
 
3275
    size = strlen(decstring);
 
3276
    if (replace_fillchar) {
 
3277
        dec_replace_fillchar(decstring);
 
3278
    }
 
3279
 
 
3280
    result = PyUnicode_DecodeUTF8(decstring, size, NULL);
3235
3281
 
3236
3282
 
3237
3283
finish:
3238
3284
    Py_XDECREF(grouping);
3239
3285
    Py_XDECREF(sep);
3240
3286
    Py_XDECREF(dot);
3241
 
    Py_XDECREF(fmt);
 
3287
    if (replace_fillchar) PyMem_Free(fmt);
3242
3288
    if (decstring) mpd_free(decstring);
3243
3289
    return result;
3244
3290
}
4423
4469
            goto malloc_error;
4424
4470
        }
4425
4471
        else {
4426
 
            PyErr_SetString(PyExc_RuntimeError,
4427
 
                "dec_hash: internal error: please report");
 
4472
            PyErr_SetString(PyExc_RuntimeError, /* GCOV_NOT_REACHED */
 
4473
                "dec_hash: internal error: please report"); /* GCOV_NOT_REACHED */
4428
4474
        }
4429
 
        result = -1;
 
4475
        result = -1; /* GCOV_NOT_REACHED */
4430
4476
    }
4431
4477
 
4432
4478
 
5577
5623
        }
5578
5624
 
5579
5625
        if (base == NULL) {
5580
 
            goto error;
 
5626
            goto error; /* GCOV_NOT_REACHED */
5581
5627
        }
5582
5628
 
5583
5629
        ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL));
5609
5655
            base = PyTuple_Pack(1, signal_map[0].ex);
5610
5656
        }
5611
5657
        if (base == NULL) {
5612
 
            goto error;
 
5658
            goto error; /* GCOV_NOT_REACHED */
5613
5659
        }
5614
5660
 
5615
5661
        ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL));