Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

242 lines
7.5 KiB
C

static char sccsid[] = "@(#)42 1.11 src/bos/usr/ccs/lib/libc/AFread.c, libcgen, bos411, 9428A410j 1/12/94 17:11:15";
/*
* COMPONENT_NAME: LIBCGEN
*
* FUNCTIONS: AFread
*
* ORIGINS: 9, 27
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1985, 1994
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/*
* FUNCTION: Read the next record from an Attribute File. Parse and
* fill in the current attribute table and current buffer.
*
* RETURN VALUE DESCRIPTION:
*/
#include <stdio.h>
#include <IN/standard.h>
#include <IN/AFdefs.h>
#include <stdlib.h>
#include <sys/limits.h>
#define SP 0 /* space */
#define LF 1 /* line feed */
#define CO 2 /* ':' */
#define EQ 3 /* '=' */
#define QO 4 /* '"' */
#define SL 5 /* '\' */
#define CM 6 /* ',' */
#define OD 7 /* octal digit */
#define ID 8 /* other alphanumeric */
#define NTYPES 9
#define BOR 0 /* skip to beginning of record */
#define SKR (NTYPES) /* skip to key */
#define KEY (NTYPES*2) /* accumulate key */
#define SKK (NTYPES*3) /* skip to next key */
#define SKC (NTYPES*4) /* skip to colon */
#define SKA (NTYPES*5) /* skip to attribute name */
#define ATR (NTYPES*6) /* accumulate name */
#define SKE (NTYPES*7) /* skip to equals */
#define SKV (NTYPES*8) /* skip to value */
#define VAL (NTYPES*9) /* accumulate value */
#define QUO (NTYPES*10) /* accumulate quoted value */
#define SLS (NTYPES*11) /* last char was backslash */
#define OD1 (NTYPES*12) /* accumulate octal digits */
#define OD2 (NTYPES*13) /* accumulate octal digits */
#define OD3 (NTYPES*14) /* accumulate octal digits */
#define SKL (NTYPES*15) /* skip to next value */
#define NSTATE 16
#define FIN (NTYPES*16)
#define E 0100000 /* error */
#define O 0040000 /* octal digit */
#define D 0020000 /* end octal spec */
#define B 0010000 /* check for backslashed control character */
#define N 0004000 /* terminate name */
#define V 0002000 /* terminate value */
#define L 0001000 /* terminate list */
#define S 0000400 /* store character */
#define SMASK 0377 /* next state */
static char typetab[128] =
{ SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,LF,LF,LF,SP,SP,SP,
SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,SP,
SP,ID,QO,ID,ID,ID,ID,ID,ID,ID,ID,ID,CM,ID,ID,ID,
OD,OD,OD,OD,OD,OD,OD,OD,ID,ID,CO,ID,ID,EQ,ID,ID,
ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,
ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,SL,ID,ID,ID,
ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,
ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,ID,SP
};
static short action[NSTATE*NTYPES] = {
/*SP(0) LF(1) CO(2) EQ(3) QO(4) SL(5) CM(6) OD(7) ID(8) */
E|SKR, 0|BOR, E|SKR, E|SKR, E|SKR, E|SKR, E|SKR, S|KEY, S|KEY,/*BOR*/
0|SKR, 0|BOR, 0|SKR, 0|SKR, 0|SKR, 0|SKR, 0|SKR, 0|SKR, 0|SKR,/*SKR*/
V|SKC, E|SKR,V|L|SKA, E|SKR, E|SKR, E|SKR, V|SKK, S|KEY, S|KEY,/*KEY*/
0|SKK, L|FIN, L|SKA, E|SKR, E|SKR, E|SKR, 0|SKK, S|KEY, S|KEY,/*SKK*/
0|SKC, E|SKR, L|SKA, E|SKR, E|SKR, E|SKR, 0|SKK, E|SKR, E|SKR,/*SKC*/
0|SKA, 0|FIN, E|SKR, E|SKR, E|SKR, E|SKR, E|SKR, S|ATR, S|ATR,/*SKA*/
N|SKE,N|V|L|FIN, E|SKR, N|SKV, E|SKR, E|SKR, E|SKR, S|ATR, S|ATR,/*ATR*/
0|SKE, V|L|FIN, E|SKR, 0|SKV, E|SKR, E|SKR, E|SKR,V|L|SKA,V|L|SKA,/*SKE*/
0|SKV, V|SKR, E|SKR, E|SKR, 0|QUO, E|SKR, E|SKV, S|VAL, S|VAL,/*SKV*/
V|SKL, V|L|FIN, S|VAL, S|VAL, E|SKR, S|VAL, V|SKV, S|VAL, S|VAL,/*VAL*/
S|QUO, E|SKR, S|QUO, S|QUO, V|SKL, 0|SLS, S|QUO, S|QUO, S|QUO,/*QUO*/
S|QUO, E|SKR, S|QUO, S|QUO, S|QUO, S|QUO, S|QUO, D|OD1,B|S|QUO,/*SLS*/
O|S|QUO, E|SKR,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO, D|OD2,O|S|QUO,/*OD1*/
O|S|QUO, E|SKR,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO, D|OD3,O|S|QUO,/*OD2*/
O|S|QUO, E|SKR,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO,O|S|QUO,/*OD3*/
0|SKL, L|FIN, E|SKR, E|SKR, E|SKR, E|SKR, 0|SKV,L|S|ATR,L|S|ATR /*SKL*/
};
#ifdef DEBUG
int AFread_debug = 0;
#endif
/*
* Read next record from Attribute File.
* Parse and fill in current attribute table and current buffer.
*/
char *
AFread(af)
AFILE_t af;
{ register char *p;
register ATTR_t a;
register int t;
register int c;
int tmpch;
int peekc, num, state, mb_cur_max, mbleng,
cattrBottom = &(af->AF_catr[ af->AF_natr -1 ]),
cbufBottom = &(af->AF_cbuf[ af->AF_rsiz ]);
char mb_buf[MB_LEN_MAX+2];
char* mbp = mb_buf;
mb_cur_max = MB_CUR_MAX;
a = af->AF_catr;
p = af->AF_cbuf;
a->AT_name = "";
a->AT_value = p;
for (peekc = '\n', num = 0, state = BOR; state != FIN; state = t&SMASK)
{ if ((c = peekc) == EOF)
c = getc(af->AF_iop);
peekc = EOF;
if (c < 0 || (int)a >= cattrBottom || (int)p >= cbufBottom )
return(NULL);
if (c == '\n')
{ while ((c = getc(af->AF_iop)) == '*') /* strip comments */
while ((c = getc(af->AF_iop)) != '\n' && c != EOF);
if (state == SKV || (c != ' ' && c != '\t'))
{ peekc = c;
c = '\n';
}
}
t = (!(c & 0200)) ? typetab[c & 0177] : ID;
#ifdef TRACE
fprintf(stderr,"peekc=`%c',c=`%c',type=%d,state=%d,action=0%o\n",
peekc,c,t,state/NTYPES,action[t + state]);
#endif
t = action[t + state];
if (t&E) /* error */
{
}
if (t&D) /* continue octal specification */
{ num = (num << 3) + (c - '0');
}
if (t&O) /* end octal specification */
{ peekc = c;
c = num;
num = 0;
}
if (t&B) /* map special backslash */
{ switch (c)
{ case 'b':
c = '\b'; break;
case 'f':
c = '\f'; break;
case 'n':
c = '\n'; break;
case 'r':
c = '\r'; break;
case 't':
c = '\t'; break;
}
}
if (t&N) /* terminate attribute name */
{ *p++ = '\0';
#ifdef DEBUG
if (AFread_debug)
fprintf(stderr,"Term Name `%s'\n",a->AT_name);
#endif
a->AT_value = p;
}
if (t&V) /* terminate attribute value */
{ *p++ = '\0';
#ifdef DEBUG
if (AFread_debug)
fprintf(stderr,"Term Value `%s'\n",a->AT_value);
#endif
}
if (t&L) /* terminate attribute list */
{ *p++ = '\0';
#ifdef DEBUG
if (AFread_debug)
fprintf(stderr,"Term List\n");
#endif
a++;
a->AT_name = p;
}
if (t&S) /* store char */
{
/*
* Only do multi-byte processing if we are not storing an
* octal character (e.g. "\012").
*/
if ((mb_cur_max > 1) && (c & 0200) && !(t&O)) {
mb_buf[0] = (char) c;
mb_buf[1] = '\0';
/*
* if this is a multi-byte character, note the following
* bytes for later processing. Getting the following bytes
* now elminates the possibility of confusing the following
* byte for a special character like backslash.
*/
for(mbleng=1; mblen(mb_buf, mbleng)<0 && mbleng <= mb_cur_max; mbleng++) {
if ((tmpch = getc(af->AF_iop)) == EOF) {
mb_buf[mbleng] = '\0';
mbleng = mb_cur_max + 1; /* mbleng>max == err */
break; /* so make sure. */
}
mb_buf[mbleng] = (char) tmpch;
}
mb_buf[mbleng] = '\0';
for (mbp = mb_buf; *mbp; )
*p++ = *mbp++;
} else {
*p++ = c;
}
}
}
#ifdef DEBUG
if (AFread_debug)
fprintf(stderr,"Term Record\n");
#endif
a->AT_name = NULL;
*p = '\0'; /* terminate record */
if (peekc != EOF)
ungetc(peekc,af->AF_iop);
return(p);
}