Files
Arquivotheca.Solaris-2.5/cmd/iconv/process.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

348 lines
5.8 KiB
C
Executable File

/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)process.c 1.4 94/01/21 SMI"
/*
* process.c code set conversion on the input
*/
#include <stdio.h>
#include <sys/errno.h>
#include <string.h>
#include "usl_iconv.h"
#define NODATA -1
static int getbyte();
static void putbyte();
static void putstring();
static unsigned char rewindnodes();
static void clear();
/*
* in the following buffer
* from begin to readp
* are the currently held
* characters being used to
* from a composite.
* from readp to end are
* the next characters
*/
static struct level {
int begin;
int end;
int read_point;
int must_clear;
unsigned char input_chars[KBDBUFSIZE];
struct cornode *c_node;
} levels[10];
/*
* Process is a
* recursive routine which will
* decend the tree and pass on
* to th next level in a composite
* table any finished characters
* If no data available it will
* return to previous level
* will attempt to generate more data.
*/
void
process ( t , fd , level)
struct kbd_tab *t;
int fd , level;
{
int j;
unsigned char c;
int ch;
struct cornode *n;
struct cornode *node_tab;
if (!t) {
while ((ch=getbyte(fd,level)) != NODATA) {
c = (unsigned char) (ch & 0x0FF);
clear(level);
printf("%c",c);
}
} else
if (t->t_flag == KBD_COT) {
while ((ch=getbyte(fd,level)) != NODATA) {
c = (unsigned char) (ch & 0x0FF);
putbyte(c,level+1);
clear(level);
process(t->t_next,fd,level+1);
}
} else
if (t->t_flag & KBD_ONE) {
while ((ch=getbyte(fd,level)) != NODATA) {
c = t->t_oneone[ch];
putbyte(c,level+1);
clear(level);
process(t->t_next,fd,level+1);
}
} else
if (!t->t_nodes) {
while ((ch=getbyte(fd,level)) != NODATA) {
c = (unsigned char) (ch & 0x0FF);
putbyte(c,level+1);
clear(level);
process(t->t_next,fd,level+1);
}
} else {
node_tab = t->t_nodep;
while ((ch=getbyte(fd,level)) != NODATA) {
c = (unsigned char) (ch & 0x0FF);
if (!levels[level].c_node) {
if (t->t_flag & KBD_FULL) {
if (c > t->t_max || c < t->t_min) {
putbyte(c,level+1);
clear(level);
process(t->t_next,fd,level+1);
continue;
} else
j = (int) (c - t->t_min);
} else
j = 0;
levels[level].c_node = &node_tab[j];
}
for(;;) {
n = levels[level].c_node;
if (n->c_val == c) {
/*
* Match
*/
if (n->c_flag & ND_RESULT) {
if (n->c_flag & ND_INLINE) {
putbyte(n->c_child,level+1);
clear(level);
process(t->t_next,fd,level+1);
break;
} else {
putstring(t->t_textp,n->c_child,level+1);
clear(level);
process(t->t_next,fd,level+1);
break;
}
}
/*
* decend tree
*/
levels[level].c_node = &node_tab[n->c_child];
break;
} else {
/*
* not matching
*/
if (n->c_flag & ND_LAST) {
/*
* get the first
* byte that caused
* this tree traversal
*/
c = rewindnodes(level);
/*
* give it to the next level
* then continue from the second byte
* that got us here
*/
if (t->t_flag & KBD_ERR)
putstring(t->t_textp,t->t_error,level+1);
else
putbyte(c,level+1);
process(t->t_next,fd,level+1);
break;
} else {
levels[level].c_node = ++n;
continue;
}
}
}
}
}
}
static int
getbyte ( fd , level )
int fd , level;
{
int n;
int j;
char buf[KBDREADBUF];
int end;
int begin;
int read_point;
unsigned char *p;
end = levels[level].end;
begin = levels[level].begin;
read_point = levels[level].read_point;
p = levels[level].input_chars;
if (levels[level].must_clear) {
fprintf(stderr,"Buffer Overrun. (1)\n");
exit(1);
}
if (read_point == end) {
/*
* NODATA. If level 0
* read a byte or 2.
*/
if (level)
return NODATA;
n = begin - end;
if (n <= 0)
n = KBDBUFSIZE + n;
if (n > KBDREADBUF)
n = KBDREADBUF;
j = read(fd,buf,n);
if (!j || j < 0)
return NODATA;
/*
* FILL BUFFER from end
*/
for(n=0;n<j;n++){
p[end] = buf[n];
end = (end + 1) % KBDBUFSIZE;
}
levels[level].end = end;
}
j = (int)(p[read_point] & 0x0FF);
/*
* increment read point
* if i hit begin then must
* do a clear opperation
* before next read or
* will get buffer overran
*/
read_point = (read_point + 1) % KBDBUFSIZE;
levels[level].read_point = read_point;
if (read_point == begin)
levels[level].must_clear = 1;
return j;
}
/*
* putstring uses
* putbyte
*/
static void
putstring ( s , index , level )
char *s;
int index , level;
{
s += index;
while (*s)
putbyte(*s++,level);
}
/*
* Give the byte to the
* next level
*/
static void
putbyte ( c , level )
unsigned char c;
int level;
{
int end = levels[level].end;
unsigned char * p = levels[level].input_chars;
p[end] = c;
levels[level].end = (end + 1) % KBDBUFSIZE;
}
/*
* Clear the held characters
* up to the read point.
* they've been processed
*/
static void
clear ( level )
int level;
{
levels[level].must_clear = 0;
levels[level].begin = levels[level].read_point;
levels[level].c_node = (struct cornode *)NULL;
}
static unsigned char
rewindnodes ( level )
int level;
{
int begin = levels[level].begin;
unsigned char c;
c = levels[level].input_chars[begin];
begin = (begin + 1 ) % KBDBUFSIZE;
levels[level].read_point = begin;
levels[level].must_clear = 0;
levels[level].begin = begin;
levels[level].c_node = (struct cornode *)NULL;
return c;
}