1 /* queryparam() - allow program parameters to be queried
9 #include "queryparam.h"
14 struct export_param_list ex_st_list
[]= {
17 QP_FIELD(st_dev
, struct stat
),
18 QP_FIELD(st_ino
, struct stat
),
23 struct buf
{ block_t b_blocknr
; ... } *buf
;
26 struct export_param_list ex_buf_list
[]=
27 QP_VECTOR(buf
, buf
, nr_bufs
),
33 struct export_params ex_st
= { ex_st_list
, 0 };
34 struct export_params ex_buf
= { ex_buf_list
, 0 };
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
;
57 int queryparam(int qgetc(void), void **poffset
, size_t *psize
)
60 struct export_params
*ep
;
61 struct export_param_list
*epl
;
68 firstc
= c
= (*qgetc
)();
69 if (c
== '&' || c
== '$') c
= (*qgetc
)();
70 if (!isvar(c
)) goto fail
;
72 if ((ep
= params
) == nil
) goto fail
;
75 while (c
!= 0 && c
!= ',') {
80 while (epl
->name
== nil
) {
81 if ((ep
= ep
->next
) == nil
) goto fail
;
84 if (strncmp(prefix
, epl
->name
, n
) == 0) {
86 while (prefix
[n
] != 0 && c
== prefix
[n
]) {
91 if (prefix
[n
] == 0 && (!isvar(c
) || prefix
[0] == '[')) {
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
;
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
;
119 if (epl
->size
== -1) {
121 offset
= (size_t) * (void **) epl
->offset
;
122 size
= (* (size_t *) epl
[1].offset
) * epl
[1].size
;
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
;
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
;
142 while (c
!= 0 && c
!= ',') c
= (*qgetc
)();
149 * $PchId: queryparam.c,v 1.1 2005/06/28 14:30:56 philip Exp $