/* gurmukhi.c
Preprocessor for TeX for text containing Gurmukhi characters.
Author: Amarjit Singh
E-mail:
[email protected]
This program 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 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <ctype.h>
#define TRUE 1
#define FALSE 0
#define ILL_CHAR 29
#define DUMMY 30
#define END_OF_FILE 30
#define END_OF_LINE 31
#define N_NOLIGS 40
/* ch_typ values */
#define ILLEGAL 0
#define CMR 1
#define CONTROL 2
#define GM 3
#define NUMERAL 4
/* ch_subtyp values */
#define LO_VOWEL 0
#define HI_VOWEL 1
#define CONSONANT 2
#define SPECIAL 3
#define LBRACE 273
#define RBRACE 264
#define RE 263
#define RN 265
#define RS 256
#define INBUF_LEN 133
/* GLOBAL VARIABLES */
FILE *f_in,*f_out,*fopen();
short buf_length;
short syll[30]; /* offset of syll is in chr_ptr or cons_ptr */
short cons_ptr, chr_ptr;
short cons_code;
char *strchr();
char wrong[10];
char *p_in,*p_out,*s_ptr,*o_ptr;
char infil[80], outfil[80];
char inbuf[INBUF_LEN], outbuf[133];
char word[500];
unsigned char gm_mode, dollar_mode, cmr_mode;
unsigned char d_found, no_gm, buf_ptr, wait_syl, lin_obey;
unsigned char error, cons_seen, vow_seen;
struct char_def {
short ch_typ, ch_subtyp, ch_code, ch_subcode;
};
struct char_def table[127] = {
{ILLEGAL,SPECIAL,0,0}, /* 1 not used */
{GM,CONSONANT,'\126',1}, /* 2 .t */
{GM,CONSONANT,'\130',2}, /* 3 .d */
{GM,SPECIAL,'\72',0}, /* 4 .o */
{GM,CONSONANT,'\132',3}, /* 5 .n */
{GM,CONSONANT,'\13',4}, /* 6 .g */
{GM,SPECIAL,'\24',0}, /* 7 .. */
{GM,CONSONANT,'\14',5}, /* 8 .K */
{GM,CONSONANT,'\127',6}, /* 9 .T */
{GM,CONSONANT,'\131',7}, /* 10 .D */
{GM,SPECIAL,'\54',0}, /* 11 .m */
{ILLEGAL,SPECIAL,0,0}, /* 12 not used */
{ILLEGAL,SPECIAL,0,0}, /* 13 not used */
{ILLEGAL,SPECIAL,0,0}, /* 14 not used */
{ILLEGAL,SPECIAL,0,0}, /* 15 not used */
{ILLEGAL,SPECIAL,0,0}, /* 16 not used */
{ILLEGAL,SPECIAL,0,0}, /* 17 not used */
{GM,CONSONANT,'\122',8}, /* 18 "n */
{GM,CONSONANT,'\146',9}, /* 19 "s */
{ILLEGAL,SPECIAL,0,0}, /* 20 not used */
{GM,CONSONANT,'\32', 10}, /* 21 ~n */
{GM,SPECIAL,'\137',0}, /* 22 ~a */
{ILLEGAL,SPECIAL,0,0}, /* 23 not used */
{ILLEGAL,SPECIAL,0,0}, /* 24 not used */
{GM,HI_VOWEL,275,'\106'}, /* 25 ii */
{GM,LO_VOWEL,274,1}, /* 26 uu */
{GM,HI_VOWEL,260,'\117'}, /* 27 oo */
{ILLEGAL,SPECIAL,0,0}, /* 28 not used */
{ILLEGAL,SPECIAL,0,0}, /* 29 not used */
{CONTROL,SPECIAL,0,0}, /* 30 DUMMY */
{CONTROL,SPECIAL,0,0}, /* 31 END_OF_LINE */
{CONTROL,SPECIAL,0,0}, /* 32 space */
{CMR,SPECIAL,0,0}, /* ! */
{ILLEGAL,SPECIAL,0,0}, /* " */
{ILLEGAL,SPECIAL,0,0}, /* # */
{ILLEGAL,SPECIAL,0,0}, /* $ */
{ILLEGAL,SPECIAL,0,0}, /* % */
{ILLEGAL,SPECIAL,0,0}, /* & */
{CMR,SPECIAL,0,0}, /* ' to - */
{CMR,SPECIAL,0,0}, /* ' to - */
{CMR,SPECIAL,0,0}, /* ' to - */
{CMR,SPECIAL,0,0}, /* ' to - */
{CMR,SPECIAL,0,0}, /* ' to - */
{CMR,SPECIAL,0,0}, /* ' to - */
{CMR,SPECIAL,0,0}, /* ' to - */
{ILLEGAL,SPECIAL,0,0}, /* . */
{GM,SPECIAL,'\40',0}, /* / */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
{CMR,SPECIAL,0,0}, /* : and ; */
{CMR,SPECIAL,0,0}, /* : and ; */
{ILLEGAL,SPECIAL,0,0}, /* < */
{CMR,SPECIAL,0,0}, /* = */
{ILLEGAL,SPECIAL,0,0}, /* > */
{CMR,SPECIAL,0,0}, /* ? */
{GM,SPECIAL,'\177',0}, /* @ */
{GM,HI_VOWEL,258,'\101'}, /* A */
{GM,CONSONANT,'\102',11}, /* B */
{GM,CONSONANT,'\103',12}, /* C */
{GM,CONSONANT,'\104',13}, /* D */
{GM,HI_VOWEL,259,'\173'}, /* E */
{ILLEGAL,SPECIAL,0,0}, /* F */
{GM,CONSONANT,'\107',14}, /* G */
{GM,SPECIAL,'\54',0}, /* H */
{GM,HI_VOWEL,267,'\106'}, /* I */
{GM,CONSONANT,'\112',15}, /* J */
{GM,CONSONANT,'\113',16}, /* K */
{ILLEGAL,SPECIAL,0,0}, /* L not used */
{GM,SPECIAL,'\54',0}, /* M */
{GM,SPECIAL,'\134',0}, /* N */
{GM,HI_VOWEL,261,'\117'}, /* O */
{GM,CONSONANT,'\120',17}, /* P */
{ILLEGAL,SPECIAL,0,0}, /* Q */
{GM,CONSONANT,'\167',18}, /* R */
{GM,CONSONANT,'\146',9}, /* S */
{GM,CONSONANT,'\124',19}, /* T */
{GM,LO_VOWEL,276,1}, /* U */
{ILLEGAL,SPECIAL,0,0}, /* V to Z */
{ILLEGAL,SPECIAL,0,0}, /* V to Z */
{ILLEGAL,SPECIAL,0,0}, /* V to Z */
{ILLEGAL,SPECIAL,0,0}, /* V to Z */
{ILLEGAL,SPECIAL,0,0}, /* V to Z */
{CMR,SPECIAL,0,0}, /* [ */
{CONTROL,SPECIAL,0,0}, /* \ */
{CMR,SPECIAL,0,0}, /* ] */
{ILLEGAL,SPECIAL,0,0}, /* ^ */
{ILLEGAL,SPECIAL,0,0}, /* _ */
{CMR,SPECIAL,0,0}, /* ` */
{GM,HI_VOWEL,'\141',257}, /* a */
{GM,CONSONANT,'\142',20}, /* b */
{GM,CONSONANT,'\143',21}, /* c */
{GM,CONSONANT,'\144',22}, /* d */
{GM,HI_VOWEL,262,3}, /* e */
{GM,CONSONANT,'\47',23}, /* f */
{GM,CONSONANT,'\147',24}, /* g */
{GM,CONSONANT,'\150',25}, /* h */
{GM,HI_VOWEL,'\151','\105'}, /* i */
{GM,CONSONANT,'\152',26}, /* j */
{GM,CONSONANT,'\153',27}, /* k */
{GM,CONSONANT,'\154',28}, /* l */
{GM,CONSONANT,'\155',29}, /* m */
{GM,CONSONANT,'\156',30}, /* n */
{GM,HI_VOWEL,'\33','\157'}, /* o */
{GM,CONSONANT,'\160',31}, /* p */
{ILLEGAL,SPECIAL,0,0}, /* not used */
{GM,CONSONANT,'\162',32}, /* r */
{GM,CONSONANT,'\163',33}, /* s */
{GM,CONSONANT,'\164',34}, /* t */
{GM,LO_VOWEL,'\165',0}, /* u */
{GM,CONSONANT,'\166',35}, /* v */
{ILLEGAL,SPECIAL,0,0}, /* not used */
{ILLEGAL,SPECIAL,0,0}, /* not used */
{GM,CONSONANT,'\171',36}, /* y */
{GM,CONSONANT,'\51',37}, /* z */
{CONTROL,SPECIAL,0,0}, /* left brace */
{GM,SPECIAL,'\56',0}, /* | */
{CONTROL,SPECIAL,0,0}, /* right brace */
{ILLEGAL,SPECIAL,0,0}, /* ~ */
{ILLEGAL,SPECIAL,0,0} /* del */
};
char chset1[12]= {'k','t','d','o','n','g','.','K','T','D','m',' '};/* . */
char chset4[10]= {'k','g','c','j','t','d','p','b','s',' '}; /* h */
char chset3[3] = {'n','s',' '}; /* " */
char chset6[3] = {'n','a',' '}; /* ~ */
char chset2[3] = {'a','i',' '}; /* a */
char chset5[2] = {'A','E'}; /* result of aa and ai */
char out_string[277][7] = {
"\\7{","\\8{","\\9{","\\?","\\<","^^E","^^F",
"^^G","^^H","^^I","^^J","^^K","^^L","\\0",
"\\qx{","^^O","^^P","^^Q","^^R",
"^^S","^^T","^^U","^^V","^^W","^^X",
"^^Y","^^Z","^^[","^^\\","^^]",
"^^^","\\qy{","\\1","!","\"","\\#","\\$",
"\\%","\\&","\'","(",")","*","+",",","-",".","/","0","1","2",
"3","4","5","6","7","8","9",":",";","<","=",">","?","@",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\2",
"]","\\qq{","\\35Fw","`","a","b","c","d","e","f","g","h","i","j",
"k","l","m","n","o","p","q","r","s","t","u","v","w","x",
"y","z","\\4","\\qz{","\\5","\\6{","^^?",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","","","","",
"","","{\\rs ","","aA","a\\4",
"ao","aO","a\\?","\\re}","}","\\rn{",
"{\\rdt}","iF","{\\qva}","{\\qvb}","{\\qvc}",
"\\qa{","\\qb{","{", "\\7{u}","Ei", "\\8{u}"
};
/* strstr : to make it portable */
char *st_find(s,q)
char *s, *q;
{
short i,j,k,l;
j = strlen(s);
k = strlen(q);
for (i=0; i <= j-k; i++) {
if (s[i]==q[0]) {
for (l = 1; (s[i + l] == q[l]) && (q[l] != '\0'); l++) ;
if (q[l] == '\0') return(&s[i]);
}
}
return(NULL);
}
/* strchr : to make it portable */
char *ch_find(s,q)
char *s;
char q;
{
short i,j;
j = strlen(s);
for (i=0; i < j; i++)
if (s[i]==q) return(&s[i]);
return(NULL);
}
err_ill(str)
char *str;
{
printf("Error: illegal character(s): %s\n",str);
puts(inbuf);
getchar();
error = TRUE;
}
/* Find {\gm in inbuf, copy everything till {\gm to outbuf */
/* and modify rest of it back to inbuf */
/* RETURN : TRUE if inbuf is valid */
/* FALSE otherwise */
/* other ouputs : no_gm */
/* d_found */
char find_gm()
{
char *d_ptr;
char *gm_ptr;
char *svbuf;
char again;
d_found = FALSE;
svbuf = inbuf;
do {
again = FALSE;
gm_ptr = st_find(svbuf,"{\\gm");
if (gm_ptr != NULL) {
again = isalpha(gm_ptr[4]);
svbuf = gm_ptr + 4;
}
} while(again);
if (dollar_mode) {
d_ptr = ch_find(inbuf,'$');
if ((d_ptr != NULL) && ((gm_ptr == NULL) || (d_ptr < gm_ptr))) {
d_found = TRUE;
gm_ptr = d_ptr;
}
}
if (gm_ptr == NULL)
return(FALSE);
strncat(outbuf,inbuf,gm_ptr-inbuf);
no_gm = FALSE;
if (!d_found) {
if (gm_ptr[4] == '#') {
no_gm = TRUE;
gm_ptr += 1;
} else {
strcat(outbuf,"{\\gm");
}
gm_ptr += 4;
} else {
switch(dollar_mode) {
case 1: strcat(outbuf,"{\\gm ");
break;
case 2: strcat(outbuf,"\\pgm ");
case 3: no_gm = TRUE;
}
gm_ptr += 1;
}
strcpy(inbuf,gm_ptr);
return(TRUE);
}
/* Returns one char from "inbuf" at "buf_ptr" */
/* if inbuf is at END_OF_LINE then refills it from "f_in" */
/* other inputs : p_in */
/* other outputs: p_in, buf_length */
char inp_ch()
{
char ch, ch_out;
ch = inbuf[buf_ptr++];
if (ch == '\n') {
if (p_in == 0)
ch_out = END_OF_FILE;
else {
p_in = fgets(inbuf,INBUF_LEN,f_in);
buf_ptr = 0;
buf_length = strlen(inbuf);
ch_out = END_OF_LINE;
}
} else {
if (ch < 32)
ch_out = ILL_CHAR;
else
ch_out = ch;
}
return(ch_out);
}
put_macro(macro)
short macro;
{
char tmp[5];
int l, i;
if (syll[chr_ptr-1] == '\175') {
syll[chr_ptr+1] = '\175';
syll[chr_ptr] = RBRACE;
syll[chr_ptr-1] = syll[chr_ptr-2];
syll[chr_ptr-2] = macro;
chr_ptr += 2;
} else if (syll[chr_ptr-1]==RBRACE) {
syll[chr_ptr-3] = 271;
syll[chr_ptr] = LBRACE;
sprintf(tmp,"%d",macro);
l = strlen(tmp);
chr_ptr += 1;
for (i = 0; i < l; i++)
syll[chr_ptr+i] = tmp[i];
chr_ptr += l;
syll[chr_ptr] = RBRACE;
chr_ptr += 1;
} else {
syll[chr_ptr] = syll[chr_ptr-1];
syll[chr_ptr-1] = macro;
syll[chr_ptr+1] = RBRACE;
chr_ptr = chr_ptr +2;
}
}
/* find out string corresponding to chars in syll */
/* and then move to word. */
/* Reset related flags */
put_syll()
{
short i;
for (i = 0; i <= (chr_ptr-1); i++)
strcat(word,&out_string[syll[i]][0]);
chr_ptr = 0;
cons_seen =FALSE;
vow_seen =FALSE;
wait_syl = FALSE;
}
/* puts out string for one code ( or char ) in word */
put_sym(code)
short code;
{
strcat(word,&out_string[code][0]);
}
/* move word to outbuf */
/* if not lin_obey then
put outnuf in f_out
keep moving word to outbuf to f_out till
len of word is bigger than 80
At end of this routine outbuf may have a valid string
*/
put_word()
{
short lw,lb;
lw = strlen(word);
lb = strlen(outbuf);
if (((lb + lw) > 80) && !lin_obey)
{
if (lb > 1)
{
if (outbuf[lb-1] != ' ')
strcat(outbuf,"%\n");
else
outbuf[lb-1] = '\n';
fputs(outbuf,f_out);
}
while (lw > 80)
{
strncpy(outbuf,word,79);
outbuf[79] = '\0';
strcat(outbuf,"%\n");
fputs(outbuf,f_out);
strcpy(word,&word[79]);
lw = strlen(word);
}
strcpy(outbuf,word);
}
else
strcat(outbuf,word);
strcpy(word,"");
}
/* copies c to word and */
/* if c is space then outputs a word */
sendchar(c)
char c;
{
char cstr[2];
cstr[0] = c;
cstr[1] = '\0';
strcat(word,cstr);
if (isspace(c))
put_word();
}
put_ch(code)
short code;
{
struct char_def *c_ptr;
short i;
c_ptr = &table[code-1];
switch(c_ptr->ch_typ) {
case GM:
if (cmr_mode) {
cmr_mode = FALSE;
put_sym(RE);
}
switch(c_ptr->ch_subtyp) {
case HI_VOWEL:
if (wait_syl)
put_syll();
if (cons_seen) {
if (code == 'i') {
for (i = chr_ptr; i>= (cons_ptr+1); i--)
syll[i] = syll[i-1];
syll[cons_ptr] = c_ptr->ch_subcode;
} else {
syll[chr_ptr] = c_ptr->ch_subcode;
if ((code != 'A') && (code != 'a'))
vow_seen = TRUE;
}
} else
syll[chr_ptr] = c_ptr->ch_code;
chr_ptr = chr_ptr + 1;
wait_syl = TRUE;
cons_seen = FALSE;
break;
case LO_VOWEL:
if (wait_syl)
put_syll();
if (cons_seen)
{
put_macro(c_ptr->ch_subcode);
chr_ptr = chr_ptr - 1;
}
else
syll[chr_ptr] = c_ptr->ch_code;
chr_ptr = chr_ptr + 1;
wait_syl = TRUE;
cons_seen = FALSE;
break;
case CONSONANT:
if (wait_syl)
put_syll();
if (!cons_seen) {
cons_seen = TRUE;
cons_ptr = chr_ptr;
cons_code = c_ptr->ch_subcode;
syll[chr_ptr] = c_ptr->ch_code;
chr_ptr += 1;
} else {
if (code == 'r') {
syll[chr_ptr] = '\175';
chr_ptr = chr_ptr + 1;
cons_code = 0;
} else if (code == 'h') {
syll[chr_ptr] = '\110';
chr_ptr = chr_ptr + 1;
cons_code = 0;
} else if (code == 'v') {
syll[chr_ptr] = '\46';
chr_ptr = chr_ptr + 1;
cons_code = 0;
} else {
cons_code = c_ptr->ch_subcode;
syll[chr_ptr] = c_ptr->ch_code;
chr_ptr += 1;
}
}
break;
case SPECIAL:
put_syll();
put_sym(c_ptr->ch_code);
}
break;
case ILLEGAL:
wrong[0] = code; wrong[1] = '\0';
err_ill(wrong);
break;
case CONTROL:
if (cmr_mode) {
cmr_mode = FALSE;
put_sym(RE);
} else {
put_syll();
}
if (code == END_OF_LINE) {
put_word();
strcat(outbuf,"\n");
fputs(outbuf,f_out);
strcpy(outbuf,"");
if (!lin_obey)
fputs("\n",f_out);
} else if (code != DUMMY)
sendchar(code);
break;
case CMR:
if (cmr_mode)
sendchar(code);
else {
cmr_mode = TRUE;
put_syll();
put_sym(RS);
sendchar(code);
}
break;
case NUMERAL:
sendchar(code);
break;
} /* end of switch on ch_typ */
}
/* This routine resolves the combination of charaters */
/* used to symbolize font characters */
/* i.e. it cooks set of input chars to one offset in "table" */
gmproc(symbol)
char symbol;
{
unsigned char saved,gmready;
short brace_lev;
char savchr;
short i;
brace_lev = 1;
saved = FALSE;
gmready = FALSE;
do {
switch(symbol) {
case '.':
savchr = inp_ch();
i = 0;
do {
i++;
} while ((i != 12) && (chset1[i-1] != savchr));
if (i == 12) {
wrong[0] = '.';
wrong[1] = savchr;
wrong[2] = '\0';
err_ill(wrong);
} else if (i < 4) {
savchr = inp_ch();
if (savchr == 'h')
i = i+7;
else {
saved = TRUE;
if (i == 1)
err_ill(".k");
}
}
if (!error) {
if (i == 11)
put_ch('M');
else
put_ch(i);
}
break;
case 'i':
savchr = inp_ch();
if (savchr == 'i')
put_ch(25);
else {
put_ch(symbol);
saved = TRUE;
}
break;
case 'u':
savchr = inp_ch();
if (savchr == 'u')
put_ch(26);
else {
put_ch(symbol);
saved = TRUE;
}
break;
case 'o':
savchr = inp_ch();
if (savchr == 'o')
put_ch(27);
else {
put_ch(symbol);
saved = TRUE;
}
break;
case 'a':
savchr = inp_ch();
i = 0;
do {
i++;
} while ((i != 3) && (chset2[i-1] != savchr));
if (i == 3)
{
put_ch(symbol);
saved = TRUE;
} else
put_ch(chset5[i-1]);
break;
case '\"':
savchr = inp_ch();
i = 0;
do {
i++;
} while ((i != 3) && (chset3[i-1] != savchr));
if (i == 3) {
wrong[0] = '~';
wrong[1] = savchr;
wrong[2] = '\0';
err_ill(wrong);
} else
put_ch(i+17);
break;
case '~':
savchr = inp_ch();
i = 0;
do {
i++;
} while ((i != 3) && (chset6[i-1] != savchr));
if (i == 3) {
wrong[0] = '~';
wrong[1] = savchr;
wrong[2] = '\0';
err_ill(wrong);
} else
put_ch(i+20);
break;
case END_OF_LINE:
if (lin_obey) {
put_ch(END_OF_LINE);
put_ch(END_OF_LINE);
} else {
do {
savchr = inp_ch();
} while (savchr == ' ');
if (savchr == END_OF_LINE)
put_ch(END_OF_LINE);
else {
put_ch(' ');
saved = TRUE;
}
}
break;
case '$':
if (!dollar_mode)
put_ch(symbol);
else {
if (no_gm)
put_ch(DUMMY);
else
put_ch('}');
gmready= TRUE;
put_word();
strcpy(inbuf,&inbuf[buf_ptr]);
}
break;
case '}':
brace_lev = brace_lev-1;
if ((brace_lev == 0) && !d_found) {
if (no_gm)
put_ch(DUMMY);
else
put_ch(symbol);
gmready= TRUE;
put_word();
strcpy(inbuf,&inbuf[buf_ptr]);
} else
put_ch(symbol);
break;
case '{':
put_ch(symbol);
brace_lev = brace_lev+1;
break;
case '%': do
symbol = inp_ch();
while(symbol != END_OF_LINE);
break;
case '\\':
put_ch(symbol);
symbol = inp_ch();
if (symbol == END_OF_LINE) {
put_word();
strcat(outbuf,"\n");
fputs(outbuf,f_out);
strcpy(outbuf,"");
} else {
if (!isalnum(symbol))
sendchar(symbol);
else {
do {
sendchar(symbol);
symbol = inp_ch();
} while (isalnum(symbol));
savchr = symbol;
saved = TRUE;
}
}
break;
case ILL_CHAR: err_ill('\0');
break;
case END_OF_FILE:
puts("error: missing }");
error = TRUE;
break;
default:
i = 0;
do {
i++;
} while ((i != 10) && (chset4[i-1] != symbol));
if (i == 10)
put_ch(symbol);
else {
savchr = inp_ch();
if (savchr == 'h') {
put_ch(symbol-32);
} else {
put_ch(symbol);
saved = TRUE;
}
}
break;
} /* end of switch */
if (saved) {
symbol = savchr;
saved = FALSE;
} else if ((!error) && (!gmready)) {
symbol = inp_ch();
}
} while (!error && !gmready);
}
main(argc,argv)
int argc;
char *argv[];
{
unsigned char gm_yes;
/* get file specifications */
if (argc == 3) {
strcpy(infil,argv[1]);
strcpy(outfil,argv[2]);
} else if (argc == 2) {
strcpy(infil,argv[1]);
strcpy(outfil,"");
} else {
do {
printf("input file: ");
gets(infil);
} while (strlen(infil) == 0);
printf("output file: ");
gets(outfil);
}
s_ptr = strchr(infil,'.');
if (strlen(outfil) == 0) {
strcpy(outfil,infil);
o_ptr = strchr(outfil,'.');
if (o_ptr != 0)
*o_ptr = '\0';
}
if (s_ptr == 0)
strcat(infil,".gm");
o_ptr = strchr(outfil,'.');
if (o_ptr == 0)
strcat(outfil,".tex");
/* open files */
if ((f_in = fopen(infil,"r")) == NULL) {
printf("cannot open file %s\n",infil);
exit(1);
}
if ((f_out = fopen(outfil,"w")) == NULL) {
printf("cannot open file %s\n",infil);
exit(1);
}
/* initialization */
error = FALSE;
cons_seen = FALSE;
vow_seen = FALSE;
wait_syl = FALSE;
cmr_mode = FALSE;
gm_mode = TRUE;
lin_obey = FALSE;
dollar_mode = 0;
chr_ptr = 0;
strcpy(word,"");
strcpy(outbuf,"");
/* read preprocessor commands */
while (TRUE) {
strcpy(inbuf,"");
p_in = fgets(inbuf,INBUF_LEN,f_in);
if (inbuf[0] != '@')
break;
while (TRUE) {
if (st_find(inbuf,"dollars") == &inbuf[1]) {
dollar_mode = 1;
break;
}
if (st_find(inbuf,"punjabi") == &inbuf[1]) {
/* reserved for hindi & pujabi merger */
break;
}
if (st_find(inbuf,"obeylines") == &inbuf[1]) {
lin_obey = TRUE;
break;
}
if (st_find(inbuf,"dolmode1") == &inbuf[1]) {
dollar_mode = 1;
break;
}
if (st_find(inbuf,"dolmode2") == &inbuf[1]) {
dollar_mode = 2;
break;
}
if (st_find(inbuf,"dolmode3") == &inbuf[1]) {
dollar_mode = 3;
break;
}
printf("Error: illegal preprocessor command\n");
puts(inbuf);
getchar();
break;
}
}
/* main loop */
do {
if (!find_gm())
fputs(inbuf,f_out);
else {
do {
buf_length = strlen(inbuf);
buf_ptr = 0;
gmproc(inp_ch());
if (!error)
gm_yes = find_gm();
if (!gm_yes) {
strcat(outbuf,inbuf);
fputs(outbuf,f_out);
}
} while (gm_yes && !error);
}
strcpy(inbuf,"");
p_in = fgets(inbuf,INBUF_LEN,f_in);
strcpy(outbuf,"");
} while ((p_in != NULL) && !error);
fclose(f_in);
fclose(f_out);
}