home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume21 / kdrill / part01 / readfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-07  |  7.0 KB  |  342 lines

  1. /*
  2.  * This file is for just setting up the structs, etc
  3.  */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <Xfuncs.h>
  9. #include <Xlib.h>
  10. #include <Xatom.h>
  11. #include <Xutil.h>
  12. #include <Intrinsic.h>
  13. #include <StringDefs.h>
  14. #include <Xos.h>
  15.  
  16. #include "defs.h"
  17. #include "externs.h"
  18.  
  19. /* translations[] keeps track of which kanji it is okay to test the
  20.  *    user on. Likewise with numberofkanji, highest, and lowest.
  21.  *    YES, it is best to keep in a large array, otherwise
  22.  *    it would be difficult to switch between grade levels.
  23.  */
  24. struct translationstruct *translations[0x8000];
  25. int numberofkanji,highest,lowest;
  26.  
  27.  
  28. /* random debugging util? */
  29. void printline(s)
  30. unsigned char *s;
  31. {
  32.     while(*s){
  33.         putchar(*s++);
  34.     }
  35.     putchar('\n');
  36. }
  37.  
  38. /* Since there is no standard util to convert hex ascii to int,...
  39.  *  have to supply our own..
  40.  *  It isn't incredibly efficient.. let's hope the compiler is smart.
  41.  *  arrg..
  42.  */
  43. int xtoi(s)
  44. char * s;
  45. {
  46.     int out=0;
  47.     sscanf(s,"%x",&out);
  48.     return out;
  49. }
  50.  
  51. /* getline:
  52.  *    reads a line (from dictionary).
  53.  *    returns true (1) if read aline, otherwise,
  54.  *    returns false (0);
  55.  *
  56.  *    used in "readstructs", below.
  57.  */
  58.  
  59. unsigned char instring[2][512];
  60. unsigned char *inptr=NULL;
  61. int whichstring;
  62.  
  63. int getline(fp,s)
  64. FILE *fp;
  65. unsigned char *s;
  66. {
  67.     if(inptr==NULL){
  68.         inptr= &instring[0][100];
  69.         whichstring=0;
  70.     }
  71.     for(;;){
  72.         int i;
  73.         if(inptr == &instring[whichstring][100]){
  74.             whichstring = 1-whichstring;
  75.             inptr=instring[whichstring];
  76.             i=fread(instring[whichstring],1,100,fp);
  77.             if(i<100){
  78.                 instring[whichstring][i]='\0';
  79.                 /* okay, we put the termination signal in.
  80.                  * But if there is a complete line in there,
  81.                  * it should be read with our buffering
  82.                  */
  83.             }
  84.         }
  85.         switch(*inptr){
  86.             case 0:
  87.                 *s = '\0';
  88.                 return 0;
  89.             case 10:
  90.             case 13:
  91.                 *inptr='\0';
  92.                 *s++ = *inptr++;
  93.                 return 1;
  94.             default:
  95.                 *s++ = *inptr++;
  96.         }
  97.     }
  98. }
  99.  
  100. /* nextword:
  101.  *    Goes to first whitespace, then sets pointer to
  102.  *    beginning of non-white-space.
  103.  *
  104.  *    Returns 1 on success, 0 on fail
  105.  */
  106. int nextword(stringp)
  107. char ** stringp;
  108. {
  109.     while(!isspace(**stringp)){
  110.         if(stringp == '\0')
  111.             return 0;
  112.         *stringp +=1;
  113.     }
  114.     /* now on space */
  115.     while(isspace(**stringp)){
  116.         if(stringp == '\0')
  117.             return 0;
  118.         *stringp +=1;
  119.     }
  120.     return 1;
  121.     
  122. }
  123.  
  124. /* nextchar:
  125.  * returns pointer to next non-whitespace char
  126. */
  127. unsigned char *nextchar(c)
  128. unsigned char *c;
  129. {
  130.     while(isspace(*c)){
  131.         if(*c == '\0') break;
  132.         c++;
  133.     }
  134.     return c;
  135. }
  136.  
  137. /* StripBrackets:
  138.  *    Gets rid of those annoying {enlish}{english2} brackets.
  139.  *    PRESUMES first char of source is '{'!!
  140.  *      Well, actually, it nicely sets a null string if otherwise.
  141.  */
  142. void StripBrackets(dest,source)
  143. char *dest,*source;
  144. {
  145.     char *parse = &source[1];
  146.  
  147.     if(source[0] != '{'){
  148.         dest[0] = '\0';
  149.         return;
  150.     }
  151.     /* (*dest) is always assumed to be needing a write */
  152.  
  153.     do {
  154.         switch(*parse){
  155.             case '{':
  156.                 *dest++ = ':';
  157.                 *dest++ = ' ';
  158.                 break;
  159.             case '}':
  160.                 break;
  161.             default:
  162.                 *dest++ = *parse;                
  163.         }
  164.         parse++;
  165.     } while((*parse != '\n') && (*parse != '\0'));
  166.     *dest = '\0';
  167.     return;
  168. }
  169.  
  170.  
  171. /* Okay, it's not actually pronunciation we're reading.
  172.  * We are reading the "no-yoni" and "kun-yoni" interpretation
  173.  * in kanjidic
  174.  */
  175. void ReadPronunciation(Pstring,kanjinum)
  176. int kanjinum;
  177. char **Pstring;
  178. {
  179.     XChar2b kanabuffer[256];
  180.     XChar2b *pronunciation;
  181.     int pronun_len;
  182.     unsigned char *parse = (unsigned char *) *Pstring;
  183.  
  184.     pronunciation = kanabuffer;
  185.     /* "bad" job here.. this is just to get things working..
  186.      * this method will probably skip a few kana
  187.      */
  188.  
  189.     if(*parse == '{'){
  190.         /* only english exists, so set to null */
  191.         translations[kanjinum] == NULL;
  192.         return;
  193.     }
  194.     
  195.     while((*parse > 127) && (*parse != '\0')){
  196.         /* kanjidic seems to have high bit set on
  197.          * Kana.. which we need to strip both of!!
  198.          */
  199.         pronunciation->byte1= (*parse++ & 0x7f);
  200.         pronunciation->byte2= (*parse++ & 0x7f);
  201.         pronunciation++;
  202.         /* skip space, and put in divider if
  203.          * second reading is there
  204.          */
  205.         while(*parse == ' ') {
  206.             parse++;
  207.             if(*parse == '\0')
  208.                 break;
  209.             if(*parse >127){
  210.                pronunciation->byte1 = 0x21;
  211.                pronunciation->byte2 = 0x27;
  212.                pronunciation++;
  213.             }
  214.         }
  215.     }
  216.     pronunciation->byte1=pronunciation->byte2 = 0;
  217.     pronun_len = strlen((char *) kanabuffer);
  218.  
  219.     translations[kanjinum]->pronunciation =
  220.         (XChar2b *) malloc(pronun_len+4);
  221.     if(translations[kanjinum]->pronunciation == NULL){
  222.         fprintf(stderr,"Not enough memory to read in dictionary\n");
  223.         exit(0);
  224.     }
  225.     strncpy(translations[kanjinum]->pronunciation, kanabuffer, pronun_len+1);
  226.  
  227.     /* now position parse pointer for next step:
  228.      *  reading english
  229.      */
  230.     while(*parse != '{'){
  231.         if(*parse == '\0'){
  232.             return;
  233.         }
  234.         parse++;
  235.     }
  236.  
  237.     *Pstring = (char *)parse;
  238. }
  239.  
  240. /* readstructs:
  241.  *    the main dictionary reading routine.
  242.  *    Fills in the global translationstruct with
  243.  *    all that is available for each selected kanji, in
  244.  *    Grade, "pronunciation", english translation, and
  245.  *    frequency of use (by native speakers)
  246.  */
  247. void readstructs(){
  248.     unsigned char instring[256];
  249.     FILE *fp;
  250.  
  251.     lowest = highest = 0x3000;
  252.     fp = fopen(dictname,"r");
  253.     if(fp == NULL){
  254.         perror("cannot open kanji translation file");
  255.         fprintf(stderr,"Looking for %s\n",dictname);
  256.         exit(0);
  257.     }
  258.  
  259.     while (getline(fp,instring) != 0) {
  260.         int Kanji;
  261.         int freq,grade;
  262.         unsigned char *parse;
  263.         int instrlen;    /* length of pronunciation */
  264.  
  265.         if(strlen(instring) <10) continue;
  266.  
  267.         /*try to get kanji Index right away */
  268.         Kanji = xtoi(&instring[2]);
  269.  
  270.  
  271.         /* skip comments, and kanji not specified in
  272.          * the usefile
  273.          */    
  274.         if( (Kanji < 0x3000) || (translations[Kanji] != NULL) ){
  275.             continue;
  276.         }
  277.  
  278.         parse = &instring[2];
  279.         if(parse == NULL){
  280.             continue;
  281.         }
  282.         /* now parse for grade level, frequency, and english */
  283.         freq = grade = 0;
  284.  
  285.         nextword(&parse);
  286.         /* check for high bit set, which means
  287.          * start of kana definition of kana
  288.          */
  289.         /* used to have (*parse != '{')  */
  290.         while ( (*parse < 127)  && (*parse != '{') ) {
  291.             
  292.             switch(*parse){
  293.                 case 'G':
  294.                     grade = atoi(++parse);
  295.                     break;
  296.                 case 'F':
  297.                     freq = atoi(++parse);
  298.                     break;
  299.                 default:
  300.                     break;
  301.             }
  302.             nextword(&parse);
  303.         }
  304.         
  305.         
  306.         /**********************************************
  307.          *  Now we know that we have a useable/wanted *
  308.          *  dictionary definition                     *
  309.          *********************************************/
  310.  
  311.         if(Kanji<lowest) lowest = Kanji;
  312.         if (Kanji >highest) highest = Kanji;
  313.         
  314.         translations[Kanji] = (struct translationstruct *)
  315.             malloc(sizeof(struct translationstruct));
  316.         if (translations[Kanji] == NULL){
  317.             perror("Cannot allocate memory for translation table\n");
  318.             exit(errno);
  319.         }
  320.         translations[Kanji]->frequency = freq;
  321.         translations[Kanji]->grade_level = grade;
  322.  
  323.         ReadPronunciation(&parse,Kanji);
  324.         /*
  325.          * translations[Kanji]->pronunciation[0].byte1=0;
  326.          * translations[Kanji]->pronunciation[0].byte2=0;
  327.          */
  328.  
  329.  
  330.         instrlen = strlen(parse)+1;
  331.         translations[Kanji]->english = (char *) malloc(instrlen);
  332.         if(translations[Kanji]->english == NULL){
  333.             perror("Cannot allocate memory for translation table\n");
  334.             exit(errno);        
  335.         }
  336.  
  337.         StripBrackets(translations[Kanji]->english,parse);
  338.  
  339.     } /* and repeat until end of file */
  340. }
  341.  
  342.