/* * Copy content of src binary string to dst, * with specified number of symbols to be copied. * An offset value can be specified, from the start of src string. * If the capacity of the dst string is not sufficient, * then the data is truncated. */ struct bwstring * bwsnocpy(struct bwstring *dst, const struct bwstring *src, size_t offset, size_t size) { if (offset >= src->len) { dst->data.wstr[0] = 0; dst->len = 0; } else { size_t nums = src->len - offset; if (nums > dst->len) nums = dst->len; if (nums > size) nums = size; dst->len = nums; if (MB_CUR_MAX == 1) { memcpy(dst->data.cstr, src->data.cstr + offset, (nums)); dst->data.cstr[dst->len] = '\0'; } else { memcpy(dst->data.wstr, src->data.wstr + offset, SIZEOF_WCHAR_STRING(nums)); dst->data.wstr[dst->len] = L'\0'; } } return (dst); }
size_t bws_memsize(const struct bwstring *bws) { return ((MB_CUR_MAX == 1) ? (bws->len + 2 + sizeof(struct bwstring)) : (SIZEOF_WCHAR_STRING(bws->len + 1) + sizeof(struct bwstring))); }
int bwsncmp(const struct bwstring *bws1, const struct bwstring *bws2, size_t offset, size_t len) { size_t cmp_len, len1, len2; int res = 0; cmp_len = 0; len1 = bws1->len; len2 = bws2->len; if (len1 <= offset) { return ((len2 <= offset) ? 0 : -1); } else { if (len2 <= offset) return (+1); else { len1 -= offset; len2 -= offset; cmp_len = len1; if (len2 < cmp_len) cmp_len = len2; if (len < cmp_len) cmp_len = len; if (MB_CUR_MAX == 1) { const unsigned char *s1, *s2; s1 = bws1->data.cstr + offset; s2 = bws2->data.cstr + offset; res = memcmp(s1, s2, cmp_len); } else { const wchar_t *s1, *s2; s1 = bws1->data.wstr + offset; s2 = bws2->data.wstr + offset; res = memcmp(s1, s2, SIZEOF_WCHAR_STRING(cmp_len)); } } } if (res == 0) { if (len1 < cmp_len && len1 < len2) res = -1; else if (len2 < cmp_len && len2 < len1) res = +1; } return (res); }
void initialise_months(void) { const nl_item item[12] = { ABMON_1, ABMON_2, ABMON_3, ABMON_4, ABMON_5, ABMON_6, ABMON_7, ABMON_8, ABMON_9, ABMON_10, ABMON_11, ABMON_12 }; unsigned char *tmp; size_t len; if (MB_CUR_MAX == 1) { if (cmonths == NULL) { unsigned char *m; cmonths = sort_malloc(sizeof(unsigned char*) * 12); for (int i = 0; i < 12; i++) { cmonths[i] = NULL; tmp = (unsigned char *) nl_langinfo(item[i]); if (debug_sort) printf("month[%d]=%s\n", i, tmp); if (*tmp == '\0') continue; m = sort_strdup(tmp); len = strlen(tmp); for (unsigned int j = 0; j < len; j++) m[j] = toupper(m[j]); cmonths[i] = m; } } } else { if (wmonths == NULL) { wchar_t *m; wmonths = sort_malloc(sizeof(wchar_t *) * 12); for (int i = 0; i < 12; i++) { wmonths[i] = NULL; tmp = (unsigned char *) nl_langinfo(item[i]); if (debug_sort) printf("month[%d]=%s\n", i, tmp); if (*tmp == '\0') continue; len = strlen(tmp); m = sort_malloc(SIZEOF_WCHAR_STRING(len + 1)); if (mbstowcs(m, (char*)tmp, len) == ((size_t) - 1)) { sort_free(m); continue; } m[len] = L'\0'; for (unsigned int j = 0; j < len; j++) m[j] = towupper(m[j]); wmonths[i] = m; } } } }
/* * Create a copy of binary string. * New string size equals the length of the old string. */ struct bwstring * bwsdup(const struct bwstring *s) { if (s == NULL) return (NULL); else { struct bwstring *ret = bwsalloc(s->len); if (MB_CUR_MAX == 1) memcpy(ret->data.cstr, s->data.cstr, (s->len)); else memcpy(ret->data.wstr, s->data.wstr, SIZEOF_WCHAR_STRING(s->len)); return (ret); } }
/* * Allocate a new binary string of specified size */ struct bwstring * bwsalloc(size_t sz) { struct bwstring *ret; if (MB_CUR_MAX == 1) ret = sort_malloc(sizeof(struct bwstring) + 1 + sz); else ret = sort_malloc(sizeof(struct bwstring) + SIZEOF_WCHAR_STRING(sz + 1)); ret->len = sz; if (MB_CUR_MAX == 1) ret->data.cstr[ret->len] = '\0'; else ret->data.wstr[ret->len] = L'\0'; return (ret); }
/* * Copy content of src binary string to dst. * If the capacity of the dst string is not sufficient, * then the data is truncated. */ size_t bwscpy(struct bwstring *dst, const struct bwstring *src) { size_t nums = src->len; if (nums > dst->len) nums = dst->len; dst->len = nums; if (MB_CUR_MAX == 1) { memcpy(dst->data.cstr, src->data.cstr, nums); dst->data.cstr[dst->len] = '\0'; } else { memcpy(dst->data.wstr, src->data.wstr, SIZEOF_WCHAR_STRING(nums + 1)); dst->data.wstr[dst->len] = L'\0'; } return (nums); }
/* * Create a new binary string from a raw binary buffer. */ struct bwstring * bwssbdup(const wchar_t *str, size_t len) { if (str == NULL) return ((len == 0) ? bwsalloc(0) : NULL); else { struct bwstring *ret; ret = bwsalloc(len); if (MB_CUR_MAX == 1) for (size_t i = 0; i < len; ++i) ret->data.cstr[i] = (unsigned char) str[i]; else memcpy(ret->data.wstr, str, SIZEOF_WCHAR_STRING(len)); return (ret); } }
/* * Allocate and read a binary string from file. * The strings are nl-ended or zero-ended, depending on the sort setting. */ struct bwstring * bwsfgetln(FILE *f, size_t *len, bool zero_ended, struct reader_buffer *rb) { wint_t eols; eols = zero_ended ? btowc('\0') : btowc('\n'); if (!zero_ended && (MB_CUR_MAX > 1)) { wchar_t *ret; ret = fgetwln(f, len); if (ret == NULL) { if (!feof(f)) err(2, NULL); return (NULL); } if (*len > 0) { if (ret[*len - 1] == (wchar_t)eols) --(*len); } return (bwssbdup(ret, *len)); } else if (!zero_ended && (MB_CUR_MAX == 1)) { char *ret; ret = fgetln(f, len); if (ret == NULL) { if (!feof(f)) err(2, NULL); return (NULL); } if (*len > 0) { if (ret[*len - 1] == '\n') --(*len); } return (bwscsbdup((unsigned char*)ret, *len)); } else { *len = 0; if (feof(f)) return (NULL); if (2 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, sizeof(wchar_t) * rb->fgetwln_z_buffer_size); } rb->fgetwln_z_buffer[*len] = 0; if (MB_CUR_MAX == 1) while (!feof(f)) { int c; c = fgetc(f); if (c == EOF) { if (*len == 0) return (NULL); goto line_read_done; } if (c == eols) goto line_read_done; if (*len + 1 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, SIZEOF_WCHAR_STRING(rb->fgetwln_z_buffer_size)); } rb->fgetwln_z_buffer[*len] = c; rb->fgetwln_z_buffer[++(*len)] = 0; } else while (!feof(f)) { wint_t c = 0; c = fgetwc(f); if (c == WEOF) { if (*len == 0) return (NULL); goto line_read_done; } if (c == eols) goto line_read_done; if (*len + 1 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, SIZEOF_WCHAR_STRING(rb->fgetwln_z_buffer_size)); } rb->fgetwln_z_buffer[*len] = c; rb->fgetwln_z_buffer[++(*len)] = 0; } line_read_done: /* we do not count the last 0 */ return (bwssbdup(rb->fgetwln_z_buffer, *len)); } }
size_t bwsrawlen(const struct bwstring *bws) { return ((MB_CUR_MAX == 1) ? bws->len : SIZEOF_WCHAR_STRING(bws->len)); }