1: # include <ingres.h>
2: # include <aux.h>
3: # include <tree.h>
4: # include "parser.h"
5: # include <catalog.h>
6: # include <pv.h>
7: # include <symbol.h>
8: # include <sccs.h>
9: # include "scanner.h"
10: # include <errors.h>
11:
12: SCCSID(@(#)par_util.c 8.2 2/14/85)
13:
14: /*
15: ** PAR_UTIL -- parser utility functions
16: **
17: ** These functions are generally unrelated except that they are
18: ** needed to operate the parser and are too small to be considered
19: ** seperate modules.
20: **
21: ** Defined Constants:
22: **
23: ** Defines:
24: ** timeofday -- convert arguments to minutes since midnight
25: ** tlprepend -- attach two target list components
26: ** header -- prints the header for a retrieve to terminal
27: ** patmat -- converts pattern matching characters in a string
28: ** permcom -- adds a command to the permit command vector
29: **
30: ** Requires:
31: ** nothing
32: **
33: ** Required By:
34: ** y.tab.c -- the grammar
35: **
36: ** Files:
37: ** none
38: **
39: ** Compilation Flags:
40: ** none
41: **
42: ** Trace Flags:
43: ** PAR_UTIL.C ~~ 62, 63
44: **
45: ** History:
46: ** 20 Dec 1978 -- written (rick)
47: */
48:
49:
50:
51:
52:
53:
54:
55:
56: /*
57: ** TIMEOFDAY -- convert 2 integers to minutes since midnight
58: **
59: ** Converts the hours and minutes parameters to minutes since midnight
60: ** performing some error (bounds) checking on the time.
61: **
62: ** To answer the question about what is midnight, both 0:00 and 24:00
63: ** are handled, but not the same way. The former is zero minutes from
64: ** midnight and the latter is 1440 minutes from midnight. (1440 is
65: ** 24 hrs times 60 minutes, or 1 minute past the end of the day.)
66: **
67: ** Parameters:
68: ** hrs -- an integer pointer to the hour
69: ** mins -- an integer pointer to the minutes
70: **
71: ** Returns:
72: ** integer time since midnight
73: **
74: ** Side Effects:
75: ** may detect an error and call par_error which never returns.
76: **
77: ** Requires:
78: ** that the pointers be on integer boundaries
79: **
80: ** Called By:
81: ** y.tab.c -- the grammar
82: **
83: ** Trace Flags:
84: ** none
85: **
86: ** Diagnostics:
87: ** BADHOURS -- No such hour
88: ** BADMINS -- No such minute
89: ** BAD24TIME -- only 24:00 allowed
90: **
91: ** Syserrs:
92: ** none
93: **
94: ** History:
95: ** 20 Dec 1978 -- written (rick)
96: */
97: timeofday(hrs, mins)
98: short *hrs;
99: short *mins;
100: {
101: register int h;
102: register int m;
103: register int rtval;
104:
105: h = *hrs;
106: m = *mins;
107: if (h > 24 || h < 0)
108: /* no such hour */
109: par_error(BADHOURS, WARN, iocv(h), 0);
110: if (m > 59 || m < 0)
111: /* no such minute */
112: par_error(BADMINS, WARN, iocv(m), 0);
113: if (h == 24)
114: {
115: h = 1440;
116: if (m != 0)
117: /* can only use 24:00 */
118: par_error(BAD24TIME, WARN, iocv(m), 0);
119: }
120: rtval = (h * 60) + m;
121: return (rtval);
122: }
123:
124:
125: /*
126: ** TLPREPEND -- combine two target list components
127: **
128: ** Attach two target list components to each other.
129: ** Neither component need be a single element. The
130: ** 'a' component will be attached at the extreme left
131: ** of the 'b' component.
132: **
133: ** Parameters:
134: ** a -- tl component to attach
135: ** b -- tl base for attaching
136: **
137: ** Returns:
138: ** nothing
139: **
140: ** Side Effects:
141: ** this routine is a side effect. It attaches a to b
142: ** and when it returns a is attached to b but the pointer
143: ** to b never changes (neither does the pointer to a)
144: **
145: ** Requires:
146: ** nothing
147: **
148: ** Called By:
149: ** y.tab.c -- the grammar
150: **
151: ** Trace Flags:
152: ** tlprepend ~~ 62.4
153: **
154: ** Diagnostics:
155: ** none
156: **
157: ** Syserrs:
158: ** none
159: **
160: ** History:
161: ** 20 Dec 1978 -- written (rick)
162: */
163:
164: QTREE *
165: tlprepend(a, b)
166: QTREE *a;
167: QTREE *b;
168: {
169: register QTREE *q;
170:
171: # ifdef xPTR1
172: tTfp(62, 4, "tlprepend\n");
173: # endif
174:
175: if (b==NULL)
176: return(a);
177: /* scan to the left end of b */
178: for (q = b; q->left != NULL; q = q->left)
179: ; /* no action */
180:
181: /* attach a to the end of b */
182: q->left = a;
183: return (b);
184: }
185:
186:
187:
188: /*
189: ** HEADER.C -- print header for retrieve to terminal
190: **
191: ** "setp" to reconstruct the field names and types and passing
192: ** them to the normal printhdr etc.
193: **
194: ** Defines:
195: ** header()
196: **
197: ** Requires:
198: ** printhdr - utility lib
199: ** beginhdr - utility lib
200: ** printeol - utility lib
201: ** printeh - utility lib
202: ** atoi - utility lib
203: ** Dc - vble, number of params in list
204: ** Dv - vble, list of parameters
205: **
206: ** Trace Flags:
207: ** none
208: **
209: ** History:
210: ** written (ancient history) (rick)
211: */
212: (pv)
213: PARM *pv;
214: {
215: int len;
216: HDRINFO *hptr;
217: HDRINFO *tptr;
218: int start = 1;
219: extern HDRINFO *Hdrptr;
220: extern HDRINFO *Fieldwidth;
221: extern int Hdr;
222:
223: Hdr = TRUE;
224: beginhdr();
225:
226:
227: for (; pv->pv_type != PV_EOF; pv += 2)
228: {
229: if ((pv[1].pv_val.pv_str[0] & I1MASK) == 'c')
230: {
231: tptr = (HDRINFO *) malloc(sizeof(HDRINFO));
232: if (start)
233: {
234: Hdrptr = tptr;
235: Fieldwidth = Hdrptr;
236: start = 0;
237: }
238: else
239: hptr->next = tptr;
240: hptr = tptr;
241: }
242:
243: len = atoi(&pv[1].pv_val.pv_str[1]);
244: printhdr(pv[1].pv_val.pv_str[0] & I1MASK, len, pv->pv_val.pv_str);
245:
246: if ((pv[1].pv_val.pv_str[0] & I1MASK) == 'c')
247: {
248: tptr->len = len;
249: tptr->len &= 0377;
250: tptr->next = NULL;
251: }
252: }
253: printeol();
254: printeh();
255: }
256:
257:
258:
259:
260:
261:
262: /*
263: ** PATMAT -- converts pattern matching characters in a string
264: **
265: ** Searches a string up to a null byte for one of the pattern
266: ** matching characters '*', '?', '[', and ']'. It then converts
267: ** these characters to their internal control character equivalents.
268: **
269: ** Parameters:
270: ** str -- the string to search
271: **
272: ** Returns:
273: ** 0 -- always
274: **
275: ** Side Effects:
276: ** none
277: **
278: ** Requires:
279: ** symbol.h
280: **
281: ** Called By:
282: ** y.tab.c -- grammar
283: **
284: ** Trace Flags:
285: ** none
286: **
287: ** Diagnostics:
288: ** none
289: **
290: ** Syserrs:
291: ** none
292: **
293: ** History:
294: ** written (ancient history) (rick)
295: ** amended (Heidi) -- checks for numbers after PAT_SPEC's
296: ** and does away with flags making pattern matching
297: ** characters legal in strings
298: */
299:
300:
301: /*
302: ** PATMAT
303: ** hunts through a string and converts the pattern matching
304: ** characters and replaces with the corresponding cntrl chars
305: */
306: patmat(str)
307: char *str;
308: {
309: register int i; /* index variables */
310: register char *p, *q, c;
311: extern int Qlflag;
312:
313: q = str;
314: for (p = str; *p; p++)
315: {
316: if (*p == '\\')
317: {
318: *q++ = *++p;
319: continue;
320: }
321: switch (*p)
322: {
323: case '#':
324: if (*(p + 1) == '#')
325: {
326: p++;
327: if ((c = *(p + 1)) == '0')
328: {
329: *q++ = PAT_GLOB;
330: p++;
331: }
332: else if (c >= '1' && c <= '9')
333: {
334: if ( !Qlflag ) /* target*/
335: Patspec_flag[c - '0'] = 1;
336: else /* qualifier */
337: {
338: if( Patspec_flag[c - '0'] == (TARGBIT | QUALBIT))
339: {
340: for (i=0; i<PATNUM; i++)
341: Patspec_flag[i] = 0;
342: par_error(DUPINDEX,WARN,0);
343: }
344: /* allows for repeated indices in
345: ** qualifier as long as index is not
346: ** mentioned in target
347: */
348: else
349: Patspec_flag[c - '0'] = Patspec_flag[c - '0'] | QUALBIT;
350: }
351: *q++ = PAT_SPEC;
352: }
353: else
354: par_error(NOINDEX,WARN,0);
355: continue;
356: }
357: else
358: *q++ = *p;
359: continue;
360:
361: case '*':
362: if (!Qlflag)
363: par_error(NOPATMAT, WARN, 0);
364: *q++ = PAT_ANY;
365: continue;
366:
367: case '?':
368: if (!Qlflag)
369: par_error(NOPATMAT, WARN, 0);
370: *q++ = PAT_ONE;
371: continue;
372:
373: case '[':
374: if (!Qlflag)
375: par_error(NOPATMAT, WARN, 0);
376: *q++ = PAT_LBRAC;
377: continue;
378:
379: case ']':
380: if (!Qlflag)
381: par_error(NOPATMAT, WARN, 0);
382: *q++ = PAT_RBRAC;
383: continue;
384:
385: default:
386: *q++ = *p;
387: continue;
388: }
389: }
390: *q = '\0';
391: return (0);
392: }
393: /*
394: ** PERMCOM -- map command allowed into protection catalog bits
395: **
396: ** translates the QMODE type symbols into the appropriate counterparts
397: ** for the permit statement allowed command vector. The manifest
398: ** constants are designed to be inclusive or'd together to form a
399: ** composite bit map of OK actions.
400: **
401: ** Parameters:
402: ** a -- the QMODE type symbol for the command to add
403: **
404: ** Returns:
405: ** none
406: **
407: ** Side Effects:
408: ** changes the variable Permcomd to reflect the additional permission
409: **
410: ** Requires:
411: ** Permcomd must be define globally
412: ** catalog.h for the proper constants
413: **
414: ** Called By:
415: ** y.tab.c -- the grammar
416: **
417: ** Trace Flags:
418: ** none
419: **
420: ** Diagnostics:
421: ** none
422: **
423: ** Syserrs:
424: ** bad QMODE(%d) -- a bad symbol has been passed for mapping
425: **
426: ** History:
427: ** 28 Dec 1978 -- written (rick)
428: */
429:
430: permcom(a)
431: int a;
432: {
433: extern int Permcomd;
434: switch (a)
435: {
436: case mdRETR:
437: Permcomd |= PRO_RETR;
438: break;
439:
440: case mdAPP:
441: Permcomd |= PRO_APP;
442: break;
443:
444: case mdREPL:
445: Permcomd |= PRO_REPL;
446: break;
447:
448: case mdDEL:
449: Permcomd |= PRO_DEL;
450: break;
451:
452: case -1:
453: Permcomd |= 0177777; /* all bits set */
454: break;
455:
456: default:
457: syserr("permcom: bad QMODE(%d)", a);
458: }
459: }
460:
461: char *
462: makestr(str)
463: register char *str;
464: {
465: register char *result;
466: register int len;
467:
468: len = length(str) + 1;
469:
470: result = (char *) need(Qbuf, len);
471:
472: bmove(str, result, len);
473:
474: return (result);
475: }
476:
477:
478: /*
479: ** QUALINDEX --
480: ** check to see if a PAT_SPEC index was used in a target
481: ** list and not in a qualifier list
482: **
483: ** Returns: 0 if ok
484: ** calls par_error if not ok
485: **
486: ** Called by: y.tab.c -grammar
487: */
488:
489: qualindex()
490: {
491: int i;
492:
493: for (i=0; i<PATNUM; i++)
494: {
495: if (Patspec_flag[i] == TARGBIT)
496: {
497: /* reset the rest of the flag array */
498: while (i++ < PATNUM)
499: Patspec_flag[i] = 0;
500: par_error(NOQUALINDX, WARN, 0);
501: }
502: Patspec_flag[i] = 0;
503: }
504: return(0);
505: }