|
|
1.1 root 1: /* pl2pe.c - presentation list to presentation element */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/psap/RCS/pl2pe.c,v 7.0 89/11/23 22:13:07 mrose Rel $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/psap/RCS/pl2pe.c,v 7.0 89/11/23 22:13:07 mrose Rel $
9: *
10: *
11: * $Log: pl2pe.c,v $
12: * Revision 7.0 89/11/23 22:13:07 mrose
13: * Release 6.0
14: *
15: */
16:
17: /*
18: * NOTICE
19: *
20: * Acquisition, use, and distribution of this module and related
21: * materials are subject to the restrictions of a license agreement.
22: * Consult the Preface in the User's Manual for the full terms of
23: * this agreement.
24: *
25: */
26:
27:
28: /* Presentation lists are a human-readable, unambiguous way of describing
29: a presentation element.
30:
31: SYNTAX: list :: "(" class code arguments ")"
32:
33: class :: "UNIV" / "APPL" / "CONT" / "PRIV"
34:
35: code :: name / number
36:
37: name :: letter (letter / digit / dash)*
38:
39: number :: "0x" [0-f] [0-f]* /
40: "0" [0-7] [0-7]* /
41: [1-9] [0-9]* /
42: "\"" (IA5 subset)* "\""
43:
44: arguments:: primitive / constructor
45:
46: primitive:: number number*
47:
48: constructor:: list*
49:
50: NOTE WELL: A single "number" must be representable in no more than
51: (sizeof (int)) bytes.
52: */
53:
54:
55: /* LINTLIBRARY */
56:
57: #include <ctype.h>
58: #include <stdio.h>
59: #include "psap.h"
60:
61: /* DATA */
62:
63: typedef struct PList {
64: u_char pl_code;
65: #define PL_CODE_LPAR 0
66: #define PL_CODE_NAME 1
67: #define PL_CODE_NUM 2
68: #define PL_CODE_RPAR 3
69:
70: union {
71: char un_pl_name[BUFSIZ];
72: int un_pl_num;
73: } pl_un;
74: #define pl_name pl_un.un_pl_name
75: #define pl_num pl_un.un_pl_num
76: } PList, *PL;
77:
78:
79: PE pl2pe_aux ();
80:
81: /* */
82:
83: PE pl2pe (ps)
84: register PS ps;
85: {
86: struct PList pls;
87: register PL pl = &pls;
88:
89: if (pl_read_lex (ps, pl) == NOTOK) {
90: if (ps -> ps_errno == PS_ERR_EOF)
91: ps -> ps_errno = PS_ERR_NONE;
92: return NULLPE;
93: }
94: if (pl -> pl_code != PL_CODE_LPAR)
95: return ps_seterr (ps, PS_ERR_XXX, NULLPE);
96:
97: return pl2pe_aux (ps, pl);
98: }
99:
100: /* */
101:
102: static PE pl2pe_aux (ps, pl)
103: register PS ps;
104: register PL pl;
105: {
106: PElementClass class;
107: PElementID id;
108: register PE pe;
109:
110: if (pl_read_class (ps, pl, &class) == NOTOK)
111: return NULLPE;
112: if (pl_read_id (ps, pl, class, &id) == NOTOK)
113: return NULLPE;
114:
115: if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
116: return ps_seterr (ps, PS_ERR_NMEM, NULLPE);
117:
118: if (pl_read_lex (ps, pl) == NOTOK)
119: return NULLPE;
120: switch (pl -> pl_code) {
121: case PL_CODE_LPAR:
122: if (pl_read_cons (ps, pl, &pe -> pe_cons) == NOTOK)
123: goto you_lose; /* else fall */
124: case PL_CODE_RPAR:
125: pe -> pe_form = PE_FORM_CONS;
126: break;
127:
128: case PL_CODE_NUM:
129: if (pl_read_prim (ps, pl, pe) == NOTOK)
130: goto you_lose;
131: break;
132:
133: default:
134: ps -> ps_errno = PS_ERR_XXX;
135: goto you_lose;
136: }
137: return pe;
138:
139: you_lose: ;
140: pe_free (pe);
141: return NULLPE;
142: }
143:
144: /* */
145:
146: static int pl_read_class (ps, pl, class)
147: register PS ps;
148: register PL pl;
149: register PElementClass *class;
150: {
151: register int i;
152:
153: if (pl_read_lex (ps, pl) == NOTOK)
154: return NOTOK;
155: if (pl -> pl_code != PL_CODE_NAME)
156: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
157:
158: if ((i = pl_read_name (pl -> pl_name, pe_classlist, pe_maxclass)) == NOTOK)
159: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
160:
161: *class = i;
162: return OK;
163: }
164:
165: /* */
166:
167: static int pl_read_id (ps, pl, class, id)
168: register PS ps;
169: register PL pl;
170: register PElementClass class;
171: register PElementID *id;
172: {
173: register int i;
174: register char **list;
175:
176: if (pl_read_lex (ps, pl) == NOTOK)
177: return NOTOK;
178: switch (pl -> pl_code) {
179: case PL_CODE_NAME:
180: switch (class) {
181: case PE_CLASS_UNIV:
182: list = pe_univlist, i = pe_maxuniv;
183: break;
184: case PE_CLASS_APPL:
185: list = pe_applist, i = pe_maxappl;
186: break;
187: default:
188: list = NULL, i = 0;
189: break;
190: case PE_CLASS_PRIV:
191: list = pe_privlist, i = pe_maxpriv;
192: break;
193: }
194: if ((i = pl_read_name (pl -> pl_name, list, i)) == NOTOK)
195: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
196: break;
197:
198: case PL_CODE_NUM:
199: i = pl -> pl_num;
200: break;
201:
202: default:
203: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
204: }
205:
206: *id = i;
207: return OK;
208: }
209:
210: /* */
211:
212: static int pl_read_name (name, list, n)
213: register char *name,
214: **list;
215: register int n;
216: {
217: register int i;
218: register char *bp;
219:
220: for (i = n; i > 0; i--)
221: if ((bp = *list++) && strcmp (bp, name) == 0)
222: return (n - i);
223:
224: return NOTOK;
225: }
226:
227: /* */
228:
229: static int pl_read_cons (ps, pl, pe)
230: register PS ps;
231: register PL pl;
232: register PE *pe;
233: {
234: register PE p,
235: q;
236:
237: if ((p = pl2pe_aux (ps, pl)) == NULLPE)
238: return NOTOK;
239: *pe = p;
240:
241: for (q = p;; q = q -> pe_next = p) {
242: if (pl_read_lex (ps, pl) == NOTOK)
243: return NOTOK;
244: switch (pl -> pl_code) {
245: case PL_CODE_LPAR:
246: if ((p = pl2pe_aux (ps, pl)) == NULLPE)
247: return NOTOK;
248: break;
249:
250: default:
251: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
252:
253: case PL_CODE_RPAR:
254: return OK;
255: }
256: }
257: }
258:
259: /* */
260:
261: static int pl_read_prim (ps, pl, pe)
262: register PS ps;
263: register PL pl;
264: register PE pe;
265: {
266: register int i,
267: len,
268: n;
269: register PElementData dp,
270: ep;
271:
272: if ((len = pl -> pl_num) == 0)
273: goto out;
274: if ((dp = PEDalloc (len)) == NULLPED)
275: return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
276:
277: pe -> pe_prim = dp, pe -> pe_len = len;
278:
279: for (ep = dp + len; dp < ep;) {
280: i = min (ep - dp, sizeof (int));
281: if (pl_read_lex (ps, pl) == NOTOK)
282: return NOTOK;
283: if (pl -> pl_code != PL_CODE_NUM)
284: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
285: n = pl -> pl_num;
286: while (i-- > 0)
287: *dp++ = (n >> (i * 8)) & 0xff;
288: }
289:
290: out: ;
291: if (pl_read_lex (ps, pl) == NOTOK)
292: return NOTOK;
293: if (pl -> pl_code != PL_CODE_RPAR)
294: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
295:
296: return OK;
297: }
298:
299: /* */
300:
301: #ifdef XXX
302: static int pl_read_lex (ps, pl)
303: register PS ps;
304: register PL pl;
305: {
306: int i = pl_read_lex_aux (ps, pl);
307:
308: fprintf (stderr, "pl_read_lex returns ");
309: if (i == NOTOK) {
310: fprintf (stderr, "NOTOK [%s]\n", ps_error (ps -> ps_errno));
311: return NOTOK;
312: }
313: switch (pl -> pl_code) {
314: case PL_CODE_LPAR:
315: fprintf (stderr, "LPAR");
316: break;
317: case PL_CODE_RPAR:
318: fprintf (stderr, "RPAR");
319: break;
320: case PL_CODE_NAME:
321: fprintf (stderr, "NAME \"%s\"", pl -> pl_name);
322: break;
323: case PL_CODE_NUM:
324: fprintf (stderr, "NUM 0x%x", pl -> pl_num);
325: break;
326: default:
327: fprintf (stderr, "code %d", pl -> pl_code);
328: break;
329: }
330: fprintf (stderr, "\n");
331: if (pl -> pl_code == PL_CODE_RPAR)
332: sleep(1);
333:
334: return i;
335: }
336:
337: #define pl_read_lex pl_read_lex_aux
338: #endif
339:
340: /* */
341:
342: static int pl_read_lex (ps, pl)
343: register PS ps;
344: register PL pl;
345: {
346: register int base,
347: n;
348: register char *bp;
349: byte c;
350:
351: do {
352: if (pl_read (ps, &c) == NOTOK)
353: return NOTOK;
354: } while (isspace (c));
355:
356: switch (c) {
357: case '(':
358: pl -> pl_code = PL_CODE_LPAR;
359: return OK;
360: case ')':
361: pl -> pl_code = PL_CODE_RPAR;
362: return OK;
363:
364: case ';':
365: do {
366: if (pl_read (ps, &c) == NOTOK)
367: return NOTOK;
368: } while (c != '\n');
369: return pl_read_lex (ps, pl);
370:
371: default:
372: if (isalpha (c)) {
373: pl -> pl_code = PL_CODE_NAME;
374: bp = pl -> pl_name;
375: while (isalnum (c) || c == '-') {
376: *bp++ = c;
377: if (pl_read (ps, &c) == NOTOK)
378: return NOTOK;
379: }
380: *bp = NULL;
381: ps -> ps_scratch = c;
382: return OK;
383: }
384:
385: if (c == '"') {
386: pl -> pl_code = PL_CODE_NUM;
387: for (n = 0;;) {
388: if (pl_read (ps, &c) == NOTOK)
389: return NOTOK;
390: if (c == '"') {
391: pl -> pl_num = n;
392: return OK;
393: }
394: n = (n << 8) | (c & 0xff);
395: }
396: }
397:
398: if (!isdigit (c))
399: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
400:
401: pl -> pl_code = PL_CODE_NUM;
402: if (c == '0') {
403: if (pl_read (ps, &c) == NOTOK)
404: return NOTOK;
405: if (c == 'x' || c == 'X') {
406: base = 16;
407: if (pl_read (ps, &c) == NOTOK)
408: return NOTOK;
409: }
410: else {
411: base = 8;
412: if (c < '0' || c > '7') {
413: pl -> pl_num = 0;
414: ps -> ps_scratch = c;
415: return OK;
416: }
417: }
418: }
419: else
420: base = 10;
421:
422: for (n = 0;;) {
423: switch (base) {
424: case 10:
425: if (c < '0' || c > '9')
426: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
427: break;
428:
429: case 8:
430: if (c < '0' || c > '7')
431: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
432: break;
433:
434: case 16:
435: if (c >= '0' && c <= '9')
436: break;
437: if (c >= 'A' && c <= 'F')
438: c += 'a' - 'A';
439: else
440: if (c < 'a' || c > 'f')
441: return ps_seterr (ps, PS_ERR_XXX, NOTOK);
442: c += '9' + 1 - 'a';
443: break;
444: }
445: n = (n * base) + c - '0';
446: if (pl_read (ps, &c) == NOTOK)
447: return NOTOK;
448: if (!isxdigit (c)) {
449: pl -> pl_num = n;
450: ps -> ps_scratch = c;
451: return OK;
452: }
453: }
454: }
455: }
456:
457: /* */
458:
459: static int pl_read (ps, c)
460: register PS ps;
461: register byte *c;
462: {
463: if (ps -> ps_scratch) {
464: *c = ps -> ps_scratch;
465: ps -> ps_scratch = 0;
466: return OK;
467: }
468:
469: return ps_read (ps, c, 1);
470: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.