VM: simplify slab allocator
[minix.git] / servers / inet / queryparam.c
blob26bf5d7f4f19a81f1198eb829f11b3ee7b53acbf
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 "queryparam.h"
11 #if EXAMPLE
12 struct stat st[2];
14 struct export_param_list ex_st_list[]= {
15 QP_VARIABLE(st),
16 QP_ARRAY(st),
17 QP_FIELD(st_dev, struct stat),
18 QP_FIELD(st_ino, struct stat),
19 ...
20 QP_END()
23 struct buf { block_t b_blocknr; ... } *buf;
24 size_t nr_bufs;
26 struct export_param_list ex_buf_list[]=
27 QP_VECTOR(buf, buf, nr_bufs),
28 QP_FIELD(b_blocknr),
29 ...
30 QP_END()
33 struct export_params ex_st= { ex_st_list, 0 };
34 struct export_params ex_buf= { ex_buf_list, 0 };
35 #endif
37 #define between(a, c, z) ((unsigned) ((c) - (a)) <= (unsigned) ((z) - (a)))
39 static int isvar(int c)
41 return between('a', c, 'z') || between('A', c, 'Z')
42 || between('0', c, '9') || c == '_';
45 static struct export_params *params;
47 void qp_export(struct export_params *ex_params)
49 /* Add a set of exported parameters. */
51 if (ex_params->next == nil) {
52 ex_params->next= params;
53 params= ex_params;
57 int queryparam(int qgetc(void), void **poffset, size_t *psize)
59 char *prefix;
60 struct export_params *ep;
61 struct export_param_list *epl;
62 size_t offset= 0;
63 size_t size= -1;
64 size_t n;
65 static size_t retval;
66 int c, firstc;
68 firstc= c= (*qgetc)();
69 if (c == '&' || c == '$') c= (*qgetc)();
70 if (!isvar(c)) goto fail;
72 if ((ep= params) == nil) goto fail;
73 epl= ep->list;
75 while (c != 0 && c != ',') {
76 prefix= "x";
77 n= 0;
79 for (;;) {
80 while (epl->name == nil) {
81 if ((ep= ep->next) == nil) goto fail;
82 epl= ep->list;
84 if (strncmp(prefix, epl->name, n) == 0) {
85 prefix= epl->name;
86 while (prefix[n] != 0 && c == prefix[n]) {
87 n++;
88 c= (*qgetc)();
91 if (prefix[n] == 0 && (!isvar(c) || prefix[0] == '[')) {
92 /* Got a match. */
93 break;
95 epl++;
98 if (prefix[0] == '[') {
99 /* Array reference. */
100 size_t idx= 0, cnt= 1, max= size / epl->size;
102 while (between('0', c, '9')) {
103 idx= idx * 10 + (c - '0');
104 if (idx > max) goto fail;
105 c= (*qgetc)();
107 if (c == ':') {
108 cnt= 0;
109 while (between('0', (c= (*qgetc)()), '9')) {
110 cnt= cnt * 10 + (c - '0');
113 if (c != ']') goto fail;
114 if (idx + cnt > max) cnt= max - idx;
115 offset+= idx * epl->size;
116 size= cnt * epl->size;
117 c= (*qgetc)();
118 } else
119 if (epl->size == -1) {
120 /* Vector. */
121 offset= (size_t) * (void **) epl->offset;
122 size= (* (size_t *) epl[1].offset) * epl[1].size;
123 } else {
124 /* Variable or struct field. */
125 offset+= (size_t) epl->offset;
126 if ((size_t) epl->offset > size) goto fail;
127 size-= (size_t) epl->offset;
128 if (size < epl->size) goto fail;
129 size= epl->size;
132 if (firstc == '&' || firstc == '$') {
133 retval= firstc == '&' ? offset : size;
134 offset= (size_t) &retval;
135 size= sizeof(retval);
137 if (c != 0 && c != ',') goto fail;
138 *poffset= (void *) offset;
139 *psize= size;
140 return c != 0;
141 fail:
142 while (c != 0 && c != ',') c= (*qgetc)();
143 *poffset= nil;
144 *psize= 0;
145 return c != 0;
149 * $PchId: queryparam.c,v 1.1 2005/06/28 14:30:56 philip Exp $