[net.sources] Pig Latin Filter

markb@sdcrdcf.UUCP (Mark Biggar) (08/27/83)

\* Just for fun here is a program that does a fairly good job of */
\* translating English text into pig latin.                      */

#include <stdio.h>
#include <ctype.h>

#define TRUE 1
#define FALSE 0

main(argc,argv)     /* pig -- piglatin filter */
int argc;
char *argv[];
{
    FILE *fp;   /* input file pointer */
    
    if (argc == 1)  /* no args -- process std input */
	latinize(stdin);
    else
	while (-argc > 0)   /* process each file */
	    if ((fp = fopen(*++argv,"r")) == NULL) { /* open file */
		fprintf(stderr,"pig: can't open %s\n",*argv);
		exit(1);	
	    } else {
		latinize(fp); /* process new file */
		fclose(fp);
	    }
    exit(0);
}

isvowel(c)  /* function to determine if letter is a vowel */
int c;
{
    if (islower(c)) c = toupper(c); /* cvt to UC */
    return ((c=='A') || (c=='E') ||
	    (c=='I') || (c=='O') ||
	    (c=='U') || (c=='Y'))
;}

char s[30] = ""; /* tmp store for consonants */
int sptr = 0;    /* pointer to next con save place */

 save(c) /* procedure to save consonants */
int c;
{
    s[sptr++] = c;
    s[sptr] = '\0' /* make string printable */
;}

 ccout() /* procedure to print saved consonants */
{
    printf(s);
    s[0] = '\0'; /* empty con save string */
    sptr = 0
;}

/*               STATE TRANSITION TABLE

		     Input Character

 Last State | Punct | Const | Vowel |   Y   |
 - - - - - -+-------------------------------+
    LFW     |  LFW  |  CC   |  CRW  |  FY   |
 - - - - - -+-------------------------------+
    CC      |  LFW  |  CC   |  CRW  |  CC   |
 - - - - - -+-------------------------------+
    CRW     |  LFW  |  CRW  |  CRW  |  CRW  |
 - - - - - -+-------------------------------+
    FY      |  LFW  |  CRW  |  CRW  |  CRW  |
 - - - - - -+-------------------------------+

NOTE: State transition is modified by consonant collection,
	capilitazation, and the "QU" problem.
*/

/*      Define State Values       */

#define LFW     0   /* Looking For Word */
#define CC      1   /* Collecting Consonants */
#define FY      2   /* Found Y */
#define CRW     3   /* Collecting the Rest of Word */

/*      Routine to convert to piglatin  */

 latinize(ffp)
FILE *ffp;  /* file to be processed */
{
    int c,          /* current input character */
	    state;      /* current state */
    int    cflg,       /* capitalization flag */
	    qflg,       /* last letter q flag */
	    wcflag;     /* word all caps */

    state = LFW;  /* initial state is looking for word */
    while ( (c = getc(ffp)) != EOF ){
	switch ( state ){
	case LFW:  /* looking for word */
		cflg = qflg = wcflag = FALSE; /* reset Cap and q flags */
		if ( !isalpha(c) ){
		    putchar(c)       /* all punct get dumped here */
		;} else if ( c == 'y' || c == 'Y' ){ /* must treat y's different */
		    state = FY;
		    if ( isupper(c) ){ cflg = TRUE ;}
		;} else if ( isvowel(c) ){
		    putchar(c);
		    state = CRW
		;} else {
		    if ( isupper(c) ){ /* must remember if UC */
			cflg = 1;
			c = tolower(c)
		    ;};
		    if ( c=='q' ){ qflg = TRUE ;}; /* remember q's */
		    save(c);
		    state = CC
		;};
		break;;
	case FY:
		if ( !isalpha(c) ){
		    putchar(cflg ? 'Y' : 'y'); /* alone y */
		    putchar(c);
		    state = LFW
		;} else if ( isvowel(c) ){ /* treat as consonant */
		    save('y');
		    putchar((cflg && !isupper(c)) ? toupper(c) : c);
		    state = CRW
		;} else { /* treat as vowel */
		    putchar(cflg ? 'Y' : 'y');
		    putchar(c);
		    state = CRW
		;};
		break;;
	case CC:
		if ( !isalpha(c) ){ /* no vowels !!!! */
		    ccout();
		    putchar(c);
		    state = LFW
		;} else if ( isvowel(c) ){ /* start of xlated word */
		    if ( qflg && c=='u' ){ /* u after q is consonant */
			save(c);
			qflg = FALSE
		    ;} else {
			putchar((cflg && !isupper(c)) ? toupper(c) : c);
			if ( isupper(c) ){
			    wcflag = TRUE;
			    if ( sptr ){ s[0] = toupper(s[0]) ;}
			;};
			state = CRW
		    ;}
		;} else {
		    if ( c=='q' ){ qflg = TRUE ;}; /* remember q'S */
		      save (c)
		;};
		break;;
	case CRW:
		if ( !isalpha(c) ){ /* word is done */
		    if ( sptr==0 ){ /* if start was vowel */
			if ( wcflag ){
			    printf("WAY")
			;} else {
			    printf("way")
			;}
		    ;} else { /* start was consonant */
			ccout();
			if ( wcflag ){
			    printf("AY")
			;} else {
			    printf("ay")
			;}
		    ;};
		    putchar(c);
		    state = LFW /* go look for next word */
		;} else {
		    putchar(c);  /* just pass along vowels */
		    if ( isupper(c) ){
			wcflag = TRUE;
			if ( sptr ){ s[0] = toupper(s[0]) ;}
		    ;}
		;}
	;}
    ;}
;}