gen_collate_from_glibc.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Generator collate table from glibc special for Uclibc.
  3. * Author Vladimir Oleynik. vodz@usa.net (c) 2001
  4. *
  5. * Require setuped work non-C LC_COLLATE
  6. * This programm created ./LOCALE/LC_COLLATE file for Uclibc
  7. * setlocale() and strcoll().
  8. * Without argument this programm used setlocale(LC_COLLATE, "") -
  9. * equivalent result setlocale(LC_COLLATE, getenv("LC_XXX"))
  10. *
  11. * Also, this programm have russian koi8 collate for test
  12. * working Uclibc ;-)
  13. *
  14. */
  15. #include <ctype.h>
  16. #include <string.h>
  17. #include <locale.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <unistd.h>
  21. #include <sys/stat.h> /* mkdir() */
  22. #include <errno.h>
  23. /* For strong test russian locale LC_COLLATE="ru_RU.KOI8-R" */
  24. static const unsigned char koi8_weights[256] = {
  25. 0, 99, 100, 101, 102, 103, 104, 105,
  26. 106, 2, 5, 3, 6, 4, 107, 108,
  27. 109, 110, 111, 112, 113, 114, 115, 116,
  28. 117, 118, 119, 120, 121, 122, 123, 124,
  29. 1, 12, 21, 34, 30, 35, 33, 20,
  30. 22, 23, 31, 36, 9, 8, 15, 14,
  31. 127, 128, 129, 131, 132, 133, 134, 135,
  32. 136, 137, 11, 10, 38, 40, 42, 13,
  33. 29, 138, 140, 142, 144, 146, 148, 150,
  34. 152, 154, 156, 158, 160, 162, 164, 166,
  35. 168, 170, 172, 174, 176, 178, 180, 182,
  36. 184, 186, 188, 24, 32, 25, 17, 7,
  37. 16, 139, 141, 143, 145, 147, 149, 151,
  38. 153, 155, 157, 159, 161, 163, 165, 167,
  39. 169, 171, 173, 175, 177, 179, 181, 183,
  40. 185, 187, 189, 26, 43, 27, 18, 125,
  41. 50, 52, 54, 58, 62, 66, 70, 74,
  42. 78, 82, 86, 90, 91, 92, 93, 94,
  43. 95, 96, 97, 48, 98, 45, 46, 47,
  44. 39, 41, 126, 49, 44, 130, 19, 37,
  45. 51, 53, 55, 203, 56, 57, 59, 60,
  46. 61, 63, 64, 65, 67, 68, 69, 71,
  47. 72, 73, 75, 202, 76, 77, 79, 80,
  48. 81, 83, 84, 85, 87, 88, 89, 28,
  49. 253, 191, 193, 237, 199, 201, 233, 197,
  50. 235, 209, 211, 213, 215, 217, 219, 221,
  51. 223, 255, 225, 227, 229, 231, 205, 195,
  52. 249, 247, 207, 241, 251, 243, 239, 245,
  53. 252, 190, 192, 236, 198, 200, 232, 196,
  54. 234, 208, 210, 212, 214, 216, 218, 220,
  55. 222, 254, 224, 226, 228, 230, 204, 194,
  56. 248, 246, 206, 240, 250, 242, 238, 244
  57. };
  58. int gen_weights(const char *collate)
  59. {
  60. int weights[256];
  61. int i,j;
  62. char probe_str1[2];
  63. char probe_str2[2];
  64. char print_buf[16];
  65. int retcode = 0;
  66. unsigned char out_weights[256];
  67. FILE *out;
  68. memset(weights, 0, sizeof(weights));
  69. probe_str1[1]=probe_str2[1]=0;
  70. for(i=0; i<256; i++) {
  71. probe_str1[0] = i;
  72. for(j=0; j<256; j++) {
  73. probe_str2[0] = j;
  74. if(strcoll(probe_str1, probe_str2)>0) {
  75. weights[i]++;
  76. if(i==j) {
  77. fprintf(stderr, "\
  78. \nWarning! c1=%d == c2, but strcoll returned greater zero\n", i);
  79. retcode++;
  80. }
  81. }
  82. }
  83. }
  84. for(i=0; i<256; ) {
  85. if(isprint(i))
  86. sprintf(print_buf, " '%c'", i);
  87. else {
  88. if(i=='\0')
  89. strcpy(print_buf, "'\\0'");
  90. else if(i=='\a')
  91. strcpy(print_buf, "'\\a'");
  92. else if(i=='\b')
  93. strcpy(print_buf, "'\\b'");
  94. else if(i=='\f')
  95. strcpy(print_buf, "'\\f'");
  96. else if(i=='\r')
  97. strcpy(print_buf, "'\\r'");
  98. else if(i=='\t')
  99. strcpy(print_buf, "'\\t'");
  100. else sprintf(print_buf, " x%02X", i);
  101. }
  102. printf("weights[%s] = %3d ", print_buf, weights[i]);
  103. i++;
  104. if( (i%4) == 0)
  105. printf("\n");
  106. }
  107. for(i=0; i<256; i++) {
  108. if(weights[i]<0 || weights[i]>=256) {
  109. fprintf(stderr, "Hmm, weights[%d]=%d\n", i, weights[i]);
  110. retcode++;
  111. }
  112. for(j=0; j<256; j++) {
  113. if(i==j)
  114. continue;
  115. if(weights[i]==weights[j]) {
  116. fprintf(stderr, "\
  117. Warning! c1=%d c2=%d and strcoll returned equivalent weight\n", i, j);
  118. retcode++;
  119. }
  120. }
  121. }
  122. if(retcode)
  123. return 1;
  124. if(strcasecmp(collate, "ru_RU.KOI8-R")==0 ||
  125. strcmp(collate, "ru_RU")==0 ||
  126. strcmp(collate, "koi8-r")==0) {
  127. for(i=0; i<256; i++)
  128. if(weights[i]!=koi8_weights[i]) {
  129. fprintf(stderr, "\
  130. Error koi8-r collate compare, glibc weights[%d]=%d but current generation %d\n",
  131. i, koi8_weights[i], weights[i]);
  132. retcode++;
  133. }
  134. if(retcode)
  135. return 5;
  136. }
  137. for(i=0; i<256; i++)
  138. out_weights[i] = weights[i];
  139. out = fopen("LC_COLLATE", "w");
  140. if(out == NULL) {
  141. fprintf(stderr, "Can`t create ./%s/LC_COLLATE file\n", collate);
  142. return 10;
  143. }
  144. if(fwrite(out_weights, 1, 256, out)!=256) {
  145. fprintf(stderr, "IO error in process write ./%s/LC_COLLATE file\n", collate);
  146. return 11;
  147. }
  148. return 0;
  149. }
  150. int main(int argc, char **argv)
  151. {
  152. char *locale;
  153. char *slr;
  154. char *collate;
  155. if(argc<1 || argc>2) {
  156. fprintf(stderr, "Usage: %s [locale]\n", argv[0]);
  157. }
  158. locale = argc==1 ? "" : argv[1];
  159. collate = setlocale(LC_COLLATE, locale);
  160. fprintf(stderr, "setlocale(LC_COLLATE, \"%s\") returned %s\n", locale, collate);
  161. if(collate==0) {
  162. fprintf(stderr, "Can`t set LC_COLLATE\n");
  163. return 2;
  164. }
  165. if(strcmp(collate, "C")==0) {
  166. fprintf(stderr, "\
  167. LC_COLLATE=\"C\" is trivial and not interesting for this programm\n");
  168. return 3;
  169. }
  170. slr = setlocale(LC_CTYPE, locale);
  171. fprintf(stderr, "setlocale(LC_CTYPE, \"%s\") returned %s\n", locale, slr);
  172. if(slr==0) {
  173. slr = setlocale(LC_CTYPE, "POSIX");
  174. if(slr==0) {
  175. fprintf(stderr, "Hmm, can`t set setlocale(LC_CTYPE, \"POSIX\")\n");
  176. return 4;
  177. }
  178. }
  179. if(mkdir(collate, 0755)!=0 && errno!=EEXIST) {
  180. fprintf(stderr, "Can`t make directory %s\n", collate);
  181. return 6;
  182. }
  183. if(chdir(collate)) {
  184. fprintf(stderr, "Hmm, can`t change directory to %s\n", collate);
  185. return 7;
  186. }
  187. if(gen_weights(collate)) {
  188. if(chdir("..")) {
  189. fprintf(stderr, "Hmm, can`t change to current directory\n");
  190. return 7;
  191. }
  192. rmdir(collate);
  193. return 1;
  194. }
  195. return 0;
  196. }