gen_ctype_from_glibc.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * Generator locale ctype tables
  3. * You must have already setuped locale for worked libc (libc5 or glibc)
  4. *
  5. * This programm scan /usr/share/locale directories and write
  6. * ./LOCALE/LC_CTYPE files for system with uclibc
  7. *
  8. * Written by Vladimir Oleynik <vodz@usa.net> 2001
  9. * Base on ideas Nickolay Saukh <nms@ussr.EU.net>
  10. *
  11. */
  12. #include <locale.h>
  13. #include <ctype.h>
  14. #include <stdio.h>
  15. #include <dirent.h>
  16. #include <sys/stat.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <getopt.h>
  20. #include <unistd.h>
  21. #include <errno.h>
  22. #include "../../libc/misc/locale/_locale.h"
  23. #define DEFAULT_LOCALE_DIR "/usr/share/locale/"
  24. #define DEF_OUT_NAME "LC_CTYPE"
  25. #define CURRENT_SUPPORT_MAX (LOCALE_BUF_SIZE/2)
  26. unsigned char x2type[CURRENT_SUPPORT_MAX];
  27. unsigned char x2trans[CURRENT_SUPPORT_MAX];
  28. int
  29. write_out (outname)
  30. unsigned char *outname;
  31. {
  32. FILE *ofp = fopen (outname, "w");
  33. if (ofp == NULL) {
  34. fprintf (stderr, "Can`t write `%s\n", outname);
  35. return 1;
  36. }
  37. fwrite (x2type, sizeof (x2type), 1, ofp);
  38. fwrite (x2trans, sizeof (x2trans), 1, ofp);
  39. fclose (ofp);
  40. return 0;
  41. }
  42. typedef struct bbits_ {
  43. int bbits;
  44. char *bb_name;
  45. } bbits_t;
  46. bbits_t basic_bits[] =
  47. {
  48. {ISprint , "ISprint" },
  49. {ISupper , "ISupper" },
  50. {ISlower , "ISlower" },
  51. {IScntrl , "IScntrl" },
  52. {ISspace , "ISspace" },
  53. {ISpunct , "ISpunct" },
  54. {ISalpha , "ISalpha" },
  55. {ISxdigit, "ISxdigit"},
  56. {0, NULL}
  57. };
  58. void
  59. ctab_out (char *oun)
  60. {
  61. int i;
  62. char *outname;
  63. FILE *fout;
  64. outname = alloca(strlen(oun)+strlen("ctype_.c")+1);
  65. if(outname==0) {
  66. perror("");
  67. exit(1);
  68. }
  69. strcpy(outname, "ctype_");
  70. strcat(outname, oun);
  71. strcat(outname, ".c");
  72. fout = fopen (outname, "w");
  73. if (fout == NULL)
  74. {
  75. perror ("");
  76. return;
  77. }
  78. fprintf (fout, "const unsigned char _uc_ctype_b_C[LOCALE_BUF_SIZE] = {\n");
  79. for (i = 0; i < CURRENT_SUPPORT_MAX; i++)
  80. {
  81. if(i)
  82. fprintf (fout, ",\n");
  83. fprintf (fout, "\t/* 0x%02x, %d, 0%o */\t", i, i, i);
  84. if (x2type[i])
  85. {
  86. int dirty = 0;
  87. bbits_t *tb = basic_bits;
  88. while (tb->bbits)
  89. {
  90. if (x2type[i] & tb->bbits)
  91. {
  92. if (dirty)
  93. fputs ("|", fout);
  94. fputs (tb->bb_name, fout);
  95. dirty = 1;
  96. }
  97. tb++;
  98. }
  99. }
  100. else
  101. fputs ("0", fout);
  102. }
  103. fputs (",\n\n", fout);
  104. fprintf (fout, "/* _uc_ctype_trans_C */\n\n");
  105. for (i = 0; i < CURRENT_SUPPORT_MAX; i++)
  106. {
  107. if(i)
  108. fprintf (fout, ",\n");
  109. fprintf (fout, "\t/* 0x%02x, %d, 0%o */\t0x%02x", i, i, i, x2trans[i]);
  110. }
  111. fputs ("\n};\n", fout);
  112. (void) fclose (fout);
  113. }
  114. int
  115. main (int argc, char *argv[])
  116. {
  117. int i,l;
  118. char *outname = DEF_OUT_NAME;
  119. char *search_dir = DEFAULT_LOCALE_DIR;
  120. char *full_path = 0;
  121. DIR *dir;
  122. struct dirent *next;
  123. char *t;
  124. int err=0;
  125. char *ln;
  126. int generate_c_code = 1;
  127. while ((i = getopt (argc, argv, "d:o:c")) != EOF) {
  128. switch (i) {
  129. case 'o':
  130. outname = optarg;
  131. break;
  132. case 'd':
  133. search_dir = optarg;
  134. break;
  135. case 'c':
  136. generate_c_code = 0;
  137. break;
  138. default:
  139. optind = i = -1;
  140. break;
  141. }
  142. if(i<0)
  143. break;
  144. }
  145. if (argc > optind) {
  146. fprintf (stderr,
  147. "Usage: %s [-d search_dir] [-o output_name] [-c]\n\
  148. Defaults:\n\
  149. search_dir : " DEFAULT_LOCALE_DIR "\n\
  150. output_name : " DEF_OUT_NAME "\n\
  151. -c : no generate c-code for other locale exept C-locale.\n"
  152. , argv[0]);
  153. return 3;
  154. }
  155. l = strlen(search_dir);
  156. if(l == 0) {
  157. search_dir = "./";
  158. l = 2;
  159. } else {
  160. if(search_dir[l-1]!='/') {
  161. t = malloc(l+2);
  162. if(t==0) {
  163. fprintf (stderr, "Can`t get %d bytes memory\n", l+2);
  164. return 4;
  165. }
  166. search_dir = strcat(strcpy(t, search_dir), "/");
  167. l++;
  168. }
  169. }
  170. dir = opendir(search_dir);
  171. if (!dir) {
  172. fprintf (stderr, "Can`t open directory `%s' load all locales\n", search_dir);
  173. return 2;
  174. }
  175. while ((next = readdir(dir)) != NULL) {
  176. struct stat st;
  177. if(strcmp(next->d_name, ".")==0)
  178. ln = "C";
  179. else if(strcmp(next->d_name, "..")==0)
  180. continue;
  181. else {
  182. ln = next->d_name;
  183. full_path = realloc(full_path, l+strlen(ln)+1);
  184. strcat(strcpy(full_path, search_dir), ln);
  185. if (lstat(full_path, &st) < 0)
  186. continue;
  187. if(S_ISDIR(st.st_mode)==0)
  188. continue;
  189. }
  190. t = setlocale(LC_CTYPE, ln);
  191. printf("setlocale(LC_CTYPE, %s) returned %s\n", ln, t);
  192. if(t==0)
  193. continue;
  194. if(mkdir(ln, 0755)!=0 && errno!=EEXIST) {
  195. fprintf(stderr, "Can`t create directory `%s'\n", ln);
  196. continue;
  197. }
  198. if(chdir(ln)) {
  199. fprintf(stderr, "Can`t change directory to `%s'\n", ln);
  200. continue;
  201. }
  202. for (i = 0; i < CURRENT_SUPPORT_MAX; i++) {
  203. if(isprint(i))
  204. x2type[i] |= ISprint;
  205. if(isupper(i))
  206. x2type[i] |= ISupper;
  207. if(islower(i))
  208. x2type[i] |= ISlower;
  209. if(isspace(i))
  210. x2type[i] |= ISspace;
  211. if(isalpha(i))
  212. x2type[i] |= ISalpha;
  213. if(iscntrl(i))
  214. x2type[i] |= IScntrl;
  215. if(ispunct(i))
  216. x2type[i] |= ISpunct;
  217. if(isxdigit(i))
  218. x2type[i] |= ISxdigit;
  219. x2trans[i] = i;
  220. if(toupper(x2trans[i]) != x2trans[i])
  221. x2trans[i] = toupper(x2trans[i]);
  222. else if(tolower(x2trans[i]) != x2trans[i])
  223. x2trans[i] = tolower(x2trans[i]);
  224. }
  225. err += write_out(outname);
  226. if(chdir("..")) {
  227. fprintf(stderr, "Can`t change directory to `..'\n");
  228. return 1;
  229. }
  230. if(strcmp(ln, "C")==0 || generate_c_code!=0)
  231. ctab_out(ln);
  232. for (i = 0; i < CURRENT_SUPPORT_MAX; i++)
  233. x2type[i] = x2trans[i] = 0;
  234. }
  235. return err ? 1 : 0;
  236. }