home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff314.lha
/
zc
/
zc.lzh
/
Examples
/
Stdio
/
Translit
/
translit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-17
|
5KB
|
258 lines
/*
* Translit.c - Remap Characters
*
* Adapted from Kernighan and Plauger's "Software Tools"
* into "C" by Jeff Lydiatt
* 22 Dec 1985
*/
#include <stdio.h>
#include <ctype.h>
#define MAXSET 81
#define MAXARR 81
#define ESCAPE '@'
#define NOT '!'
#define DASH '-'
#define EOS '\0'
#define YES 1
#define NO 0
#define TRUE 1
#define FALSE 0
main (argc, argv)
int argc;
char *argv[];
{
char arg[MAXARR];
register char c;
char from[MAXSET], to[MAXSET];
int makeset();
int allbut, collapse;
register int i, lastto;
int xindex();
extern int strlen();
extern int Enable_Abort;
Enable_Abort = YES;
if (setcmd(argc, argv, 1, arg, MAXARR) == FALSE)
error("Usage: Translit <from >to FromSet ToSet.");
else if (arg[0] == NOT)
{
allbut = YES;
if (makeset(arg, 1, from, MAXSET) == NO)
error("FromSet: too large.");
}
else
{
allbut = NO;
if (makeset(arg, 0, from, MAXSET) == NO)
error("FromSet: too large");
}
if (setcmd(argc, argv, 2, arg, MAXARR) == FALSE)
to[0] = EOS;
else if (makeset(arg, 0, to, MAXSET) == NO)
error("ToSet: too large.");
lastto = strlen(to) - 1;
if (strlen(from) >= lastto || allbut == YES)
collapse = YES;
else
collapse = NO;
do
{
i = xindex(from, c = getchar(), allbut, lastto);
if (feof(stdin))
break;
if (collapse == YES && i >= lastto && lastto >= 0)
{
putchar(to[lastto]); /* Collapse */
do
{
i = xindex (from, c = getchar(), allbut, lastto);
}
while (i >= lastto && !feof(stdin));
}
if (feof(stdin))
break;
if (i >= 0 && lastto >= 0)
putchar(to[i]); /* translate */
else if (i < 0)
putchar(c); /* copy */
else ; /* Delete */
}
while(TRUE);
}
/* makeset: creates the from and to sets by calling fillset
and addset */
int makeset (str, k, set, size)
int k, size;
char str[], set[];
{
int i, j;
int addset();
i = k;
j = 0;
fillset(EOS, str, &i, set, &j, size);
return addset(EOS, set, &j, size);
}
/* addset: - put c in set(j) if it fits, increment j */
int addset (c, set, j, maxsize)
char c, set[];
int *j, maxsize;
{
if (*j > maxsize)
return NO;
else
{
set[(*j)++] = c;
return YES;
}
}
/* fillset: expand set at str(i) into set(j), stop at delim */
fillset (delim, str, i, set, j, maxset)
int *i, *j, maxset;
char str[], delim, set[];
{
char esc();
int junk;
static char * digits = "0123456789";
static char * lowalf = "abcdefghijklmnopqrstuvwxyz";
static char * upalf = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (; str[*i] != delim && str[*i] != EOS; (*i)++)
{
if (str[*i] == ESCAPE)
junk = addset(esc(str, i), set, j, maxset);
else if (str[*i] != DASH)
junk = addset(str[*i], set, j, maxset);
else if (*j <= 0 || str[*i+1] == EOS) /* literal - */
junk = addset(DASH, set, j, maxset);
else if (isdigit(set[*j-1]))
dodash (digits, str, i, set, j, maxset);
else if (islower(set[*j-1]))
dodash(lowalf, str, i, set, j, maxset);
else if (isupper(set[*j-1]))
dodash(upalf, str, i, set, j, maxset);
else
junk = addset(DASH, set, j, maxset);
}
}
/* esc --- map str(i) into escaped character */
char esc (str, i)
char str[];
int *i;
{
if (str[*i] != ESCAPE)
return str[*i];
else if (str[*i+1] == EOS) /* Esc not special at end */
return ESCAPE;
else
switch (str[++(*i)])
{
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
default: return str[*i];
}
}
/* dodash: expand str(i-1) to str(i+1) into set(j) */
dodash (valid, str, i, set, j, maxset)
char valid[], str[], set[];
int *i, *j, maxset;
{
char esc();
int junk, addset();
int k, limit;
int index();
(*i)++;
(*j)--;
limit = index (valid, esc(str, i));
for (k = index(valid, set[*j]); k <= limit; k++)
junk = addset (valid[k], set, j, maxset);
}
/* index: find the character c in string str */
int index (str, c)
char str[], c;
{
register int i;
for (i = 0; str[i] != EOS; i++)
{
if (str[i] == c)
return i;
}
return (int) -1;
}
/* xindex: invert the condition returned by index */
int xindex (str, c, allbut, lastto)
char str[], c;
int allbut, lastto;
{
int index();
if (c == EOF)
return (int) -1;
else if (allbut == NO)
return index(str, c);
else if (index(str, c) >= 0)
return (int) -1;
else
return (int) (lastto + 1);
}
/* error: Print error message and quit */
error(msg)
char * msg;
{
extern void exit();
fputs(msg, stderr);
fputs("\n", stderr);
exit(12);
}
/* setcmd: set the n'th command line parameter into str */
setcmd (Nargs, Arg, n, str, maxsize)
int Nargs, n, maxsize;
char *Arg[], str[];
{
register char *s1, *s2, *smax;
if (n >= Nargs)
return FALSE;
s1 = Arg[n];
s2 = str;
smax = s1 + maxsize - 2;
if (*s1 == '"')
{
for (++s1; *s1 != EOS && *s1 != '"' && s1 < smax;)
*s2++ = *s1++;
}
else
{
for (; *s1 != EOS && s1 < smax;)
*s2++ = *s1++;
}
*s2 = EOS;
return TRUE;
}