/* * Generator locale ctype tables * You must have already setuped locale for worked libc (libc5 or glibc) * * This programm scan /usr/share/locale directories and write * ./LOCALE/LC_CTYPE files for system with uclibc * * Written by Vladimir Oleynik 2001 * Base on ideas Nickolay Saukh * */ #include #include #include #include #include #include #include #include #include #include #include "../../libc/misc/locale/_locale.h" #define DEFAULT_LOCALE_DIR "/usr/share/locale/" #define DEF_OUT_NAME "LC_CTYPE" #define CURRENT_SUPPORT_MAX (LOCALE_BUF_SIZE/2) unsigned char x2type[CURRENT_SUPPORT_MAX]; unsigned char x2trans[CURRENT_SUPPORT_MAX]; int write_out (outname) unsigned char *outname; { FILE *ofp = fopen (outname, "w"); if (ofp == NULL) { fprintf (stderr, "Can`t write `%s\n", outname); return 1; } fwrite (x2type, sizeof (x2type), 1, ofp); fwrite (x2trans, sizeof (x2trans), 1, ofp); fclose (ofp); return 0; } typedef struct bbits_ { int bbits; char *bb_name; } bbits_t; bbits_t basic_bits[] = { {ISprint , "ISprint" }, {ISupper , "ISupper" }, {ISlower , "ISlower" }, {IScntrl , "IScntrl" }, {ISspace , "ISspace" }, {ISpunct , "ISpunct" }, {ISalpha , "ISalpha" }, {ISxdigit, "ISxdigit"}, {0, NULL} }; void ctab_out (char *oun) { int i; char *outname; FILE *fout; outname = alloca(strlen(oun)+strlen("ctype_.c")+1); if(outname==0) { perror(""); exit(1); } strcpy(outname, "ctype_"); strcat(outname, oun); strcat(outname, ".c"); fout = fopen (outname, "w"); if (fout == NULL) { perror (""); return; } fprintf (fout, "const unsigned char _uc_ctype_b_C[LOCALE_BUF_SIZE] = {\n"); for (i = 0; i < CURRENT_SUPPORT_MAX; i++) { if(i) fprintf (fout, ",\n"); fprintf (fout, "\t/* 0x%02x, %d, 0%o */\t", i, i, i); if (x2type[i]) { int dirty = 0; bbits_t *tb = basic_bits; while (tb->bbits) { if (x2type[i] & tb->bbits) { if (dirty) fputs ("|", fout); fputs (tb->bb_name, fout); dirty = 1; } tb++; } } else fputs ("0", fout); } fputs (",\n\n", fout); fprintf (fout, "/* _uc_ctype_trans_C */\n\n"); for (i = 0; i < CURRENT_SUPPORT_MAX; i++) { if(i) fprintf (fout, ",\n"); fprintf (fout, "\t/* 0x%02x, %d, 0%o */\t0x%02x", i, i, i, x2trans[i]); } fputs ("\n};\n", fout); (void) fclose (fout); } int main (int argc, char *argv[]) { int i,l; char *outname = DEF_OUT_NAME; char *search_dir = DEFAULT_LOCALE_DIR; char *full_path = 0; DIR *dir; struct dirent *next; char *t; int err=0; char *ln; int generate_c_code = 1; while ((i = getopt (argc, argv, "d:o:c")) != EOF) { switch (i) { case 'o': outname = optarg; break; case 'd': search_dir = optarg; break; case 'c': generate_c_code = 0; break; default: optind = i = -1; break; } if(i<0) break; } if (argc > optind) { fprintf (stderr, "Usage: %s [-d search_dir] [-o output_name] [-c]\n\ Defaults:\n\ search_dir : " DEFAULT_LOCALE_DIR "\n\ output_name : " DEF_OUT_NAME "\n\ -c : no generate c-code for other locale exept C-locale.\n" , argv[0]); return 3; } l = strlen(search_dir); if(l == 0) { search_dir = "./"; l = 2; } else { if(search_dir[l-1]!='/') { t = malloc(l+2); if(t==0) { fprintf (stderr, "Can`t get %d bytes memory\n", l+2); return 4; } search_dir = strcat(strcpy(t, search_dir), "/"); l++; } } dir = opendir(search_dir); if (!dir) { fprintf (stderr, "Can`t open directory `%s' load all locales\n", search_dir); return 2; } while ((next = readdir(dir)) != NULL) { struct stat st; if(strcmp(next->d_name, ".")==0) ln = "C"; else if(strcmp(next->d_name, "..")==0) continue; else { ln = next->d_name; full_path = realloc(full_path, l+strlen(ln)+1); strcat(strcpy(full_path, search_dir), ln); if (lstat(full_path, &st) < 0) continue; if(S_ISDIR(st.st_mode)==0) continue; } t = setlocale(LC_CTYPE, ln); printf("setlocale(LC_CTYPE, %s) returned %s\n", ln, t); if(t==0) continue; if(mkdir(ln, 0755)!=0 && errno!=EEXIST) { fprintf(stderr, "Can`t create directory `%s'\n", ln); continue; } if(chdir(ln)) { fprintf(stderr, "Can`t change directory to `%s'\n", ln); continue; } for (i = 0; i < CURRENT_SUPPORT_MAX; i++) { if(isprint(i)) x2type[i] |= ISprint; if(isupper(i)) x2type[i] |= ISupper; if(islower(i)) x2type[i] |= ISlower; if(isspace(i)) x2type[i] |= ISspace; if(isalpha(i)) x2type[i] |= ISalpha; if(iscntrl(i)) x2type[i] |= IScntrl; if(ispunct(i)) x2type[i] |= ISpunct; if(isxdigit(i)) x2type[i] |= ISxdigit; x2trans[i] = i; if(toupper(x2trans[i]) != x2trans[i]) x2trans[i] = toupper(x2trans[i]); else if(tolower(x2trans[i]) != x2trans[i]) x2trans[i] = tolower(x2trans[i]); } err += write_out(outname); if(chdir("..")) { fprintf(stderr, "Can`t change directory to `..'\n"); return 1; } if(strcmp(ln, "C")==0 || generate_c_code!=0) ctab_out(ln); for (i = 0; i < CURRENT_SUPPORT_MAX; i++) x2type[i] = x2trans[i] = 0; } return err ? 1 : 0; }