|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 8950 (0x22f6)
Types: TextFile
Names: »pl2pe.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/psap/pl2pe.c«
/* pl2pe.c - presentation list to presentation element */
#ifndef lint
static char *rcsid = "$Header: /f/osi/psap/RCS/pl2pe.c,v 6.0 89/03/18 23:38:47 mrose Rel $";
#endif
/*
* $Header: /f/osi/psap/RCS/pl2pe.c,v 6.0 89/03/18 23:38:47 mrose Rel $
*
*
* $Log: pl2pe.c,v $
* Revision 6.0 89/03/18 23:38:47 mrose
* Release 5.0
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
/* Presentation lists are a human-readable, unambiguous way of describing
a presentation element.
SYNTAX: list :: "(" class code arguments ")"
class :: "UNIV" / "APPL" / "CONT" / "PRIV"
code :: name / number
name :: letter (letter / digit / dash)*
number :: "0x" [0-f] [0-f]* /
"0" [0-7] [0-7]* /
[1-9] [0-9]* /
"\"" (IA5 subset)* "\""
arguments:: primitive / constructor
primitive:: number number*
constructor:: list*
NOTE WELL: A single "number" must be representable in no more than
(sizeof (int)) bytes.
*/
/* LINTLIBRARY */
#include <ctype.h>
#include <stdio.h>
#include "psap.h"
/* \f
DATA */
typedef struct PList {
u_char pl_code;
#define PL_CODE_LPAR 0
#define PL_CODE_NAME 1
#define PL_CODE_NUM 2
#define PL_CODE_RPAR 3
union {
char un_pl_name[BUFSIZ];
int un_pl_num;
} pl_un;
#define pl_name pl_un.un_pl_name
#define pl_num pl_un.un_pl_num
} PList, *PL;
PE pl2pe_aux ();
/* \f
*/
PE pl2pe (ps)
register PS ps;
{
struct PList pls;
register PL pl = &pls;
if (pl_read_lex (ps, pl) == NOTOK) {
if (ps -> ps_errno == PS_ERR_EOF)
ps -> ps_errno = PS_ERR_NONE;
return NULLPE;
}
if (pl -> pl_code != PL_CODE_LPAR)
return ps_seterr (ps, PS_ERR_XXX, NULLPE);
return pl2pe_aux (ps, pl);
}
/* \f
*/
static PE pl2pe_aux (ps, pl)
register PS ps;
register PL pl;
{
PElementClass class;
PElementID id;
register PE pe;
if (pl_read_class (ps, pl, &class) == NOTOK)
return NULLPE;
if (pl_read_id (ps, pl, class, &id) == NOTOK)
return NULLPE;
if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
return ps_seterr (ps, PS_ERR_NMEM, NULLPE);
if (pl_read_lex (ps, pl) == NOTOK)
return NULLPE;
switch (pl -> pl_code) {
case PL_CODE_LPAR:
if (pl_read_cons (ps, pl, &pe -> pe_cons) == NOTOK)
goto you_lose; /* else fall */
case PL_CODE_RPAR:
pe -> pe_form = PE_FORM_CONS;
break;
case PL_CODE_NUM:
if (pl_read_prim (ps, pl, pe) == NOTOK)
goto you_lose;
break;
default:
ps -> ps_errno = PS_ERR_XXX;
goto you_lose;
}
return pe;
you_lose: ;
pe_free (pe);
return NULLPE;
}
/* \f
*/
static int pl_read_class (ps, pl, class)
register PS ps;
register PL pl;
register PElementClass *class;
{
register int i;
if (pl_read_lex (ps, pl) == NOTOK)
return NOTOK;
if (pl -> pl_code != PL_CODE_NAME)
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
if ((i = pl_read_name (pl -> pl_name, pe_classlist, pe_maxclass)) == NOTOK)
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
*class = i;
return OK;
}
/* \f
*/
static int pl_read_id (ps, pl, class, id)
register PS ps;
register PL pl;
register PElementClass class;
register PElementID *id;
{
register int i;
register char **list;
if (pl_read_lex (ps, pl) == NOTOK)
return NOTOK;
switch (pl -> pl_code) {
case PL_CODE_NAME:
switch (class) {
case PE_CLASS_UNIV:
list = pe_univlist, i = pe_maxuniv;
break;
case PE_CLASS_APPL:
list = pe_applist, i = pe_maxappl;
break;
default:
list = NULL, i = 0;
break;
case PE_CLASS_PRIV:
list = pe_privlist, i = pe_maxpriv;
break;
}
if ((i = pl_read_name (pl -> pl_name, list, i)) == NOTOK)
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
break;
case PL_CODE_NUM:
i = pl -> pl_num;
break;
default:
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
}
*id = i;
return OK;
}
/* \f
*/
static int pl_read_name (name, list, n)
register char *name,
**list;
register int n;
{
register int i;
register char *bp;
for (i = n; i > 0; i--)
if ((bp = *list++) && strcmp (bp, name) == 0)
return (n - i);
return NOTOK;
}
/* \f
*/
static int pl_read_cons (ps, pl, pe)
register PS ps;
register PL pl;
register PE *pe;
{
register PE p,
q;
if ((p = pl2pe_aux (ps, pl)) == NULLPE)
return NOTOK;
*pe = p;
for (q = p;; q = q -> pe_next = p) {
if (pl_read_lex (ps, pl) == NOTOK)
return NOTOK;
switch (pl -> pl_code) {
case PL_CODE_LPAR:
if ((p = pl2pe_aux (ps, pl)) == NULLPE)
return NOTOK;
break;
default:
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
case PL_CODE_RPAR:
return OK;
}
}
}
/* \f
*/
static int pl_read_prim (ps, pl, pe)
register PS ps;
register PL pl;
register PE pe;
{
register int i,
len,
n;
register PElementData dp,
ep;
if ((len = pl -> pl_num) == 0)
goto out;
if ((dp = PEDalloc (len)) == NULLPED)
return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
pe -> pe_prim = dp, pe -> pe_len = len;
for (ep = dp + len; dp < ep;) {
i = min (ep - dp, sizeof (int));
if (pl_read_lex (ps, pl) == NOTOK)
return NOTOK;
if (pl -> pl_code != PL_CODE_NUM)
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
n = pl -> pl_num;
while (i-- > 0)
*dp++ = (n >> (i * 8)) & 0xff;
}
out: ;
if (pl_read_lex (ps, pl) == NOTOK)
return NOTOK;
if (pl -> pl_code != PL_CODE_RPAR)
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
return OK;
}
/* \f
*/
#ifdef XXX
static int pl_read_lex (ps, pl)
register PS ps;
register PL pl;
{
int i = pl_read_lex_aux (ps, pl);
fprintf (stderr, "pl_read_lex returns ");
if (i == NOTOK) {
fprintf (stderr, "NOTOK [%s]\n", ps_error (ps -> ps_errno));
return NOTOK;
}
switch (pl -> pl_code) {
case PL_CODE_LPAR:
fprintf (stderr, "LPAR");
break;
case PL_CODE_RPAR:
fprintf (stderr, "RPAR");
break;
case PL_CODE_NAME:
fprintf (stderr, "NAME \"%s\"", pl -> pl_name);
break;
case PL_CODE_NUM:
fprintf (stderr, "NUM 0x%x", pl -> pl_num);
break;
default:
fprintf (stderr, "code %d", pl -> pl_code);
break;
}
fprintf (stderr, "\n");
if (pl -> pl_code == PL_CODE_RPAR)
sleep(1);
return i;
}
#define pl_read_lex pl_read_lex_aux
#endif
/* \f
*/
static int pl_read_lex (ps, pl)
register PS ps;
register PL pl;
{
register int base,
n;
register char *bp;
byte c;
do {
if (pl_read (ps, &c) == NOTOK)
return NOTOK;
} while (isspace (c));
switch (c) {
case '(':
pl -> pl_code = PL_CODE_LPAR;
return OK;
case ')':
pl -> pl_code = PL_CODE_RPAR;
return OK;
case ';':
do {
if (pl_read (ps, &c) == NOTOK)
return NOTOK;
} while (c != '\n');
return pl_read_lex (ps, pl);
default:
if (isalpha (c)) {
pl -> pl_code = PL_CODE_NAME;
bp = pl -> pl_name;
while (isalnum (c) || c == '-') {
*bp++ = c;
if (pl_read (ps, &c) == NOTOK)
return NOTOK;
}
*bp = NULL;
ps -> ps_scratch = c;
return OK;
}
if (c == '"') {
pl -> pl_code = PL_CODE_NUM;
for (n = 0;;) {
if (pl_read (ps, &c) == NOTOK)
return NOTOK;
if (c == '"') {
pl -> pl_num = n;
return OK;
}
n = (n << 8) | (c & 0xff);
}
}
if (!isdigit (c))
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
pl -> pl_code = PL_CODE_NUM;
if (c == '0') {
if (pl_read (ps, &c) == NOTOK)
return NOTOK;
if (c == 'x' || c == 'X') {
base = 16;
if (pl_read (ps, &c) == NOTOK)
return NOTOK;
}
else {
base = 8;
if (c < '0' || c > '7') {
pl -> pl_num = 0;
ps -> ps_scratch = c;
return OK;
}
}
}
else
base = 10;
for (n = 0;;) {
switch (base) {
case 10:
if (c < '0' || c > '9')
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
break;
case 8:
if (c < '0' || c > '7')
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
break;
case 16:
if (c >= '0' && c <= '9')
break;
if (c >= 'A' && c <= 'F')
c += 'a' - 'A';
else
if (c < 'a' || c > 'f')
return ps_seterr (ps, PS_ERR_XXX, NOTOK);
c += '9' + 1 - 'a';
break;
}
n = (n * base) + c - '0';
if (pl_read (ps, &c) == NOTOK)
return NOTOK;
if (!isxdigit (c)) {
pl -> pl_num = n;
ps -> ps_scratch = c;
return OK;
}
}
}
}
/* \f
*/
static int pl_read (ps, c)
register PS ps;
register byte *c;
{
if (ps -> ps_scratch) {
*c = ps -> ps_scratch;
ps -> ps_scratch = 0;
return OK;
}
return ps_read (ps, c, 1);
}