/*
 * File: wsu2tipa.l
 *
 * (c) Peter Kleiweg 2000
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2,
 * or (at your option) any later version.
 *
 * Compile:
 *
 *    flex -B -8 wsu2tipa.l
 *    gcc -s -Wall -o wsu2tipa lex.yy.c -lfl
 *    rm lex.yy.c
 */

%{

#ifdef __MSDOS__
#  include <dir.h>
#  include <fcntl.h>
#  include <io.h>
#else
#  include <unistd.h>
#endif
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

int
    line = 1;

long
    count = 0;

char
    *filename,
    *programname;

void
    out (char const *s),
    warn (void),
    get_programname (char const *argv0),
    syntax (void),
    errit (char const *format, ...);

#define YY_NO_UNPUT
#define YY_SKIP_YYWRAP
#ifdef yywrap
#  undef yywrap
#endif
int yywrap()
{
    return 1;
}

%}

S    ([^a-zA-Z])

%Start _dia _open

%%

\\inva/{S}           { out ("\\textturna"); }
\\scripta/{S}        { out ("\\textscripta"); }
\\nialpha/{S}        { warn (); }
\\invscripta/{S}     { out ("\\textturnscripta"); }
\\invv/{S}           { out ("\\textturnv"); }
\\crossb/{S}         { out ("\\textcrb"); }
\\barb/{S}           { out ("\\textbarb"); }
\\slashb/{S}         { out ("\\ipaclap{b}{/}"); }
\\hookb/{S}          { out ("\\texthtb"); }
\\nibeta/{S}         { out ("\\textbeta"); }
\\slashc/{S}         { out ("\\ipaclap{c}{/}"); }
\\curlyc/{S}         { out ("\\textctc"); }
\\clickc/{S}         { out ("\\textstretchc"); }
\\crossd/{S}         { out ("\\textcrd"); }
\\bard/{S}           { out ("\\textbard"); }
\\slashd/{S}         { out ("\\ipaclap{d}{/}"); }
\\hookd/{S}          { out ("\\texthtd"); }
\\taild/{S}          { out ("\\textrtaild"); }
\\dz/{S}             { out ("\\textdyoghlig"); }
\\eth/{S}            { out ("\\dh"); }
\\scd/{S}            { warn (); }
\\schwa/{S}          { out ("\\textschwa"); }
\\er/{S}             { out ("\\textrhookschwa"); }
\\reve/{S}           { out ("\\textreve"); }
\\niepsilon/{S}      { out ("\\textepsilon"); }
\\revepsilon/{S}     { out ("\\textrevepsilon"); }
\\hookrevepsilon/{S} { out ("\\textrhookrevepsilon"); }
\\closedrevepsilon/{S} { out ("\\textcloserevepsilon"); }
\\scriptg/{S}        { out ("\\textipa{g}"); }
\\hookg/{S}          { out ("\\texthtg"); }
\\scg/{S}            { out ("\\textscg"); }
\\nigamma/{S}        { out ("\\textramshorns"); }
\\ipagamma/{S}       { out ("\\textgamma"); }
\\babygamma/{S}      { out ("\\textbabygamma"); }
\\hv/{S}             { out ("\\texthvlig"); }
\\crossh/{S}         { out ("\\textcrh"); }
\\hookh/{S}          { out ("\\texthth"); }
\\hookheng/{S}       { out ("\\texththeng"); }
\\invh/{S}           { out ("\\textturnh"); }
\\bari/{S}           { out ("\\textbari"); }
\\dlbari/{S}         { out ("\\ipabar{\\i}{.5ex}{1.1}{}{}"); }
\\niiota/{S}         { out ("\\textiota"); }
\\sci/{S}            { out ("\\textsci"); }
\\barsci/{S}         { out ("\\ipabar{\\textsci}{.5ex}{1.1}{}{}"); }
\\invf/{S}           { out ("\\textObardotlessj"); }
\\tildel/{S}         { out ("\\textltilde"); }
\\barl/{S}           { out ("\\textbarl"); }
\\latfric/{S}        { out ("\\textbeltl"); }
\\taill/{S}          { out ("\\textrtaill"); }
\\lz/{S}             { out ("\\textlyoghlig"); }
\\nilambda/{S}       { out ("\\textlambda"); }
\\crossnilambda/{S}  { out ("\\textcrlambda"); }
\\labdentalnas/{S}   { out ("\\textltailm"); }
\\invm/{S}           { out ("\\textturnm"); }
\\legm/{S}           { out ("\\textturnmrleg"); }
\\nj/{S}             { out ("\\textltailn"); }
\\eng/{S}            { out ("\\ng"); }
\\tailn/{S}          { out ("\\textrtailn"); }
\\scn/{S}            { out ("\\textscn"); }
\\clickb/{S}         { out ("\\textbullseye"); }
\\baro/{S}           { out ("\\textbaro"); }
\\openo/{S}          { out ("\\textopeno"); }
\\niomega/{S}        { out ("\\textomega"); }
\\closedniomega/{S}  { out ("\\textcloseomega"); }
\\oo/{S}             { warn (); }
\\barp/{S}           { out ("\\ipabar{p}{.5ex}{1.1}{}{}"); }
\\thorn/{S}          { out ("\\textthorn"); }
\\niphi/{S}          { out ("\\textphi"); }
\\flapr/{S}          { out ("\\textfishhookr"); }
\\legr/{S}           { out ("\\textlonglegr"); }
\\tailr/{S}          { out ("\\textrtailr"); }
\\invr/{S}           { out ("\\textturnr"); }
\\tailinvr/{S}       { out ("\\textturnrrtail"); }
\\invlegr/{S}        { out ("\\textturnlonglegr"); }
\\scr/{S}            { out ("\\textscr"); }
\\invscr/{S}         { out ("\\textinvscr"); }
\\tails/{S}          { out ("\\textrtails"); }
\\esh/{S}            { out ("\\textesh"); }
\\curlyesh/{S}       { out ("\\textctesh"); }
\\nisigma/{S}        { warn (); }
\\tailt/{S}          { out ("\\textrtailt"); }
\\tesh/{S}           { out ("\\textteshlig"); }
\\clickt/{S}         { out ("\\textturnt"); }
\\nitheta/{S}        { out ("\\texttheta"); }
\\baru/{S}           { out ("\\textbaru"); }
\\slashu/{S}         { out ("\\ipaclap{u}{/}"); }
\\niupsilon/{S}      { out ("\\textupsilon"); }
\\scu/{S}            { out ("\\textscu"); }
\\barscu/{S}         { out ("\\ipabar{\\textscu}{.5ex}{1.1}{}{}"); }
\\scriptv/{S}        { out ("\\textscriptv"); }
\\invw/{S}           { out ("\\textturnw"); }
\\nichi/{S}          { out ("\\textchi"); }
\\invy/{S}           { out ("\\textturny"); }
\\scy/{S}            { out ("\\textscy"); }
\\curlyz/{S}         { out ("\\textctz"); }
\\tailz/{S}          { out ("\\textrtailz"); }
\\yogh/{S}           { out ("\\textyogh"); }
\\curlyyogh/{S}      { out ("\\textctyogh"); }
\\glotstop/{S}       { out ("\\textglotstop"); }
\\revglotstop/{S}    { out ("\\textrevglotstop"); }
\\invglotstop/{S}    { out ("\\textinvglotstop"); }
\\ejective/{S}       { out ("\\textraiseglotstop"); }
\\reveject/{S}       { warn (); }

\\dental/{S}         { out ("\\textsubbridge"); }
\\stress/{S}         { out ("\\textprimstress"); }
\\secstress/{S}      { out ("\\textsecstress"); }
\\syllabic/{S}       { out ("\\textsyllabic"); }
\\corner/{S}         { out ("\\textcorner"); }
\\upt/{S}            { out ("\\textraising"); }
\\downt/{S}          { out ("\\textlowering"); }
\\leftt/{S}          { out ("\\textadvancing"); }
\\rightt/{S}         { out ("\\textretracting"); }
\\halflength/{S}     { out ("\\texthalflength"); }
\\length/{S}         { out ("\\textlengthmark"); }
\\underdots/{S}      { out ("\\textsubumlaut"); }
\\ain/{S}            { out ("\\textrevapostrophe"); }
\\upp/{S}            { out ("\\^"); }
\\downp/{S}          { out ("\\v"); }
\\leftp/{S}          { out ("\\textlptr"); }
\\rightp/{S}         { out ("\\textrptr"); }
\\overring/{S}       { out ("\\r"); }
\\underring/{S}      { out ("\\textsubring"); }
\\open/{S}           { out ("\\textsublhalfring"); }
\\midtilde/{S}       { out ("\\textsuperimposetilde"); }
\\undertilde/{S}     { out ("\\textsubtilde"); }
\\underwedge/{S}     { out ("\\textsubwedge"); }
\\polishhook/{S}     { out ("\\textpolhook"); }
\\underarch/{S}      { out ("\\textsubarch"); }

\\dia(top|under)/{S} { BEGIN _dia; }


\n                   { line++;
                       fputc ('\n', yyout);
                     }

<_dia>"{"            { BEGIN _open; }

<_open>"|"           { fputc ('{', yyout);
                       BEGIN INITIAL;
                     }

%%

int main (int argc, char *argv [])
{
    get_programname (argv [0]);

    switch (argc) {
        case 1:
            if (isatty (fileno (stdin)))
                syntax ();
            yyin = stdin;
	    filename = "(stdin)";
            break;
        case 2:
            yyin = fopen (argv [1], "r");
            if (! yyin)
                errit ("Opening file \"%s\": %s", argv [1], strerror (errno));
            filename = argv [1];
            break;
        default:
            syntax ();
    }

    yylex ();

    if (yyin != stdin)
        fclose (yyin);

    fprintf (stderr, "%li change%s made.\n", count, (count == 1) ? "" : "s");

    return 0;
}

void out (char const *s)
{
    fputs (s, yyout);
    count++;
}

void warn ()
{
    fputs (yytext, yyout);
    fprintf (stderr, "%s:%i: UNTRANSLATED: %s\n", filename, line, yytext);
}

void get_programname (char const *argv0)
{
#ifdef __MSDOS__
    char
        name [MAXFILE];
    fnsplit (argv0, NULL, NULL, name, NULL);
    programname = strdup (name);
#else   /* unix */
    char
        *p;
    p = strrchr (argv0, '/');
    if (p)
        programname = strdup (p + 1);
    else
        programname = strdup (argv0);
#endif    
}

void errit (char const *format, ...)
{
    va_list
        list;

    fprintf (stderr, "\nError %s: ", programname);

    va_start (list, format);
    vfprintf (stderr, format, list);

    fprintf (stderr, "\n\n");

    exit (1);
}

void syntax ()
{
    fprintf (
        stderr,
        "\n"
        "Usage: %s [file.tex]\n"
	"\n"
        "This program translates wsuipa font commands into tipa font commands.\n"
        "\n",
        programname
    );

    exit (1);
}