home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / ausay / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  7.6 KB  |  442 lines

  1. #include <stdio.h>
  2. #include <audio/audiolib.h>
  3. #include <audio/soundlib.h>
  4. #include <ctype.h>
  5.  
  6. extern     AuServer    aud;
  7.  
  8. #ifdef LIBSPEAK
  9. #ifdef getc
  10. #undef getc
  11. #endif    /* getc */
  12. #define getc(FP)    hacked_getc(FP)
  13. #endif    /* LIBSPEAK */
  14.  
  15. #define MAX_LENGTH 128
  16.  
  17. #ifdef LIBSPEAK
  18. FILE           *In_file;
  19. FILE           *Out_file;
  20. #else
  21. static FILE    *In_file;
  22. static FILE    *Out_file;
  23. #endif    /* LIBSPEAK */
  24.  
  25. static int      Char, Char1, Char2, Char3;
  26.  
  27. #ifndef LIBSPEAK
  28. /*
  29.  * * main(argc, argv) *    int argc; *    char *argv[]; *
  30.  * 
  31.  *    This is the main program.  It takes up to two file names (input *
  32.  * and output)  and translates the input file to phoneme codes *    (see
  33.  * ENGLISH.C) on the output file.
  34.  */
  35. main(argc, argv)
  36.     int             argc;
  37.     char           *argv[];
  38. {
  39.     if (argc > 3)
  40.     {
  41.         fputs("Usage: PHONEME [infile [outfile]]\n", stderr);
  42.         exit();
  43.     }
  44.  
  45.     if (argc == 1)
  46.     {
  47.         fputs("Enter english text:\n", stderr);
  48.     }
  49.  
  50.     if (argc > 1)
  51.     {
  52.         In_file = fopen(argv[1], "r");
  53.         if (In_file == 0)
  54.         {
  55.             fputs("Error: Cannot open input file.\n", stderr);
  56.             fputs("Usage: PHONEME [infile [outfile]]\n", stderr);
  57.             exit();
  58.         }
  59.     }
  60.     else
  61.         In_file = stdin;
  62.  
  63.     if (argc > 2)
  64.     {
  65.         Out_file = fopen(argv[2], "w");
  66.         if (Out_file == 0)
  67.         {
  68.             fputs("Error: Cannot create output file.\n", stderr);
  69.             fputs("Usage: PHONEME [infile [outfile]]\n", stderr);
  70.             exit();
  71.         }
  72.     }
  73.     else
  74.         Out_file = stdout;
  75.  
  76.     xlate_file();
  77. }
  78. #endif    /* LIBSPEAK */
  79.  
  80. outstring(string)
  81.     char           *string;
  82. {
  83. #ifdef LIBSPEAK
  84.     phoneme_str_to_audio(string);
  85. #else
  86.     while (*string != '\0')
  87.         outchar(*string++);
  88. #endif
  89. }
  90.  
  91. #ifndef LIBSPEAK
  92. outchar(chr)
  93.     int             chr;
  94. {
  95.     fputc(chr, Out_file);
  96. }
  97. #endif    /* LIBSPEAK */
  98.  
  99.  
  100. int 
  101. makeupper(character)
  102.     int             character;
  103. {
  104.     if (islower(character))
  105.         return toupper(character);
  106.     else
  107.         return character;
  108. }
  109.  
  110. new_char()
  111. {
  112.     /*
  113.      * If the cache is full of newline, time to prime the look-ahead
  114.      * again.  If an EOF is found, fill the remainder of the queue with
  115.      * EOF's.
  116.      */
  117.     if (Char == '\n' && Char1 == '\n' && Char2 == '\n' && Char3 == '\n')
  118.     {            /* prime the pump again */
  119.         Char = getc(In_file);
  120.         if (Char == EOF)
  121.         {
  122.             Char1 = EOF;
  123.             Char2 = EOF;
  124.             Char3 = EOF;
  125.             return Char;
  126.         }
  127.         if (Char == '\n')
  128.             return Char;
  129.  
  130.         Char1 = getc(In_file);
  131.         if (Char1 == EOF)
  132.         {
  133.             Char2 = EOF;
  134.             Char3 = EOF;
  135.             return Char;
  136.         }
  137.         if (Char1 == '\n')
  138.             return Char;
  139.  
  140.         Char2 = getc(In_file);
  141.         if (Char2 == EOF)
  142.         {
  143.             Char3 = EOF;
  144.             return Char;
  145.         }
  146.         if (Char2 == '\n')
  147.             return Char;
  148.  
  149.         Char3 = getc(In_file);
  150.     }
  151.     else
  152.     {
  153.         /*
  154.          * Buffer not full of newline, shuffle the characters and
  155.          * either get a new one or propagate a newline or EOF.
  156.          */
  157.         Char = Char1;
  158.         Char1 = Char2;
  159.         Char2 = Char3;
  160.         if (Char3 != '\n' && Char3 != EOF)
  161.             Char3 = getc(In_file);
  162.     }
  163.     return Char;
  164. }
  165.  
  166. /*
  167.  * * xlate_file() *
  168.  * 
  169.  *    This is the input file translator.  It sets up the first character *
  170.  * and uses it to determine what kind of text follows.
  171.  */
  172. xlate_file()
  173. {
  174.     /* Prime the queue */
  175.     Char = '\n';
  176.     Char1 = '\n';
  177.     Char2 = '\n';
  178.     Char3 = '\n';
  179.     new_char();        /* Fill Char, Char1, Char2 and Char3 */
  180.  
  181.     while (Char != EOF)    /* All of the words in the file */
  182.     {
  183.         if (isdigit(Char))
  184.             have_number();
  185.         else if (isalpha(Char) || Char == '\'')
  186.             have_letter();
  187.         else if (Char == '$' && isdigit(Char1))
  188.             have_dollars();
  189.         else
  190.             have_special();
  191.     }
  192. }
  193.  
  194. have_dollars()
  195. {
  196.     long int        value;
  197.  
  198.     value = 0L;
  199.     for (new_char(); isdigit(Char) || Char == ','; new_char())
  200.     {
  201.         if (Char != ',')
  202.             value = 10 * value + (Char - '0');
  203.     }
  204.  
  205.     say_cardinal(value);    /* Say number of whole dollars */
  206.  
  207.     /* Found a character that is a non-digit and non-comma */
  208.  
  209.     /* Check for no decimal or no cents digits */
  210.     if (Char != '.' || !isdigit(Char1))
  211.     {
  212.         if (value == 1L)
  213.             outstring("dAAlER ");
  214.         else
  215.             outstring("dAAlAArz ");
  216.         return;
  217.     }
  218.  
  219.     /* We have '.' followed by a digit */
  220.  
  221.     new_char();        /* Skip the period */
  222.  
  223.     /* If it is ".dd " say as " DOLLARS AND n CENTS " */
  224.     if (isdigit(Char1) && !isdigit(Char2))
  225.     {
  226.         if (value == 1L)
  227.             outstring("dAAlER ");
  228.         else
  229.             outstring("dAAlAArz ");
  230.         if (Char == '0' && Char1 == '0')
  231.         {
  232.             new_char();    /* Skip tens digit */
  233.             new_char();    /* Skip units digit */
  234.             return;
  235.         }
  236.  
  237.         outstring("AAnd ");
  238.         value = (Char - '0') * 10 + Char1 - '0';
  239.         say_cardinal(value);
  240.  
  241.         if (value == 1L)
  242.             outstring("sEHnt ");
  243.         else
  244.             outstring("sEHnts ");
  245.         new_char();    /* Used Char (tens digit) */
  246.         new_char();    /* Used Char1 (units digit) */
  247.         return;
  248.     }
  249.  
  250.     /* Otherwise say as "n POINT ddd DOLLARS " */
  251.  
  252.     outstring("pOYnt ");
  253.     for (; isdigit(Char); new_char())
  254.     {
  255.         say_ascii(Char);
  256.     }
  257.  
  258.     outstring("dAAlAArz ");
  259.  
  260.     return;
  261. }
  262.  
  263. have_special()
  264. {
  265. #ifndef LIBSPEAK
  266.     if (Char == '\n')
  267.         outchar('\n');
  268.     else
  269. #endif
  270.     if (!isspace(Char))
  271.         say_ascii(Char);
  272.  
  273.     new_char();
  274.     return;
  275. }
  276.  
  277.  
  278. have_number()
  279. {
  280.     long int        value;
  281.     int             lastdigit;
  282.  
  283.     value = Char - '0';
  284.     lastdigit = Char;
  285.  
  286.     for (new_char(); isdigit(Char); new_char())
  287.     {
  288.         value = 10 * value + (Char - '0');
  289.         lastdigit = Char;
  290.     }
  291.  
  292.     /* Recognize ordinals based on last digit of number */
  293.     switch (lastdigit)
  294.     {
  295.     case '1':        /* ST */
  296.         if (makeupper(Char) == 'S' && makeupper(Char1) == 'T' &&
  297.             !isalpha(Char2) && !isdigit(Char2))
  298.         {
  299.             say_ordinal(value);
  300.             new_char();    /* Used Char */
  301.             new_char();    /* Used Char1 */
  302.             return;
  303.         }
  304.         break;
  305.  
  306.     case '2':        /* ND */
  307.         if (makeupper(Char) == 'N' && makeupper(Char1) == 'D' &&
  308.             !isalpha(Char2) && !isdigit(Char2))
  309.         {
  310.             say_ordinal(value);
  311.             new_char();    /* Used Char */
  312.             new_char();    /* Used Char1 */
  313.             return;
  314.         }
  315.         break;
  316.  
  317.     case '3':        /* RD */
  318.         if (makeupper(Char) == 'R' && makeupper(Char1) == 'D' &&
  319.             !isalpha(Char2) && !isdigit(Char2))
  320.         {
  321.             say_ordinal(value);
  322.             new_char();    /* Used Char */
  323.             new_char();    /* Used Char1 */
  324.             return;
  325.         }
  326.         break;
  327.  
  328.     case '0':        /* TH */
  329.     case '4':        /* TH */
  330.     case '5':        /* TH */
  331.     case '6':        /* TH */
  332.     case '7':        /* TH */
  333.     case '8':        /* TH */
  334.     case '9':        /* TH */
  335.         if (makeupper(Char) == 'T' && makeupper(Char1) == 'H' &&
  336.             !isalpha(Char2) && !isdigit(Char2))
  337.         {
  338.             say_ordinal(value);
  339.             new_char();    /* Used Char */
  340.             new_char();    /* Used Char1 */
  341.             return;
  342.         }
  343.         break;
  344.     }
  345.  
  346.     say_cardinal(value);
  347.  
  348.     /* Recognize decimal points */
  349.     if (Char == '.' && isdigit(Char1))
  350.     {
  351.         outstring("pOYnt ");
  352.         for (new_char(); isdigit(Char); new_char())
  353.         {
  354.             say_ascii(Char);
  355.         }
  356.     }
  357.  
  358.     /* Spell out trailing abbreviations */
  359.     if (isalpha(Char))
  360.     {
  361.         while (isalpha(Char))
  362.         {
  363.             say_ascii(Char);
  364.             new_char();
  365.         }
  366.     }
  367.  
  368.     return;
  369. }
  370.  
  371.  
  372. have_letter()
  373. {
  374.     char            buff[MAX_LENGTH];
  375.     int             count;
  376.  
  377.     count = 0;
  378.     buff[count++] = ' ';    /* Required initial blank */
  379.  
  380.     buff[count++] = makeupper(Char);
  381.  
  382.     for (new_char(); isalpha(Char) || Char == '\''; new_char())
  383.     {
  384.         buff[count++] = makeupper(Char);
  385.         if (count > MAX_LENGTH - 2)
  386.         {
  387.             buff[count++] = ' ';
  388.             buff[count++] = '\0';
  389.             xlate_word(buff);
  390.             count = 1;
  391.         }
  392.     }
  393.  
  394.     buff[count++] = ' ';    /* Required terminating blank */
  395.     buff[count++] = '\0';
  396.  
  397.     /* Check for AAANNN type abbreviations */
  398.     if (isdigit(Char))
  399.     {
  400.         spell_word(buff);
  401.         return;
  402.     }
  403.     else if (strlen(buff) == 3)    /* one character, two spaces */
  404.         say_ascii(buff[1]);
  405.     else if (Char == '.')    /* Possible abbreviation */
  406.         abbrev(buff);
  407.     else
  408.         xlate_word(buff);
  409.  
  410.     if (Char == '-' && isalpha(Char1))
  411.         new_char();    /* Skip hyphens */
  412.  
  413. }
  414.  
  415. /* Handle abbreviations.  Text in buff was followed by '.' */
  416. abbrev(buff)
  417.     char            buff[];
  418. {
  419.     if (strcmp(buff, " DR ") == 0)
  420.     {
  421.         xlate_word(" DOCTOR ");
  422.         new_char();
  423.     }
  424.     else if (strcmp(buff, " MR ") == 0)
  425.     {
  426.         xlate_word(" MISTER ");
  427.         new_char();
  428.     }
  429.     else if (strcmp(buff, " MRS ") == 0)
  430.     {
  431.         xlate_word(" MISSUS ");
  432.         new_char();
  433.     }
  434.     else if (strcmp(buff, " PHD ") == 0)
  435.     {
  436.         spell_word(" PHD ");
  437.         new_char();
  438.     }
  439.     else
  440.         xlate_word(buff);
  441. }
  442.