static void free_sort_level(struct sort_level *sl) { if (sl) { if (sl->leaves) sort_free(sl->leaves); if (sl->level > 0) sort_free(sl->tosort); if (sl->sublevels) { struct sort_level *slc; size_t sln; sln = sl->sln; for (size_t i = 0; i < sln; ++i) { slc = sl->sublevels[i]; if (slc) free_sort_level(slc); } sort_free(sl->sublevels); } sort_free(sl); } }
/* * Implements random sort (-R). */ static int randomcoll(struct key_value *kv1, struct key_value *kv2, size_t offset) { struct bwstring *s1, *s2; MD5_CTX ctx1, ctx2; char *b1, *b2; UNUSED_ARG(offset); s1 = kv1->k; s2 = kv2->k; if (debug_sort) { bwsprintf(stdout, s1, "; k1=<", ">"); bwsprintf(stdout, s2, ", k2=<", ">"); } if (s1 == s2) return (0); memcpy(&ctx1,&md5_ctx,sizeof(MD5_CTX)); memcpy(&ctx2,&md5_ctx,sizeof(MD5_CTX)); MD5Update(&ctx1, bwsrawdata(s1), bwsrawlen(s1)); MD5Update(&ctx2, bwsrawdata(s2), bwsrawlen(s2)); b1 = MD5End(&ctx1, NULL); b2 = MD5End(&ctx2, NULL); if (b1 == NULL) { if (b2 == NULL) return (0); else { sort_free(b2); return (-1); } } else if (b2 == NULL) { sort_free(b1); return (+1); } else { int cmp_res; cmp_res = strcmp(b1,b2); sort_free(b1); sort_free(b2); if (!cmp_res) cmp_res = bwscoll(s1, s2, 0); return (cmp_res); } }
/* * Pop sort level from the stack (multi-threaded style) */ static inline struct sort_level* pop_ls_mt(void) { struct level_stack *saved_ls; struct sort_level *sl; #if defined(SORT_THREADS) pthread_mutex_lock(&g_ls_mutex); #endif if (g_ls) { sl = g_ls->sl; saved_ls = g_ls; g_ls = g_ls->next; } else { sl = NULL; saved_ls = NULL; } #if defined(SORT_THREADS) pthread_mutex_unlock(&g_ls_mutex); #endif sort_free(saved_ls); return (sl); }
/* * De-allocate object memory */ void bwsfree(const struct bwstring *s) { if (s) sort_free(s); }
int sort_print(sort_link *sort_head,char *data_name) { sort_link *r1 = sort_head,*r2 = NULL; st_info *p1 = NULL; unsigned int i = 0,j = 0; char check; system("cls"); print_tips(" 学生体检信息排序 "); printf(menu_print); while(r1) { ++j; r1 = r1->next; } for (r1 = sort_head->next;r1;r1 = r1->next) { ++i; p1 = r1->sort_point; printf("\n"); printf(STINFO); if(i % flag_page == 0) { print_star(); printf(" Tips:-----数据过多,当前页面可能无法完全显示,请按任意键翻页!"); printf(" \n 共%u页 按S键:更新排序到文件 按ESC键:返回 第%7u 页",j/flag_page + 1,i/flag_page); printf("\r"); if((check = getch()) == 27) { sort_free(sort_head); return 0; } if (check == 's' || check == 'S') { system("cls"); save_file(sort_head,data_name,T_T); getch(); } system("cls"); print_tips(" 学生体检信息排序 "); printf(menu_print); } } printf("\n************************** 输出完毕 ***********************"); sort_free(sort_head); return 1; }
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; } } } }
/* * Set current locale symbols. */ static void set_locale(void) { struct lconv *lc; const char *locale; setlocale(LC_ALL, ""); lc = localeconv(); if (lc) { /* obtain LC_NUMERIC info */ /* Convert to wide char form */ conv_mbtowc(&symbol_decimal_point, lc->decimal_point, symbol_decimal_point); conv_mbtowc(&symbol_thousands_sep, lc->thousands_sep, symbol_thousands_sep); conv_mbtowc(&symbol_positive_sign, lc->positive_sign, symbol_positive_sign); conv_mbtowc(&symbol_negative_sign, lc->negative_sign, symbol_negative_sign); } if (getenv("GNUSORT_NUMERIC_COMPATIBILITY")) gnusort_numeric_compatibility = true; locale = setlocale(LC_COLLATE, NULL); if (locale) { char *tmpl; const char *cclocale; tmpl = sort_strdup(locale); cclocale = setlocale(LC_COLLATE, "C"); if (cclocale && !strcmp(cclocale, tmpl)) byte_sort = true; else { const char *pclocale; pclocale = setlocale(LC_COLLATE, "POSIX"); if (pclocale && !strcmp(pclocale, tmpl)) byte_sort = true; } setlocale(LC_COLLATE, tmpl); sort_free(tmpl); } }
/* * Pop sort level from the stack (single-threaded style) */ static inline struct sort_level* pop_ls_st(void) { struct sort_level *sl; if (g_ls) { struct level_stack *saved_ls; sl = g_ls->sl; saved_ls = g_ls; g_ls = g_ls->next; sort_free(saved_ls); } else sl = NULL; return (sl); }
/* * Pop sort level from the stack (multi-threaded style) */ static inline struct sort_level* pop_ls_mt(void) { struct level_stack *saved_ls; struct sort_level *sl; pthread_mutex_lock(&g_ls_mutex); if (g_ls) { sl = g_ls->sl; saved_ls = g_ls; g_ls = g_ls->next; } else { sl = NULL; saved_ls = NULL; } pthread_mutex_unlock(&g_ls_mutex); sort_free(saved_ls); return (sl); }
/* * Compare a string and a sort list item, according to the sort specs. */ int str_list_coll(struct bwstring *str1, struct sort_list_item **ss2) { struct keys_array *ka1; int ret = 0; ka1 = keys_array_alloc(); preproc(str1, ka1); sort_list_item_make_key(*ss2); if (debug_sort) { bwsprintf(stdout, str1, "; s1=<", ">"); bwsprintf(stdout, (*ss2)->str, ", s2=<", ">"); } ret = key_coll(ka1, &((*ss2)->ka), 0); if (debug_sort) printf("; cmp1=%d", ret); clean_keys_array(str1, ka1); sort_free(ka1); if ((ret == 0) && !(sort_opts_vals.sflag) && sort_opts_vals.complex_sort) { ret = top_level_str_coll(str1, ((*ss2)->str)); if (debug_sort) printf("; cmp2=%d", ret); } if (debug_sort) printf("\n"); return (ret); }
static void run_sort_level_next(struct sort_level *sl) { struct sort_level *slc; size_t i, sln, tosort_num; if (sl->sublevels) { sort_free(sl->sublevels); sl->sublevels = NULL; } switch (sl->tosort_num){ case 0: goto end; case (1): sl->sorted[sl->start_position] = sl->tosort[0]; sort_left_dec(1); goto end; case (2): if (list_coll_offset(&(sl->tosort[0]), &(sl->tosort[1]), sl->level) > 0) { sl->sorted[sl->start_position++] = sl->tosort[1]; sl->sorted[sl->start_position] = sl->tosort[0]; } else { sl->sorted[sl->start_position++] = sl->tosort[0]; sl->sorted[sl->start_position] = sl->tosort[1]; } sort_left_dec(2); goto end; default: if (TINY_NODE(sl) || (sl->level > 15)) { listcoll_t func; func = get_list_call_func(sl->level); sl->leaves = sl->tosort; sl->leaves_num = sl->tosort_num; sl->leaves_sz = sl->leaves_num; sl->leaves = sort_realloc(sl->leaves, (sizeof(struct sort_list_item *) * (sl->leaves_sz))); sl->tosort = NULL; sl->tosort_num = 0; sl->tosort_sz = 0; sl->sln = 0; sl->real_sln = 0; if (sort_opts_vals.sflag) { if (mergesort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) func) == -1) /* NOTREACHED */ err(2, "Radix sort error 3"); } else qsort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) func); memcpy(sl->sorted + sl->start_position, sl->leaves, sl->leaves_num * sizeof(struct sort_list_item*)); sort_left_dec(sl->leaves_num); goto end; } else { sl->tosort_sz = sl->tosort_num; sl->tosort = sort_realloc(sl->tosort, sizeof(struct sort_list_item*) * (sl->tosort_sz)); } } sl->sln = 256; sl->sublevels = sort_malloc(slsz); memset(sl->sublevels, 0, slsz); sl->real_sln = 0; tosort_num = sl->tosort_num; for (i = 0; i < tosort_num; ++i) place_item(sl, i); sort_free(sl->tosort); sl->tosort = NULL; sl->tosort_num = 0; sl->tosort_sz = 0; if (sl->leaves_num > 1) { if (keys_num > 1) { if (sort_opts_vals.sflag) { mergesort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) list_coll); } else { qsort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) list_coll); } } else if (!sort_opts_vals.sflag && sort_opts_vals.complex_sort) { qsort(sl->leaves, sl->leaves_num, sizeof(struct sort_list_item *), (int(*)(const void *, const void *)) list_coll_by_str_only); } } sl->leaves_sz = sl->leaves_num; sl->leaves = sort_realloc(sl->leaves, (sizeof(struct sort_list_item *) * (sl->leaves_sz))); if (!reverse_sort) { memcpy(sl->sorted + sl->start_position, sl->leaves, sl->leaves_num * sizeof(struct sort_list_item*)); sl->start_position += sl->leaves_num; sort_left_dec(sl->leaves_num); sort_free(sl->leaves); sl->leaves = NULL; sl->leaves_num = 0; sl->leaves_sz = 0; sln = sl->sln; for (i = 0; i < sln; ++i) { slc = sl->sublevels[i]; if (slc) { slc->sorted = sl->sorted; slc->start_position = sl->start_position; sl->start_position += slc->tosort_num; if (SMALL_NODE(slc)) run_sort_level_next(slc); else push_ls(slc); sl->sublevels[i] = NULL; } } } else { size_t n; sln = sl->sln; for (i = 0; i < sln; ++i) { n = sln - i - 1; slc = sl->sublevels[n]; if (slc) { slc->sorted = sl->sorted; slc->start_position = sl->start_position; sl->start_position += slc->tosort_num; if (SMALL_NODE(slc)) run_sort_level_next(slc); else push_ls(slc); sl->sublevels[n] = NULL; } } memcpy(sl->sorted + sl->start_position, sl->leaves, sl->leaves_num * sizeof(struct sort_list_item*)); sort_left_dec(sl->leaves_num); } end: free_sort_level(sl); }