gen_ctype_from_glibc.c 5.3 KB

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