source: trunk/minix/servers/inet/minix3/queryparam.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 3.1 KB
Line 
1/* queryparam() - allow program parameters to be queried
2 * Author: Kees J. Bot
3 * 21 Apr 1994
4 */
5#define nil 0
6#include <stddef.h>
7#include <stdlib.h>
8#include <string.h>
9#include <sys/types.h>
10#include <minix3/queryparam.h>
11
12#if EXAMPLE
13struct stat st[2];
14
15struct export_param_list ex_st_list[]= {
16 QP_VARIABLE(st),
17 QP_ARRAY(st),
18 QP_FIELD(st_dev, struct stat),
19 QP_FIELD(st_ino, struct stat),
20 ...
21 QP_END()
22};
23
24struct buf { block_t b_blocknr; ... } *buf;
25size_t nr_bufs;
26
27struct export_param_list ex_buf_list[]=
28 QP_VECTOR(buf, buf, nr_bufs),
29 QP_FIELD(b_blocknr),
30 ...
31 QP_END()
32};
33
34struct export_params ex_st= { ex_st_list, 0 };
35struct export_params ex_buf= { ex_buf_list, 0 };
36#endif
37
38#define between(a, c, z) ((unsigned) ((c) - (a)) <= (unsigned) ((z) - (a)))
39
40static int isvar(int c)
41{
42 return between('a', c, 'z') || between('A', c, 'Z')
43 || between('0', c, '9') || c == '_';
44}
45
46static struct export_params *params;
47
48void qp_export(struct export_params *ex_params)
49{
50 /* Add a set of exported parameters. */
51
52 if (ex_params->next == nil) {
53 ex_params->next= params;
54 params= ex_params;
55 }
56}
57
58int queryparam(int qgetc(void), void **poffset, size_t *psize)
59{
60 char *prefix;
61 struct export_params *ep;
62 struct export_param_list *epl;
63 size_t offset= 0;
64 size_t size= -1;
65 size_t n;
66 static size_t retval;
67 int c, firstc;
68
69 firstc= c= (*qgetc)();
70 if (c == '&' || c == '$') c= (*qgetc)();
71 if (!isvar(c)) goto fail;
72
73 if ((ep= params) == nil) goto fail;
74 epl= ep->list;
75
76 while (c != 0 && c != ',') {
77 prefix= "x";
78 n= 0;
79
80 for (;;) {
81 while (epl->name == nil) {
82 if ((ep= ep->next) == nil) goto fail;
83 epl= ep->list;
84 }
85 if (strncmp(prefix, epl->name, n) == 0) {
86 prefix= epl->name;
87 while (prefix[n] != 0 && c == prefix[n]) {
88 n++;
89 c= (*qgetc)();
90 }
91 }
92 if (prefix[n] == 0 && (!isvar(c) || prefix[0] == '[')) {
93 /* Got a match. */
94 break;
95 }
96 epl++;
97 }
98
99 if (prefix[0] == '[') {
100 /* Array reference. */
101 size_t idx= 0, cnt= 1, max= size / epl->size;
102
103 while (between('0', c, '9')) {
104 idx= idx * 10 + (c - '0');
105 if (idx > max) goto fail;
106 c= (*qgetc)();
107 }
108 if (c == ':') {
109 cnt= 0;
110 while (between('0', (c= (*qgetc)()), '9')) {
111 cnt= cnt * 10 + (c - '0');
112 }
113 }
114 if (c != ']') goto fail;
115 if (idx + cnt > max) cnt= max - idx;
116 offset+= idx * epl->size;
117 size= cnt * epl->size;
118 c= (*qgetc)();
119 } else
120 if (epl->size == -1) {
121 /* Vector. */
122 offset= (size_t) * (void **) epl->offset;
123 size= (* (size_t *) epl[1].offset) * epl[1].size;
124 } else {
125 /* Variable or struct field. */
126 offset+= (size_t) epl->offset;
127 if ((size_t) epl->offset > size) goto fail;
128 size-= (size_t) epl->offset;
129 if (size < epl->size) goto fail;
130 size= epl->size;
131 }
132 }
133 if (firstc == '&' || firstc == '$') {
134 retval= firstc == '&' ? offset : size;
135 offset= (size_t) &retval;
136 size= sizeof(retval);
137 }
138 if (c != 0 && c != ',') goto fail;
139 *poffset= (void *) offset;
140 *psize= size;
141 return c != 0;
142fail:
143 while (c != 0 && c != ',') c= (*qgetc)();
144 *poffset= nil;
145 *psize= 0;
146 return c != 0;
147}
148
149/*
150 * $PchId: queryparam.c,v 1.1 2005/06/28 14:30:56 philip Exp $
151 */
Note: See TracBrowser for help on using the repository browser.