home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / mtools_3.6.src.lzh / MTOOLS_3.6 / codepage.c < prev    next >
C/C++ Source or Header  |  1997-11-14  |  4KB  |  222 lines

  1. #include "sysincludes.h"
  2. #include "mtools.h"
  3. #include "codepage.h"
  4.  
  5.  
  6. Codepage_t *Codepage=0;
  7. char *mstoupper=0;
  8.  
  9.  
  10. #undef WORD
  11. #define WORD(x,y) (file[(x)+2*(y)] + (file[(x)+1+2*(y)] << 8))
  12.  
  13. #define COUNTRY(x) WORD(25+(x)*14, 1)
  14. #define CODEPAGE(x) WORD(25+(x)*14, 2)
  15. #define DATA(x) WORD(25+(x)*14, 5)
  16. #define CTYINFO(x) WORD(DATA(x), 3)
  17. #define CTYINFOCP(x) WORD(CTYINFO(x), 6)
  18. #define UCASE(x) WORD(DATA(x), 11)
  19. #define UCASEBYTE file[ucase+10+j*8+k]
  20.  
  21. #define NBVARS(x) WORD(DATA(x), 0)
  22. #define VARID(x,y) WORD(DATA(x), y*4+2)
  23. #define VARVAL(x,y) WORD(DATA(x), y*4+3)
  24.  
  25. static void bad_country_file(void)
  26. {
  27.     fprintf(stderr,"Corrupted country.sys file\n");
  28.     exit(1);
  29. }
  30.  
  31. static void not_found(int country_found, int country, int codepage)
  32. {
  33.     if(!country_found)
  34.         fprintf(stderr,"Country code %03d not supported\n",
  35.             country);
  36.     else    
  37.         fprintf(stderr,"Country/codepage combo %03d/%d not supported\n",
  38.             country, codepage);
  39.     exit(1);
  40. }
  41.  
  42.  
  43. static short get_variable(unsigned char *file, int i, int id)
  44. {
  45.     int j;
  46.  
  47.     for(j=0; j < NBVARS(i); j++)
  48.         if(VARID(i,j) == id)
  49.             return VARVAL(i,j);
  50.     return 0;
  51. }
  52.  
  53.  
  54. static void set_toupper_from_builtin(int country, int *codepage)
  55. {
  56.     country_t *p;
  57.     int country_found = 0;
  58.  
  59.     if(mstoupper)
  60.         return;
  61.     for(p = countries; p->country; p++) {
  62.         if(p->country == country) {
  63.             country_found = 1;
  64.             if(!*codepage)
  65.                 *codepage = p->default_codepage;
  66.             if (p->codepage == *codepage) {
  67.                 mstoupper = (char *) toucase[p->to_upper];
  68.                 return;
  69.             }
  70.         }
  71.     }
  72.     not_found(country_found, country, *codepage);
  73. }
  74.  
  75.  
  76. static void load_toupper(int country, int *codepage, char *filename)
  77. {
  78.     int fd, filesize;
  79.     unsigned char *file;
  80.     unsigned short ucase=0, records;
  81.     int i;
  82.     int country_found = 0;
  83.     struct stat buf;
  84.  
  85.     if(!filename) {
  86.         set_toupper_from_builtin(country, codepage);
  87.         return;
  88.     }
  89.  
  90.     fd = open(filename, O_RDONLY);
  91.     if(fd < 0) {
  92.         perror("open country.sys");
  93.         exit(1);
  94.     }
  95.  
  96.     fstat(fd, &buf);
  97.     file = (unsigned char *) malloc(buf.st_size);
  98.     if(!file) {
  99.         fprintf(stderr, "Out of memory\n");
  100.         exit(1);
  101.     }
  102.  
  103.     /* load country.sys */
  104.     filesize=read(fd, (char *) file, 65536);
  105.     if(filesize < 0) {
  106.         perror("Read country.sys\n");
  107.         exit(1);
  108.     }
  109.     close(fd);
  110.     
  111.     if(strcmp((char *)file, "\377COUNTRY"))
  112.         bad_country_file();
  113.  
  114.     records = WORD(23,0);    
  115.  
  116.     /* second pass: locate translation table */
  117.     for(i=0; i<records; i++) {
  118.         if(country == COUNTRY(i)) {
  119.             country_found = 1;
  120.             if(!*codepage)
  121.                 *codepage = get_variable(file, i, 1);
  122.             if(mstoupper)
  123.                 continue;
  124.             if(*codepage == CODEPAGE(i)) {
  125.                 ucase = get_variable(file, i, 4);
  126.                 if(!ucase) {
  127.                     fprintf(stderr,
  128.                         "No translation table for this"
  129.                         "country and code page\n");
  130.                     exit(1);
  131.                 }
  132.                 if(strncmp((char*)file+ucase+1, "UCASE", 5) &&
  133.                    strncmp((char*)file+ucase+1, "FUCASE", 6))
  134.                     bad_country_file();
  135.                 mstoupper = (char *) toucase[0];
  136.                 memcpy(mstoupper, file + ucase + 10, 128);
  137.                 free(file);
  138.                 return;
  139.             }
  140.         }
  141.     }
  142.     not_found(country_found, country, *codepage);
  143.     free(file);
  144. }
  145.  
  146. static void set_codepage(int nr)
  147. {
  148.     if(Codepage)
  149.         return;
  150.     for(Codepage = codepages; Codepage->nr; Codepage++)
  151.         if(Codepage->nr == nr)
  152.             return;
  153.     fprintf(stderr,"Unknown code page %d\n", nr);
  154.     exit(1);
  155.  
  156. }
  157.  
  158.  
  159. static void syntax(void)
  160. {
  161.     fprintf(stderr,"Syntax error in COUNTRY environmental variable\n");
  162.     fprintf(stderr,"Usage: export COUNTRY=countrycode[,[codepage][,filename]]\n");
  163.     exit(1);
  164. }
  165.  
  166. void init_codepage(void)
  167. {
  168.     char *country, *file;
  169.     int country_prefix;
  170.     int codepage;
  171.  
  172.     file = 0;
  173.     country=country_string;
  174.     if(!country) {
  175.         codepage = 850;
  176.         country_prefix = 41; /* Switzerland */
  177.     } else {
  178.         file = 0;
  179.         codepage = 0;
  180.         country_prefix = strtoul(country, &country, 10);
  181.         if(!country_prefix)
  182.             syntax();
  183.         if(*country==',') {
  184.             country++;
  185.             codepage = strtoul(country, &country,10);
  186.             if(*country==',') {
  187.                 file = country+1;
  188.             } else if (*country)
  189.                 syntax();
  190.         } else if(*country)
  191.             syntax();
  192.     }    
  193.  
  194.     load_toupper(country_prefix, &codepage, file);
  195.     set_codepage(codepage);
  196. }
  197.  
  198. unsigned char to_dos(unsigned char c)
  199. {
  200.     int oc;
  201.  
  202.     if(c < 0x80)
  203.         return c;
  204.     for(oc = 0 ; oc < 128; oc++) {
  205.         if(c == Codepage->tounix[oc])
  206.             return oc | 0x80;
  207.     }
  208.     return '_';
  209. }
  210.  
  211.  
  212. void to_unix(char *a, int n)
  213. {
  214.     for( ; *a && n >= 0; n--, a++) {
  215.         /* special case, 0xE5 */
  216.         if(*a == 0x05)
  217.             *a = DELMARK;
  218.         if(*a & 0x80)
  219.             *a = (char) Codepage->tounix[(*a) & 0x7f];
  220.     }
  221. }
  222.