banan@butler.UUCP (Mohsen) (01/17/86)
Ipa2sc is a filter that converts International Phonetic Alphabet code to Votrax SC01 phoneme codes. Do what you always do with a shar file and read readme. # The rest of this file is a shell script which will extract: # readme makefile mkp pdtbat getopt.h mbstd.h mbsup.h msc3sup.h rule.h string.h arg_str.c bsearch.c cantopen.c getopt.c ipa2sc.c nl_elim.c prs_str.c sc_rules.c setmode.c strupr.c x_ipa2sc.c bdpdt.bat mkpdt.bat echo x - readme cat >readme <<'!Funky!Stuff!' BACKGROUND: Last April, John A. Wasser posted an English to International Phonetic Alphabet (IPA) program. Let me call John's program eng2ipa. eng2ipa is based on a navy research report done in 1976 (See sc_rules.c). My compliments to Mr. Wasser for eng2ipa. What is to follow (ipa2sc) is designed to work with the output of eng2ipa. It converts IPA codes to Votrax SC01 phoneme codes. The structure of the code is very similar to that of eng2ipa. The tables for the conversion come from the same navy research report. Typical usage would be: "eng2ipa < file.eng | ipa2sc". The code has been minimally tested on BSD4.2 and the IBM-PC (using MSC 3.0 compiler). Ipa2sc is part of a bigger program that I have been working on. I have developed a simple board for the IBM-PC based around the Votrax Chip that takes the phoneme codes and talks (tries to talk). The code to support SC01&IPA local dictionaries will also be posted later. Should you be interested in all of this or the talking board, e-mail me a note or call me at home (206)821-8560. Also, please e-mail me any bugs you find or any enhancements you make. SOFTWARE ORGANIZATION: Ipa2sc is part of a bigger program. That is why the structure of all of this may come across as somewhat funny. mkp is a pre-processor for make. To recreate ipa2sc under unix. Make mkp executable and run it. With an IBM-PC, simply run mkpdt.bat and bdpdt.bat in that order. mkpdt.bat and bdpdt.bat have been created by pdtbat using the makefile. bsearch and getopt are not mine, but the rest is. And Naturally: * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * !Funky!Stuff! echo x - makefile cat >makefile <<'!Funky!Stuff!' # :::::::::::::::::::::::::::::::::::::::::::::::::: # # File: Makefile # Description: Makefile for creating # # This module is the proprietary property of the # Teltone Corporation, copyright 1985, # all rights reserved. # # # Audit Trail: $Log:$ # # $Header: $ # # :::::::::::::::::::::::::::::::::::::::::::::::::: MAKEFILE = makefile PDT = ipa2sc PUB_H = LCL_H = getopt.h mbstd.h mbsup.h msc3sup.h rule.h string.h LCL_C = ipa2sc.c arg_str.c cantopen.c getopt.c nl_elim.c prs_str.c \ setmode.c strupr.c bsearch.c x_ipa2sc.c sc_rules.c C_SRC = ${PUB_H} ${LCL_H} ${LCL_C} OBJS = ipa2sc.o arg_str.o cantopen.o getopt.o nl_elim.o prs_str.o \ setmode.o strupr.o bsearch.o x_ipa2sc.o sc_rules.o # LOADER = ld # $(PDT): $(OBJS) ${LOADER} -M -X -o ${PDT} /lib/crt0.o ${OBJS} -lg -lc # e_make: @echo ${MAKEFILE} e_pub_h: @echo ${PUB_H} e_lcl_h: @echo ${LCL_H} e_lcl_c: @echo ${LCL_C} e_c_src: @echo ${C_SRC} e_objs: @echo ${OBJS} e_libs: @echo ${LIBS} e_pdt: @echo ${PDT} # ctags: ${LCL_C} $(CTAGS) $(LCL_C) # lint: $(LINT) ${LFLAGS} $(LCL_C) depend: mv Makefile Makefile.old sed -n '1,/^# MAKE DEPEND/p' Makefile.old > Makefile /we/sw/cds/avail/common/bin/mkdp -m $(CFILES) >> Makefile # Do not change anything these comments or it will # be lost by the next "make depend" # MAKE DEPEND !Funky!Stuff! echo x - mkp cat >mkp <<'!Funky!Stuff!' #!/bin/csh -f # This is the make pre-processor program written in the 'C' shell. # # mkp defines a group of parameters and passes them to make. # SWITCHES: # -f <filename> # source <filename. priore to invoking make. # If -f is not present and .mkprc exists in the current directory # it is sourced. Otherwise if .mkprc exists in the home directory # it is sourced. # -- # argument parsing is terminated remainder of command line is passed # to make as is. # set MKPFILE=.mkprc set mkpname=$0 set mkpname=$mkpname:t # ### VISIBLE MAKE TOOLS set MAKE=make set CC=cc set AS="as -" set LK="" set LD="" set LINT="lint -u" set REMOVE="rm -f" set CTAGS="ctags -w" # Internal parametrs set BASE = ~/sw set COMMON = ${BASE}/common set COMMON_H_PATH = ${COMMON}/header #set INCFLAGS = "-I. -I${COMMON_H_PATH} -I${BASE}/cd/header" set INCFLAGS = "-I. " # ### VISIBLE MAKE PARAMETERS set CFLAGS = "-gx ${INCFLAGS} -DBSD4_2" set LINTFLAGS = "${INCFLAGS}" set TARGETS # MKP FLAGS set S_MKPFILE # umask 002 # # # Gather command line options # foreach i ($*) switch ($1) case -f: shift argv set S_MKPFILE=$1 breaksw case --: shift argv break default: break breaksw endsw shift argv end # # # # if ("$S_MKPFILE" != "") then set MKPFILE = "$S_MKPFILE" source $MKPFILE else if (-f $MKPFILE) then source $MKPFILE else if (-f $HOME/$MKPFILE) then source $HOME/$MKPFILE endif # set TARGETS="$*" # $MAKE "CC=$CC" "AS=$AS" \ "CFLAGS=$CFLAGS" "LINTFLAGS=$LINTFLAGS" \ "LINT=$LINT" \ "REMOVE=$REMOVE" "CTAGS=$CTAGS" \ $TARGETS set ret=$status if ("$ret" != "0") then exit 1 endif exit 0 !Funky!Stuff! echo x - pdtbat cat >pdtbat <<'!Funky!Stuff!' # rm -f mkpdt.bat rm -f bdpdt.bat set lcl_c = `make e_lcl_c` set pdt = `make e_pdt` set olibs = (`make e_libs`) set tlibs = () set libs = () while ($#olibs > 0) set tlibs = ($tlibs $olibs[1]:t) shift olibs end while ($#tlibs > 0) set libs = ($libs $tlibs[1]:r.lib) shift tlibs end foreach i ($lcl_c) echo cl -c -DMSDOS $i >> mkpdt.bat end echo -n "cl -o $pdt:r " >> bdpdt.bat foreach i ($lcl_c) echo -n "$i:r " >> bdpdt.bat end echo -n " -link " >> bdpdt.bat echo -n " $libs " >> bdpdt.bat echo >> bdpdt.bat exit 0 !Funky!Stuff! echo x - getopt.h cat >getopt.h <<'!Funky!Stuff!' #ifndef GETOPT_H #define GETOPT_H extern char *optarg; extern int optind; extern int getopt(); #endif GETOPT_H !Funky!Stuff! echo x - mbstd.h cat >mbstd.h <<'!Funky!Stuff!' #ifndef MBSTD_H #define MBSTD_H #define CHAR char #define SCHAR char typedef unsigned char UCHAR; #define INT int #define SINT int typedef unsigned int UINT; #define SHORT short #define SSHORT short typedef unsigned short USHORT; #define LONG long #define SLONG long typedef unsigned long ULONG; #define DOUBLE double #define BOOL int #define SUCC_FAIL int #ifndef VOID #define VOID void #endif #define STATIC static /* Names not needed outside this src module */ #define LOCAL /* Names not needed outside this software module */ #define LCL_XTRN extern /* Names defines within this software module */ #define PUBLIC /* Names needed outside this software module */ #define EXTERN extern /* Names defined outside this software module */ #define TRUE 1 #define FALSE 0 #define SUCCESS 0 #define FAIL (-1) #define OOPS() fprintf(stderr,"OOPS: file %s, line %d\n", __FILE__, __LINE__); #endif MBSTD_H !Funky!Stuff! echo x - mbsup.h cat >mbsup.h <<'!Funky!Stuff!' #ifndef MBSUP_H #define MBSUP_H #include "mbstd.h" extern int str2flds(); extern int arg_str(); extern char prs_str(); extern VOID cant_open(); extern VOID nl_elim(); #endif MBSUP_H !Funky!Stuff! echo x - msc3sup.h cat >msc3sup.h <<'!Funky!Stuff!' #ifndef MSC3SUP_H #define MSC3SUP_H #ifdef unix #define O_TEXT 0x4000 #define O_BINARY 0x8000 #endif extern int setmode(); extern char * bsearch(); #endif MSC3SUP_H !Funky!Stuff! echo x - rule.h cat >rule.h <<'!Funky!Stuff!' /*+ * File: * Description: * * * $Header$ * * Audit Trail: $Log$ * -*/ #ifndef RULE_H #define RULE_H typedef struct { CHAR * left; CHAR * match; CHAR * right; CHAR * out; } RULE; /* Context definitions */ static char Anything[] = ""; /* No context requirement */ static char Nothing[] = " "; /* Context is beginning or end of word */ /* Phoneme definitions */ static char Pause[] = " "; /* Short silence */ static char Silent[] = ""; /* No phonemes */ #define E_O_RULE ((CHAR *) 0) #endif !Funky!Stuff! echo x - string.h cat >string.h <<'!Funky!Stuff!' #ifndef STRING_H #define STRING_H #ifdef BSD4_2 #define strchr index #include <strings.h> extern char * strlwr(); extern char * strupr(); extern char * strdup(); #endif #endif STRING_H !Funky!Stuff! echo x - arg_str.c cat >arg_str.c <<'!Funky!Stuff!' /*+ * File: * Description: * * * * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * * Functions: * * * Audit Trail: $Log$ * -*/ #ifdef RCS_VER static char *rcs = "$Header$"; #endif #include "mbstd.h" /*< * Function: str2flds * Description: * Gets an array of arguments from a string * Returned Value: * Number of arguments detected. * * >*/ PUBLIC int str2flds(p_str, flds, maxflds, seps) char **p_str; char *flds[]; /* Where to put the parsed fields */ int maxflds; /* Maximum number of arguments expected */ char * seps; { int argc; char * str; char prs_str(); char sep_fnd; str = *p_str; argc = 0; do { sep_fnd = prs_str(p_str, str, seps); flds[argc++] = str; str = *p_str; } while ((argc < maxflds) && sep_fnd); return argc; } /*< * Function: arg_str * Description: * Gets an array of arguments from a string * Returned Value: * Number of arguments detected. * * >*/ PUBLIC int arg_str(p_str, argv, maxarg) char **p_str; char *argv[]; /* pointer to an array of strings containing the arguments */ int maxarg; /* Maximum number of arguments expected */ { static char blank_sep[] = " "; #if 0 int argc; char * str; char prs_str(); char sep_fnd; str = *p_str; argc = 0; do { sep_fnd = prs_str(p_str, str, blank_sep); argv[argc++] = str; str = *p_str; } while ((argc < maxarg) && sep_fnd); return argc; #endif return (str2flds(p_str, argv, maxarg, blank_sep)); } !Funky!Stuff! echo x - bsearch.c cat >bsearch.c <<'!Funky!Stuff!' char *bsearch(key, base, nelem, width, fcmp) char *key; char *base; register int nelem; int width; int (*fcmp)(); { char *kmin, *probe; int i, j; kmin = base; while (nelem > 0){ i = nelem >> 1; probe = kmin + i * width; j = (*fcmp)(key, probe); if (j == 0) return(probe); else if (j < 0) nelem = i; else { kmin = probe + width; nelem = nelem - i - 1; } } return(0); } !Funky!Stuff! echo x - cantopen.c cat >cantopen.c <<'!Funky!Stuff!' #include "mbstd.h" #include <stdio.h> PUBLIC VOID cant_open (prog_name,filename) char * prog_name; char * filename; { fprintf (stderr, "%s :can not open %s \n", prog_name, filename); } !Funky!Stuff! echo x - getopt.c cat >getopt.c <<'!Funky!Stuff!' /* * getopt - get option letter from argv */ #include <stdio.h> #include <string.h> char *optarg; /* Global argument pointer. */ int optind = 0; /* Global argv index. */ static char *scan = NULL; /* Private scan pointer. */ int getopt(argc, argv, optstring) int argc; char *argv[]; char *optstring; { register char c; register char *place; optarg = NULL; if (scan == NULL || *scan == '\0') { if (optind == 0) optind++; if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') return(EOF); if (strcmp(argv[optind], "--")==0) { optind++; return(EOF); } scan = argv[optind]+1; optind++; } c = *scan++; place = strchr(optstring, c); if (place == NULL || c == ':') { fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); return('?'); } place++; if (*place == ':') { if (*scan != '\0') { optarg = scan; scan = NULL; } else if (optind < argc) { optarg = argv[optind]; optind++; } else { fprintf(stderr, "%s: -%c argument missing\n", argv[0], c); return('?'); } } return(c); } !Funky!Stuff! echo x - ipa2sc.c cat >ipa2sc.c <<'!Funky!Stuff!' /*+ * File: ipa2sc * Description: * ipa2sc is a filter. * ipa2sc processes i_files or the standard input. * ipa2sc writes to o_file or standard output. * * * Usages: * ipa2sc [-t] [-p] [-o] <o_file> <i_files> * * * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * * * Functions: * * * Audit Trail: $Log: dosb2t.c,v $ * Revision 1.1 85/08/28 08:38:24 mohsen * original posting to the net * * * -*/ #ifdef RCS_VER static char *rcs = "$Header: dosb2t.c,v 1.1 85/08/28 08:38:24 mohsen Exp $"; #endif /* #includes */ #include "mbstd.h" #include <stdio.h> #include <ctype.h> #include <fcntl.h> #include <string.h> #ifdef BSD4_2 #include "msc3sup.h" #endif #include "getopt.h" /* #defines */ /* external variables */ /* referenced external function declarations */ /* internal function declarations */ PUBLIC VOID ipa2sc(); STATIC VOID usage(); STATIC int compare(); /* global variables */ /* static variables */ STATIC char * prog_name; /*< * Function: * Description: * * Arguments: * * Returns: * * >*/ INT main (argc, argv) INT argc; CHAR * argv[]; { FILE * i_fp; FILE * o_fp; INT i, c; #define LINE_LENGTH 128 #define WORDS_IN_LINE 128 static char line[LINE_LENGTH]; char * line_var; static char * words[WORDS_IN_LINE]; char word_cnvrt[80]; static char line_cnvrt[256]; int words_cnt; BOOL t_flg = FALSE; /* TALK */ BOOL p_flg = FALSE; /* Print While Talking */ BOOL err_flg = FALSE; #define MAX_IFILES 50 CHAR *ifiles[MAX_IFILES+1], **p_ifile; CHAR *ofile = (CHAR *)0; i_fp = stdin; o_fp = stdout; prog_name = argv[0]; while ((c = getopt(argc, argv, "tTpPo:O:")) != EOF) { switch (c) { case 't': case 'T': t_flg = TRUE; #ifdef HARDWARE ini_st_ppi(); #endif break; case 'p': case 'P': p_flg = TRUE; break; case 'o': case 'O': ofile = optarg; break; case '?': default: err_flg = TRUE; break; } } if (err_flg) { usage(); exit(1); } for (i = 0; (optind < argc) || (i < MAX_IFILES); optind++, i++) { ifiles[i] = argv[optind]; } ifiles[i] = (CHAR *)0; if ( ofile ) { if ( !(o_fp = fopen(ofile, "w")) ) { cant_open (prog_name, ofile); exit (1); } } p_ifile = ifiles; do { if (ifiles[0]) { if (!(i_fp = fopen (*p_ifile, "r"))) { cant_open (prog_name, *p_ifile); exit (1); } } else { /* We are processing STDIN, make sure that this is the last one */ * (p_ifile + 1) = (CHAR *)0; } setmode (fileno(i_fp), O_TEXT); setmode (fileno(o_fp), O_TEXT); while (fgets(line, LINE_LENGTH, i_fp)) { int i; nl_elim(line); line_var = line; words_cnt = arg_str(&line_var, words, WORDS_IN_LINE); line_cnvrt[0] = '\0'; for (i=0; i < words_cnt; ++i) { word_cnvrt[0] = '\0'; x_ipa2sc(words[i], word_cnvrt, 80); if ( t_flg ) { #ifdef HARDWARE sca_say(word_cnvrt); sca_utter("STP"); #endif } strcat(line_cnvrt, word_cnvrt); strcat(line_cnvrt, " "); } /* If t_flag is true and p_flg is false, don't print */ if ( !(t_flg && !p_flg) ) { fputs(line_cnvrt, o_fp); fputc('\n', o_fp); } } fclose (i_fp); } while (*(++p_ifile)); fclose (o_fp); exit (0); } STATIC VOID usage () { fprintf (stderr, "Usage: %s [-t] [-p] [-o] <o_file> <i_files> \n", prog_name); } !Funky!Stuff! echo x - nl_elim.c cat >nl_elim.c <<'!Funky!Stuff!' /*+ * File: * Description: * * * * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * * Functions: * * * Audit Trail: $Log$ * -*/ #ifdef RCS_VER static char *rcs = "$Header$"; #endif /* #includes */ #include "mbstd.h" #include <stdio.h> /*< * Function: * Description: * * Arguments: * * Returns: * * Side Effects: * * Calls: * >*/ PUBLIC VOID nl_elim (iline) char iline[]; { char * cp; cp= &iline[strlen(iline)-1]; if (*cp == '\n') { *cp = '\0'; } } !Funky!Stuff! echo x - prs_str.c cat >prs_str.c <<'!Funky!Stuff!' /*+ * File: * Description: * * * * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * * Functions: * * * Audit Trail: $Log$ * -*/ #ifdef RCS_VER static char *rcs = "$Header$"; #endif /* #includes */ #include "mbstd.h" #include <stdio.h> #include <string.h> /* #defines */ /* external variables */ /* referenced external function declarations */ /* internal function declarations */ /* global variables */ /* static variables */ /*< * Function: prs_str * Description: * Given a a pointer to the input string, prs_str copies contents of * i_str to o_str until any of charachters in p_seps is detected. * -) All initial seperators are ignored. * -)A '\0' is written to o_str instead of the seperator. * -) contents of p_i_str points to the character following the seperator * unless the seperator had been a '\0' in which case p_i_str points to * it. * -) single quote ('\'') is not copied to output, what is enclosed in * single quotes is immune to seperator detection. * * Returns: * detected seperator. * * >*/ PUBLIC char prs_str(p_i_str, o_str, p_seps) char ** p_i_str; /* pointer to input string */ char * o_str; /* pointer to output string */ char * p_seps; { char * i_str; char * p_fnd; char c; i_str = * p_i_str; /* Skipp over initial seperators */ do { if ( (c = *i_str++) == '\0' ) { break; } } while (p_fnd = strchr(p_seps, c)); while ((p_fnd = strchr(p_seps, c)) == NULL) { int completed; switch (c) { case '\'': completed = FALSE; while (c = *i_str++) { if (c == '\'') { completed = TRUE; break; } else { *o_str++ = c; } } if (!completed) { --i_str; fprintf (stderr, "Unmatched \'\n"); } break; default: *o_str++ = c; break; } c = *i_str++; } if ( *p_fnd == '\0') { --i_str; } *o_str = '\0'; *p_i_str = i_str; return (*p_fnd); } !Funky!Stuff! echo x - sc_rules.c cat >sc_rules.c <<'!Funky!Stuff!' /*+ * File: * Description: * * This File contains a set of rules for converting International * Phonetic Alphabet, representation of phonemes, to SC01 Ascii * codes. * The tables had been taken from the * Navy Research Laboratory Report 7948 * Which is distributed as * AD-A021-929 * National Technical Information Service * U.S. Department of Commerce * tel: Info. (703) 487-4600 * tel: order (703) 487-4650 * * *** * DIFFERENCES: * The following changes have been made to NRL report tables: * NX is replaced by NG. * JH is replaced by j. * HH is replaced by h. * This was done (reluctantly) to be compatible with english-to-ipa * program. * * * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * * Functions: * * * Audit Trail: $Log$ * -*/ #ifdef RCS_VER static char *rcs = "$Header$"; #endif /* #includes */ #include "mbstd.h" #include "rule.h" /* internal function declarations */ STATIC int compare(); /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE IY_rule[] = { {Anything, "IY", Anything, "E" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE IH_rule[] = { {Anything, "IH", Anything, "I" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE EY_rule[] = { {"l", "EY", "r", "UH3-A1-I3" }, {"l", "EY", Anything, "UH3-A1-AY" }, {Anything, "EY", "r", "A-I3" }, {Anything, "EY", Anything, "A-AY" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE EH_rule[] = { {"l", "EH", Anything, "UH3-EH" }, {Anything, "EH", Anything, "EH" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE AE_rule[] = { {"l", "AE", "r", "UH3-AE-EH3" }, {"l", "AE", Anything, "UH3-AE" }, {Anything, "AE", "r", "AE1-EH3" }, {Anything, "AE", Anything, "AE" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE AA_rule[] = { {Anything, "AA", Anything, "AH" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE AO_rule[] = { {"l", "AO", "r", "UH3-O" }, {"l", "AO", "ER", "UH3-AW-O2" }, {"l", "AO", Anything, "UH3-AW" }, {Anything, "AO", "r", "O" }, {Anything, "AO", "ER", "AW-O2" }, {Anything, "AO", Anything, "AW" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE OW_rule[] = { {"l", "OW", Anything, "UH3-O1-U1" }, {Anything, "OW", Anything, "O1-U1" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE UH_rule[] = { {"l", "UH", Anything, "UH3-OO" }, {Anything, "UH", Anything, "OO" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE UW_rule[] = { {Anything, "UW", Anything, "IU-U" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE ER_rule[] = { {"IY", "ER", Anything, "I3_ER" }, {"ER", "ER", Anything, "IU-r" }, {"l", "ER", Anything, "UH3-ER" }, {Anything, "ER", "l", "UH3-ER" }, {"r", "ER", Anything, "UH3-r" }, {Anything, "ER", Anything, "ER" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE AX_rule[] = { {Anything, "AX", Anything, "UH2" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE AH_rule[] = { {Anything, "AH", Anything, "UH" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE AY_rule[] = { {Anything, "AY", "l", "AH-AY" }, {Anything, "AY", "r", "AH-I3" }, {Anything, "AY", "ER", "AH-AY" }, {Anything, "AY", Anything, "AH-E1" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE AW_rule[] = { {Anything, "AW", Anything, "AH-O1" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE OY_rule[] = { {"l", "OY", "ER", "UH3-O1-AY" }, {"l", "OY", "l", "UH3-O1-AY" }, {"l", "OY", "r", "UH3-O1-EH2" }, {Anything, "OY", "ER", "O1-AY" }, {Anything, "OY", "l", "O1-AY" }, {Anything, "OY", "r", "O1-EH2" }, {Anything, "OY", Anything, "O1-E1" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE y_rule[] = { {Anything, "y", Anything, "Y" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE p_rule[] = { {Anything, "p", Anything, "P" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE b_rule[] = { {Anything, "b", Anything, "B" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE t_rule[] = { {Anything, "t", Anything, "T" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE d_rule[] = { {Anything, "d", Anything, "D" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE k_rule[] = { {Anything, "k", Anything, "K" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE g_rule[] = { {Anything, "g", Anything, "G" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE f_rule[] = { {Anything, "f", Anything, "F" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE v_rule[] = { {Anything, "v", Anything, "V" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE TH_rule[] = { {Anything, "TH", Anything, "TH" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE DH_rule[] = { {Anything, "DH", Anything, "THV" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE s_rule[] = { {Anything, "s", Anything, "S" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE z_rule[] = { {Anything, "z", Anything, "Z" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE SH_rule[] = { {Anything, "SH", Anything, "SH" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE ZH_rule[] = { {Anything, "ZH", Anything, "ZH" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE h_rule[] = { {Anything, "h", Anything, "H" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE CH_rule[] = { {Anything, "CH", Anything, "T-CH" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE j_rule[] = { {Anything, "j", Anything, "D-J" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE m_rule[] = { {Anything, "m", Anything, "M" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE n_rule[] = { {Anything, "n", Anything, "N" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE NG_rule[] = { {Anything, "NG", Anything, "NG" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE l_rule[] = { {"IY", "l", Anything, "I3-L" }, {"EY", "l", Anything, "I3-L" }, {"AY", "l", Anything, "I3-L" }, {"OY", "l", Anything, "I3-L" }, {"AE", "l", Anything, "UH3-L" }, {"AO", "l", Anything, "UH3-L" }, {"OW", "l", Anything, "UH3-L" }, {Anything, "l", Anything, "L" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE w_rule[] = { {Anything, "w", Anything, "W" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE WH_rule[] = { {Anything, "WH", Anything, "H-W" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE r_rule[] = { {Anything, "r", "l", "UH3-R" }, {Anything, "r", Anything, "R" }, {Anything, E_O_RULE, Anything, Silent }, }; /* ** LEFT_PART MATCH_PART RIGHT_PART OUT_PART */ STATIC RULE punct_rules[] = { {Anything, " ", Anything, "PA0" }, {Anything, ",", Anything, "PA1" }, {Anything, ".", Anything, "PA1-PA1" }, {Anything, "?", Anything, "PA1-PA1" }, {Anything, "-", Anything, "PA1" }, {Anything, E_O_RULE, Anything, Silent }, }; /*< * Function: * Description: * Table, associating IPAs to the RULEs. * >*/ typedef struct { CHAR * ipa; RULE * sc_rule; } IPA_SC; STATIC IPA_SC ipa_sc_tbl[] = { {"AA", AA_rule }, {"AE", AE_rule }, {"AH", AH_rule }, {"AO", AO_rule }, {"AW", AW_rule }, {"AX", AX_rule }, {"AY", AY_rule }, {"CH", CH_rule }, {"DH", DH_rule }, {"EH", EH_rule }, {"ER", ER_rule }, {"EY", EY_rule }, {"IH", IH_rule }, {"IY", IY_rule }, {"NG", NG_rule }, {"OW", OW_rule }, {"OY", OY_rule }, {"SH", SH_rule }, {"TH", TH_rule }, {"UH", UH_rule }, {"UW", UW_rule }, {"WH", WH_rule }, {"ZH", ZH_rule }, {"b", b_rule }, {"d", d_rule }, {"f", f_rule }, {"g", g_rule }, {"h", h_rule }, {"j", j_rule }, {"k", k_rule }, {"l", l_rule }, {"m", m_rule }, {"n", n_rule }, {"p", p_rule }, {"r", r_rule }, {"s", s_rule }, {"t", t_rule }, {"v", v_rule }, {"w", w_rule }, {"y", y_rule }, {"z", z_rule }, }; #define TBL_SIZE ((sizeof(ipa_sc_tbl))/(sizeof(IPA_SC))) /*< * Function: * Description: * Finds the rule corresponding to the specified IPA. * * Returns: * Pointer to RULE. * NULL if specified ipa was not in the table. * >*/ PUBLIC RULE * xrule (ipa) char * ipa; { extern char * bsearch(); RULE * retval; IPA_SC * p_fnd; IPA_SC key; char * fnd_code; key.ipa = ipa; if (p_fnd = (IPA_SC *) bsearch ((char *)&key, (char *)ipa_sc_tbl, TBL_SIZE, sizeof(IPA_SC), compare)) { retval = p_fnd->sc_rule; } else { retval = (RULE *) 0; } return (retval); } STATIC int compare (ky_cd1, ky_cd2) IPA_SC * ky_cd1; IPA_SC * ky_cd2; { return (strcmp(ky_cd1->ipa, ky_cd2->ipa)); } !Funky!Stuff! echo x - setmode.c cat >setmode.c <<'!Funky!Stuff!' #include "mbstd.h" PUBLIC int setmode(handle, mode) int handle; int mode; {} !Funky!Stuff! echo x - strupr.c cat >strupr.c <<'!Funky!Stuff!' /*+ * File: * Description: * The strlwr function converts any upper case letters in the given * null terminated string to lowercase. Other characters are not affected. * * * * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * * Functions: * * * Audit Trail: $Log$ * -*/ #ifdef RCS_VER static char *rcs = "$Header$"; #endif #include "mbstd.h" #include <ctype.h> PUBLIC char * strupr (str) char * str; { char c; char * retval; retval = str; while ( c= *str ) { if (islower(c)) { *str++ = toupper(c); } else { str++; } } return retval; } !Funky!Stuff! echo x - x_ipa2sc.c cat >x_ipa2sc.c <<'!Funky!Stuff!' /*+ * File: * Description: * * * * Author: Mohsen Banan. * * This program is public domain software, no warranty intended or * implied. * General permission to copy or modify, but not for profit, is * hereby granted. * * Functions: * * * Audit Trail: $Log$ * -*/ #ifdef RCS_VER static char *rcs = "$Header$"; #endif /* #includes */ #include "mbstd.h" #include <stdio.h> #include <ctype.h> #include <fcntl.h> #include <string.h> #ifdef BSD4_2 #include "msc3sup.h" #endif #include "rule.h" /* #defines */ /* external variables */ /* referenced external function declarations */ /* internal function declarations */ /* global variables */ /* static variables */ /*< * Function: * Description: * * Returns: * * >*/ PUBLIC SUCC_FAIL x_ipa2sc (ipa_word, sc_out, out_len) CHAR * ipa_word; CHAR * sc_out; INT out_len; { static CHAR buf1[3] = {'\0'}; static CHAR buf2[3] = {'\0'}; static CHAR buf3[3] = {'\0'}; CHAR * prev_left; CHAR * left_ipa = buf1; CHAR * match_ipa = buf2; CHAR * right_ipa = buf3; BOOL e_o_ipa_word = FALSE; CHAR *in_index, *out_index, *out_end; CHAR c1, c; RULE *rules, *rule; extern RULE * xrule(); SUCC_FAIL retval; retval = SUCCESS; in_index = ipa_word; out_index = sc_out; out_end = sc_out + (out_len - 1); /* Room for end-of-string */ *left_ipa = *match_ipa = *right_ipa = '\0'; do { prev_left = left_ipa; left_ipa = match_ipa; match_ipa = right_ipa; right_ipa = prev_left; if ( (! e_o_ipa_word) && (c1 = *in_index++) ) { CHAR * buf = right_ipa; if ( islower(c1) ) { *buf++ = c1; *buf = '\0'; } else { *buf++ = c1; if (c1 = *in_index++) { *buf++ = c1; *buf = '\0'; } else { e_o_ipa_word = TRUE; *buf = '\0'; OOPS(); } } } else { e_o_ipa_word = TRUE; *right_ipa = '\0'; } if (*match_ipa) { if ( rules = xrule(match_ipa) ) { BOOL found = FALSE; CHAR * p_out; for ( rule=rules; rule->match != E_O_RULE; ++rule ) { if ( *(rule->left) != '\0' ) { if ( strcmp(rule->left, left_ipa) ) { continue; } } if ( *rule->right != '\0' ) { if ( strcmp(rule->right, right_ipa) ) { continue; } } /* then it is found */ p_out = rule->out; while ( c = *p_out++ ) { if ( out_index >= out_end ) { OOPS(); *out_index = '\0'; return FAIL; } else { *out_index++ = c; } } *out_index++ = '-'; found = TRUE; break; } if ( ! found ) { OOPS(); retval = FAIL; } } else { OOPS(); retval = FAIL; } } } while ( (*match_ipa) || (*right_ipa) ); /* Handle an empty string input and convert the last '-' to a '\0' */ if ( out_index > sc_out ) { *(out_index - 1) = '\0'; } return retval; } !Funky!Stuff! echo x - bdpdt.bat cat >bdpdt.bat <<'!Funky!Stuff!' cl -o ipa2sc ipa2sc arg_str cantopen getopt nl_elim prs_str setmode strupr bsearch x_ipa2sc sc_rules -link !Funky!Stuff! echo x - mkpdt.bat cat >mkpdt.bat <<'!Funky!Stuff!' cl -c -DMSDOS ipa2sc.c cl -c -DMSDOS arg_str.c cl -c -DMSDOS cantopen.c cl -c -DMSDOS getopt.c cl -c -DMSDOS nl_elim.c cl -c -DMSDOS prs_str.c cl -c -DMSDOS setmode.c cl -c -DMSDOS strupr.c cl -c -DMSDOS bsearch.c cl -c -DMSDOS x_ipa2sc.c cl -c -DMSDOS sc_rules.c !Funky!Stuff!