GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: rpc_parse.c,v 1.20 2016/01/15 10:14:32 jasper Exp $ */ |
||
2 |
/* $NetBSD: rpc_parse.c,v 1.5 1995/08/29 23:05:55 cgd Exp $ */ |
||
3 |
|||
4 |
/* |
||
5 |
* Copyright (c) 2010, Oracle America, Inc. |
||
6 |
* |
||
7 |
* Redistribution and use in source and binary forms, with or without |
||
8 |
* modification, are permitted provided that the following conditions are |
||
9 |
* met: |
||
10 |
* |
||
11 |
* * Redistributions of source code must retain the above copyright |
||
12 |
* notice, this list of conditions and the following disclaimer. |
||
13 |
* * Redistributions in binary form must reproduce the above |
||
14 |
* copyright notice, this list of conditions and the following |
||
15 |
* disclaimer in the documentation and/or other materials |
||
16 |
* provided with the distribution. |
||
17 |
* * Neither the name of the "Oracle America, Inc." nor the names of its |
||
18 |
* contributors may be used to endorse or promote products derived |
||
19 |
* from this software without specific prior written permission. |
||
20 |
* |
||
21 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||
22 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||
23 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
||
24 |
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||
25 |
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
||
26 |
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||
27 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
||
28 |
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
29 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||
30 |
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||
31 |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||
32 |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
33 |
*/ |
||
34 |
|||
35 |
/* |
||
36 |
* rpc_parse.c, Parser for the RPC protocol compiler |
||
37 |
*/ |
||
38 |
#include <stdio.h> |
||
39 |
#include <stdlib.h> |
||
40 |
#include <string.h> |
||
41 |
#include "rpc/types.h" |
||
42 |
#include "rpc_scan.h" |
||
43 |
#include "rpc_parse.h" |
||
44 |
#include "rpc_util.h" |
||
45 |
|||
46 |
#define ARGNAME "arg" |
||
47 |
|||
48 |
static void isdefined(definition *); |
||
49 |
static void def_struct(definition *); |
||
50 |
static void def_program(definition *); |
||
51 |
static void def_enum(definition *); |
||
52 |
static void def_const(definition *); |
||
53 |
static void def_union(definition *); |
||
54 |
static void def_typedef(definition *); |
||
55 |
static void get_declaration(declaration *, defkind); |
||
56 |
static void get_prog_declaration(declaration *, defkind, int); |
||
57 |
static void get_type(char **, char **, defkind); |
||
58 |
static void unsigned_dec(char **); |
||
59 |
|||
60 |
/* |
||
61 |
* return the next definition you see |
||
62 |
*/ |
||
63 |
definition * |
||
64 |
get_definition(void) |
||
65 |
{ |
||
66 |
definition *defp; |
||
67 |
1836 |
token tok; |
|
68 |
|||
69 |
918 |
defp = malloc(sizeof(definition)); |
|
70 |
918 |
get_token(&tok); |
|
71 |
✓✓✓✓ ✓✓✓✗ |
918 |
switch (tok.kind) { |
72 |
case TOK_STRUCT: |
||
73 |
294 |
def_struct(defp); |
|
74 |
294 |
break; |
|
75 |
case TOK_UNION: |
||
76 |
42 |
def_union(defp); |
|
77 |
42 |
break; |
|
78 |
case TOK_TYPEDEF: |
||
79 |
60 |
def_typedef(defp); |
|
80 |
60 |
break; |
|
81 |
case TOK_ENUM: |
||
82 |
39 |
def_enum(defp); |
|
83 |
39 |
break; |
|
84 |
case TOK_PROGRAM: |
||
85 |
48 |
def_program(defp); |
|
86 |
48 |
break; |
|
87 |
case TOK_CONST: |
||
88 |
390 |
def_const(defp); |
|
89 |
390 |
break; |
|
90 |
case TOK_EOF: |
||
91 |
45 |
free(defp); |
|
92 |
45 |
return (NULL); |
|
93 |
default: |
||
94 |
error("definition keyword expected"); |
||
95 |
} |
||
96 |
873 |
scan(TOK_SEMICOLON, &tok); |
|
97 |
873 |
isdefined(defp); |
|
98 |
873 |
return (defp); |
|
99 |
918 |
} |
|
100 |
|||
101 |
static void |
||
102 |
isdefined(defp) |
||
103 |
definition *defp; |
||
104 |
{ |
||
105 |
1746 |
STOREVAL(&defined, defp); |
|
106 |
873 |
} |
|
107 |
|||
108 |
static void |
||
109 |
def_struct(defp) |
||
110 |
definition *defp; |
||
111 |
{ |
||
112 |
588 |
token tok; |
|
113 |
294 |
declaration dec; |
|
114 |
decl_list *decls; |
||
115 |
decl_list **tailp; |
||
116 |
|||
117 |
294 |
defp->def_kind = DEF_STRUCT; |
|
118 |
|||
119 |
294 |
scan(TOK_IDENT, &tok); |
|
120 |
294 |
defp->def_name = tok.str; |
|
121 |
294 |
scan(TOK_LBRACE, &tok); |
|
122 |
294 |
tailp = &defp->def.st.decls; |
|
123 |
294 |
do { |
|
124 |
1026 |
get_declaration(&dec, DEF_STRUCT); |
|
125 |
1026 |
decls = malloc(sizeof(decl_list)); |
|
126 |
1026 |
decls->decl = dec; |
|
127 |
1026 |
*tailp = decls; |
|
128 |
1026 |
tailp = &decls->next; |
|
129 |
1026 |
scan(TOK_SEMICOLON, &tok); |
|
130 |
1026 |
peek(&tok); |
|
131 |
✓✓ | 1026 |
} while (tok.kind != TOK_RBRACE); |
132 |
294 |
get_token(&tok); |
|
133 |
294 |
*tailp = NULL; |
|
134 |
294 |
} |
|
135 |
|||
136 |
static void |
||
137 |
def_program(defp) |
||
138 |
definition *defp; |
||
139 |
{ |
||
140 |
96 |
token tok; |
|
141 |
48 |
declaration dec; |
|
142 |
decl_list *decls; |
||
143 |
decl_list **tailp; |
||
144 |
version_list *vlist; |
||
145 |
version_list **vtailp; |
||
146 |
proc_list *plist; |
||
147 |
proc_list **ptailp; |
||
148 |
int num_args; |
||
149 |
bool_t isvoid = FALSE; /* whether first argument is void */ |
||
150 |
48 |
defp->def_kind = DEF_PROGRAM; |
|
151 |
48 |
scan(TOK_IDENT, &tok); |
|
152 |
48 |
defp->def_name = tok.str; |
|
153 |
48 |
scan(TOK_LBRACE, &tok); |
|
154 |
48 |
vtailp = &defp->def.pr.versions; |
|
155 |
48 |
tailp = &defp->def.st.decls; |
|
156 |
48 |
scan(TOK_VERSION, &tok); |
|
157 |
48 |
do { |
|
158 |
63 |
scan(TOK_IDENT, &tok); |
|
159 |
63 |
vlist = malloc(sizeof(version_list)); |
|
160 |
63 |
vlist->vers_name = tok.str; |
|
161 |
63 |
scan(TOK_LBRACE, &tok); |
|
162 |
63 |
ptailp = &vlist->procs; |
|
163 |
63 |
do { |
|
164 |
/* get result type */ |
||
165 |
342 |
plist = malloc(sizeof(proc_list)); |
|
166 |
342 |
get_type(&plist->res_prefix, &plist->res_type, |
|
167 |
DEF_PROGRAM); |
||
168 |
✗✓ | 342 |
if (streq(plist->res_type, "opaque")) { |
169 |
error("illegal result type"); |
||
170 |
} |
||
171 |
342 |
scan(TOK_IDENT, &tok); |
|
172 |
342 |
plist->proc_name = tok.str; |
|
173 |
342 |
scan(TOK_LPAREN, &tok); |
|
174 |
/* get args - first one*/ |
||
175 |
num_args = 1; |
||
176 |
isvoid = FALSE; |
||
177 |
/* type of DEF_PROGRAM in the first |
||
178 |
* get_prog_declaration and DEF_STURCT in the next |
||
179 |
* allows void as argument if it is the only argument |
||
180 |
*/ |
||
181 |
342 |
get_prog_declaration(&dec, DEF_PROGRAM, num_args); |
|
182 |
✓✓ | 342 |
if (streq(dec.type, "void")) |
183 |
78 |
isvoid = TRUE; |
|
184 |
342 |
decls = malloc(sizeof(decl_list)); |
|
185 |
342 |
plist->args.decls = decls; |
|
186 |
342 |
decls->decl = dec; |
|
187 |
342 |
tailp = &decls->next; |
|
188 |
/* get args */ |
||
189 |
✗✓ | 684 |
while (peekscan(TOK_COMMA, &tok)) { |
190 |
num_args++; |
||
191 |
get_prog_declaration(&dec, DEF_STRUCT, |
||
192 |
num_args); |
||
193 |
decls = malloc(sizeof(decl_list)); |
||
194 |
decls->decl = dec; |
||
195 |
*tailp = decls; |
||
196 |
if (streq(dec.type, "void")) |
||
197 |
isvoid = TRUE; |
||
198 |
tailp = &decls->next; |
||
199 |
} |
||
200 |
/* multiple arguments are only allowed in newstyle */ |
||
201 |
✗✓ | 342 |
if (!newstyle && num_args > 1) { |
202 |
error("only one argument is allowed"); |
||
203 |
} |
||
204 |
✗✓ | 342 |
if (isvoid && num_args > 1) { |
205 |
error("illegal use of void in program definition"); |
||
206 |
} |
||
207 |
342 |
*tailp = NULL; |
|
208 |
342 |
scan(TOK_RPAREN, &tok); |
|
209 |
342 |
scan(TOK_EQUAL, &tok); |
|
210 |
342 |
scan_num(&tok); |
|
211 |
342 |
scan(TOK_SEMICOLON, &tok); |
|
212 |
342 |
plist->proc_num = tok.str; |
|
213 |
342 |
plist->arg_num = num_args; |
|
214 |
342 |
*ptailp = plist; |
|
215 |
342 |
ptailp = &plist->next; |
|
216 |
342 |
peek(&tok); |
|
217 |
✓✓ | 342 |
} while (tok.kind != TOK_RBRACE); |
218 |
63 |
*ptailp = NULL; |
|
219 |
63 |
*vtailp = vlist; |
|
220 |
63 |
vtailp = &vlist->next; |
|
221 |
63 |
scan(TOK_RBRACE, &tok); |
|
222 |
63 |
scan(TOK_EQUAL, &tok); |
|
223 |
63 |
scan_num(&tok); |
|
224 |
63 |
vlist->vers_num = tok.str; |
|
225 |
/* make the argument structure name for each arg*/ |
||
226 |
✓✓ | 810 |
for (plist = vlist->procs; plist != NULL; |
227 |
342 |
plist = plist->next) { |
|
228 |
684 |
plist->args.argname = make_argname(plist->proc_name, |
|
229 |
342 |
vlist->vers_num); |
|
230 |
/* free the memory ??*/ |
||
231 |
} |
||
232 |
63 |
scan(TOK_SEMICOLON, &tok); |
|
233 |
63 |
scan2(TOK_VERSION, TOK_RBRACE, &tok); |
|
234 |
✓✓ | 63 |
} while (tok.kind == TOK_VERSION); |
235 |
48 |
scan(TOK_EQUAL, &tok); |
|
236 |
48 |
scan_num(&tok); |
|
237 |
48 |
defp->def.pr.prog_num = tok.str; |
|
238 |
48 |
*vtailp = NULL; |
|
239 |
48 |
} |
|
240 |
|||
241 |
|||
242 |
static void |
||
243 |
def_enum(defp) |
||
244 |
definition *defp; |
||
245 |
{ |
||
246 |
78 |
token tok; |
|
247 |
enumval_list *elist; |
||
248 |
enumval_list **tailp; |
||
249 |
|||
250 |
39 |
defp->def_kind = DEF_ENUM; |
|
251 |
39 |
scan(TOK_IDENT, &tok); |
|
252 |
39 |
defp->def_name = tok.str; |
|
253 |
39 |
scan(TOK_LBRACE, &tok); |
|
254 |
39 |
tailp = &defp->def.en.vals; |
|
255 |
39 |
do { |
|
256 |
312 |
scan(TOK_IDENT, &tok); |
|
257 |
312 |
elist = malloc(sizeof(enumval_list)); |
|
258 |
312 |
elist->name = tok.str; |
|
259 |
312 |
elist->assignment = NULL; |
|
260 |
312 |
scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); |
|
261 |
✓✗ | 312 |
if (tok.kind == TOK_EQUAL) { |
262 |
312 |
scan_num(&tok); |
|
263 |
312 |
elist->assignment = tok.str; |
|
264 |
312 |
scan2(TOK_COMMA, TOK_RBRACE, &tok); |
|
265 |
312 |
} |
|
266 |
312 |
*tailp = elist; |
|
267 |
312 |
tailp = &elist->next; |
|
268 |
✓✓ | 312 |
} while (tok.kind != TOK_RBRACE); |
269 |
39 |
*tailp = NULL; |
|
270 |
39 |
} |
|
271 |
|||
272 |
static void |
||
273 |
def_const(defp) |
||
274 |
definition *defp; |
||
275 |
{ |
||
276 |
780 |
token tok; |
|
277 |
|||
278 |
390 |
defp->def_kind = DEF_CONST; |
|
279 |
390 |
scan(TOK_IDENT, &tok); |
|
280 |
390 |
defp->def_name = tok.str; |
|
281 |
390 |
scan(TOK_EQUAL, &tok); |
|
282 |
390 |
scan2(TOK_IDENT, TOK_STRCONST, &tok); |
|
283 |
390 |
defp->def.co = tok.str; |
|
284 |
390 |
} |
|
285 |
|||
286 |
static void |
||
287 |
def_union(defp) |
||
288 |
definition *defp; |
||
289 |
{ |
||
290 |
84 |
token tok; |
|
291 |
42 |
declaration dec; |
|
292 |
case_list *cases; |
||
293 |
case_list **tailp; |
||
294 |
int flag; |
||
295 |
|||
296 |
42 |
defp->def_kind = DEF_UNION; |
|
297 |
42 |
scan(TOK_IDENT, &tok); |
|
298 |
42 |
defp->def_name = tok.str; |
|
299 |
42 |
scan(TOK_SWITCH, &tok); |
|
300 |
42 |
scan(TOK_LPAREN, &tok); |
|
301 |
42 |
get_declaration(&dec, DEF_UNION); |
|
302 |
42 |
defp->def.un.enum_decl = dec; |
|
303 |
42 |
tailp = &defp->def.un.cases; |
|
304 |
42 |
scan(TOK_RPAREN, &tok); |
|
305 |
42 |
scan(TOK_LBRACE, &tok); |
|
306 |
42 |
scan(TOK_CASE, &tok); |
|
307 |
✓✓ | 192 |
while (tok.kind == TOK_CASE) { |
308 |
54 |
scan2(TOK_IDENT, TOK_CHARCONST, &tok); |
|
309 |
54 |
cases = malloc(sizeof(case_list)); |
|
310 |
54 |
cases->case_name = tok.str; |
|
311 |
54 |
scan(TOK_COLON, &tok); |
|
312 |
/* now peek at next token */ |
||
313 |
flag=0; |
||
314 |
✗✓ | 54 |
if (peekscan(TOK_CASE,&tok)) { |
315 |
do { |
||
316 |
scan2(TOK_IDENT, TOK_CHARCONST, &tok); |
||
317 |
cases->contflag=1; /* continued case statement */ |
||
318 |
*tailp = cases; |
||
319 |
tailp = &cases->next; |
||
320 |
cases = malloc(sizeof(case_list)); |
||
321 |
cases->case_name = tok.str; |
||
322 |
scan(TOK_COLON, &tok); |
||
323 |
} while (peekscan(TOK_CASE,&tok)); |
||
324 |
✗✓ | 54 |
} else if (flag) { |
325 |
*tailp = cases; |
||
326 |
tailp = &cases->next; |
||
327 |
cases = malloc(sizeof(case_list)); |
||
328 |
} |
||
329 |
54 |
get_declaration(&dec, DEF_UNION); |
|
330 |
54 |
cases->case_decl = dec; |
|
331 |
54 |
cases->contflag=0; /* no continued case statement */ |
|
332 |
54 |
*tailp = cases; |
|
333 |
54 |
tailp = &cases->next; |
|
334 |
54 |
scan(TOK_SEMICOLON, &tok); |
|
335 |
|||
336 |
54 |
scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); |
|
337 |
} |
||
338 |
42 |
*tailp = NULL; |
|
339 |
|||
340 |
✓✓ | 42 |
if (tok.kind == TOK_DEFAULT) { |
341 |
30 |
scan(TOK_COLON, &tok); |
|
342 |
30 |
get_declaration(&dec, DEF_UNION); |
|
343 |
30 |
defp->def.un.default_decl = malloc(sizeof(declaration)); |
|
344 |
30 |
*defp->def.un.default_decl = dec; |
|
345 |
30 |
scan(TOK_SEMICOLON, &tok); |
|
346 |
30 |
scan(TOK_RBRACE, &tok); |
|
347 |
30 |
} else { |
|
348 |
12 |
defp->def.un.default_decl = NULL; |
|
349 |
} |
||
350 |
42 |
} |
|
351 |
|||
352 |
static char *reserved_words[] = { |
||
353 |
"array", |
||
354 |
"bytes", |
||
355 |
"destroy", |
||
356 |
"free", |
||
357 |
"getpos", |
||
358 |
"inline", |
||
359 |
"pointer", |
||
360 |
"reference", |
||
361 |
"setpos", |
||
362 |
"sizeof", |
||
363 |
"union", |
||
364 |
"vector", |
||
365 |
NULL |
||
366 |
}; |
||
367 |
|||
368 |
static char *reserved_types[] = { |
||
369 |
"opaque", |
||
370 |
"string", |
||
371 |
NULL |
||
372 |
}; |
||
373 |
|||
374 |
/* check that the given name is not one that would eventually result in |
||
375 |
xdr routines that would conflict with internal XDR routines. */ |
||
376 |
static void |
||
377 |
check_type_name(char *name, int new_type) |
||
378 |
{ |
||
379 |
int i; |
||
380 |
2466 |
char tmp[100]; |
|
381 |
|||
382 |
✓✓ | 32058 |
for (i = 0; reserved_words[i] != NULL; i++) { |
383 |
✗✓ | 14796 |
if (strcmp(name, reserved_words[i]) == 0) { |
384 |
snprintf(tmp, sizeof tmp, |
||
385 |
"illegal (reserved) name :\'%s\' in type definition", name); |
||
386 |
error(tmp); |
||
387 |
} |
||
388 |
} |
||
389 |
✓✓ | 1233 |
if (new_type) { |
390 |
✓✓ | 360 |
for (i = 0; reserved_types[i] != NULL; i++) { |
391 |
✗✓ | 120 |
if (strcmp(name, reserved_types[i]) == 0) { |
392 |
snprintf(tmp, sizeof tmp, |
||
393 |
"illegal (reserved) name :\'%s\' in" |
||
394 |
" type definition", name); |
||
395 |
error(tmp); |
||
396 |
} |
||
397 |
} |
||
398 |
} |
||
399 |
1233 |
} |
|
400 |
|||
401 |
static void |
||
402 |
def_typedef(defp) |
||
403 |
definition *defp; |
||
404 |
{ |
||
405 |
120 |
declaration dec; |
|
406 |
|||
407 |
60 |
defp->def_kind = DEF_TYPEDEF; |
|
408 |
60 |
get_declaration(&dec, DEF_TYPEDEF); |
|
409 |
60 |
defp->def_name = dec.name; |
|
410 |
60 |
check_type_name(dec.name, 1); |
|
411 |
60 |
defp->def.ty.old_prefix = dec.prefix; |
|
412 |
60 |
defp->def.ty.old_type = dec.type; |
|
413 |
60 |
defp->def.ty.rel = dec.rel; |
|
414 |
60 |
defp->def.ty.array_max = dec.array_max; |
|
415 |
60 |
} |
|
416 |
|||
417 |
static void |
||
418 |
get_declaration(dec, dkind) |
||
419 |
declaration *dec; |
||
420 |
defkind dkind; |
||
421 |
{ |
||
422 |
2424 |
token tok; |
|
423 |
|||
424 |
1212 |
get_type(&dec->prefix, &dec->type, dkind); |
|
425 |
1212 |
dec->rel = REL_ALIAS; |
|
426 |
✓✓ | 1212 |
if (streq(dec->type, "void")) { |
427 |
39 |
return; |
|
428 |
} |
||
429 |
|||
430 |
1173 |
check_type_name(dec->type, 0); |
|
431 |
|||
432 |
1173 |
scan2(TOK_STAR, TOK_IDENT, &tok); |
|
433 |
✓✓ | 1173 |
if (tok.kind == TOK_STAR) { |
434 |
21 |
dec->rel = REL_POINTER; |
|
435 |
21 |
scan(TOK_IDENT, &tok); |
|
436 |
21 |
} |
|
437 |
1173 |
dec->name = tok.str; |
|
438 |
✓✓ | 1173 |
if (peekscan(TOK_LBRACKET, &tok)) { |
439 |
✗✓ | 57 |
if (dec->rel == REL_POINTER) { |
440 |
error("no array-of-pointer declarations -- use typedef"); |
||
441 |
} |
||
442 |
57 |
dec->rel = REL_VECTOR; |
|
443 |
57 |
scan_num(&tok); |
|
444 |
57 |
dec->array_max = tok.str; |
|
445 |
57 |
scan(TOK_RBRACKET, &tok); |
|
446 |
✓✓ | 1173 |
} else if (peekscan(TOK_LANGLE, &tok)) { |
447 |
✗✓ | 123 |
if (dec->rel == REL_POINTER) { |
448 |
error("no array-of-pointer declarations -- use typedef"); |
||
449 |
} |
||
450 |
123 |
dec->rel = REL_ARRAY; |
|
451 |
✓✓ | 123 |
if (peekscan(TOK_RANGLE, &tok)) { |
452 |
27 |
dec->array_max = "~0"; /* unspecified size, use max */ |
|
453 |
27 |
} else { |
|
454 |
96 |
scan_num(&tok); |
|
455 |
96 |
dec->array_max = tok.str; |
|
456 |
96 |
scan(TOK_RANGLE, &tok); |
|
457 |
} |
||
458 |
} |
||
459 |
✓✓ | 1173 |
if (streq(dec->type, "opaque")) { |
460 |
✓✓✗✓ |
81 |
if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { |
461 |
error("array declaration expected"); |
||
462 |
} |
||
463 |
✓✓ | 1125 |
} else if (streq(dec->type, "string")) { |
464 |
✗✓ | 99 |
if (dec->rel != REL_ARRAY) { |
465 |
error("variable-length array declaration expected"); |
||
466 |
} |
||
467 |
} |
||
468 |
2385 |
} |
|
469 |
|||
470 |
static void |
||
471 |
get_prog_declaration(dec, dkind, num) |
||
472 |
declaration *dec; |
||
473 |
defkind dkind; |
||
474 |
int num; /* arg number */ |
||
475 |
{ |
||
476 |
684 |
token tok; |
|
477 |
|||
478 |
✓✗ | 342 |
if (dkind == DEF_PROGRAM) { |
479 |
342 |
peek(&tok); |
|
480 |
✗✓ | 342 |
if (tok.kind == TOK_RPAREN) { /* no arguments */ |
481 |
dec->rel = REL_ALIAS; |
||
482 |
dec->type = "void"; |
||
483 |
dec->prefix = NULL; |
||
484 |
dec->name = NULL; |
||
485 |
return; |
||
486 |
} |
||
487 |
} |
||
488 |
342 |
get_type(&dec->prefix, &dec->type, dkind); |
|
489 |
342 |
dec->rel = REL_ALIAS; |
|
490 |
✗✓ | 342 |
if (peekscan(TOK_IDENT, &tok)) { /* optional name of argument */ |
491 |
dec->name = (char *)strdup(tok.str); |
||
492 |
if (dec->name == NULL) |
||
493 |
error("out of memory"); |
||
494 |
} else { |
||
495 |
/* default name of argument */ |
||
496 |
✗✓ | 342 |
if (asprintf(&dec->name, "%s%d", ARGNAME, num) == -1) |
497 |
error("out of memory"); |
||
498 |
} |
||
499 |
|||
500 |
✓✓ | 342 |
if (streq(dec->type, "void")) |
501 |
78 |
return; |
|
502 |
|||
503 |
✗✓ | 264 |
if (streq(dec->type, "opaque")) |
504 |
error("opaque -- illegal argument type"); |
||
505 |
|||
506 |
✗✓ | 264 |
if (peekscan(TOK_STAR, &tok)) { |
507 |
if (streq(dec->type, "string")) |
||
508 |
error("pointer to string not allowed in program arguments\n"); |
||
509 |
|||
510 |
dec->rel = REL_POINTER; |
||
511 |
if (peekscan(TOK_IDENT, &tok)) { /* optional name of argument */ |
||
512 |
dec->name = (char *)strdup(tok.str); |
||
513 |
if (dec->name == NULL) |
||
514 |
error("out of memory"); |
||
515 |
} |
||
516 |
} |
||
517 |
✗✓ | 264 |
if (peekscan(TOK_LANGLE, &tok)) { |
518 |
if (!streq(dec->type, "string")) |
||
519 |
error("arrays cannot be declared as arguments to " |
||
520 |
"procedures -- use typedef"); |
||
521 |
dec->rel = REL_ARRAY; |
||
522 |
if (peekscan(TOK_RANGLE, &tok)) { |
||
523 |
dec->array_max = "~0";/* unspecified size, use max */ |
||
524 |
} else { |
||
525 |
scan_num(&tok); |
||
526 |
dec->array_max = tok.str; |
||
527 |
scan(TOK_RANGLE, &tok); |
||
528 |
} |
||
529 |
} |
||
530 |
✓✓ | 264 |
if (streq(dec->type, "string")) { |
531 |
/* .x specifies just string as |
||
532 |
* type of argument |
||
533 |
* - make it string<> |
||
534 |
*/ |
||
535 |
✓✗ | 3 |
if (dec->rel != REL_ARRAY) { |
536 |
3 |
dec->rel = REL_ARRAY; |
|
537 |
3 |
dec->array_max = "~0";/* unspecified size, use max */ |
|
538 |
3 |
} |
|
539 |
} |
||
540 |
606 |
} |
|
541 |
|||
542 |
static void |
||
543 |
get_type(prefixp, typep, dkind) |
||
544 |
char **prefixp; |
||
545 |
char **typep; |
||
546 |
defkind dkind; |
||
547 |
{ |
||
548 |
3792 |
token tok; |
|
549 |
|||
550 |
1896 |
*prefixp = NULL; |
|
551 |
1896 |
get_token(&tok); |
|
552 |
✓✗✗✓ ✓✗✗✗ ✓✗✗✗ ✗✗✗✗ ✓✗ |
1896 |
switch (tok.kind) { |
553 |
case TOK_IDENT: |
||
554 |
855 |
*typep = tok.str; |
|
555 |
855 |
break; |
|
556 |
case TOK_STRUCT: |
||
557 |
case TOK_ENUM: |
||
558 |
case TOK_UNION: |
||
559 |
129 |
*prefixp = tok.str; |
|
560 |
129 |
scan(TOK_IDENT, &tok); |
|
561 |
129 |
*typep = tok.str; |
|
562 |
129 |
break; |
|
563 |
case TOK_UNSIGNED: |
||
564 |
276 |
unsigned_dec(typep); |
|
565 |
276 |
break; |
|
566 |
case TOK_SHORT: |
||
567 |
*typep = "short"; |
||
568 |
(void) peekscan(TOK_INT, &tok); |
||
569 |
break; |
||
570 |
case TOK_LONG: |
||
571 |
*typep = "long"; |
||
572 |
(void) peekscan(TOK_INT, &tok); |
||
573 |
break; |
||
574 |
case TOK_HYPER: |
||
575 |
*typep = "int64_t"; |
||
576 |
(void) peekscan(TOK_INT, &tok); |
||
577 |
break; |
||
578 |
case TOK_VOID: |
||
579 |
✗✓ | 243 |
if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { |
580 |
error("voids allowed only inside union and program definitions with one argument"); |
||
581 |
} |
||
582 |
243 |
*typep = tok.str; |
|
583 |
243 |
break; |
|
584 |
case TOK_STRING: |
||
585 |
case TOK_OPAQUE: |
||
586 |
case TOK_CHAR: |
||
587 |
case TOK_INT: |
||
588 |
case TOK_FLOAT: |
||
589 |
case TOK_DOUBLE: |
||
590 |
case TOK_QUAD: |
||
591 |
case TOK_BOOL: |
||
592 |
393 |
*typep = tok.str; |
|
593 |
393 |
break; |
|
594 |
default: |
||
595 |
error("expected type specifier"); |
||
596 |
} |
||
597 |
1896 |
} |
|
598 |
|||
599 |
static void |
||
600 |
unsigned_dec(typep) |
||
601 |
char **typep; |
||
602 |
{ |
||
603 |
552 |
token tok; |
|
604 |
|||
605 |
276 |
peek(&tok); |
|
606 |
✗✗✗✗ ✓✓ |
276 |
switch (tok.kind) { |
607 |
case TOK_CHAR: |
||
608 |
get_token(&tok); |
||
609 |
*typep = "u_char"; |
||
610 |
break; |
||
611 |
case TOK_SHORT: |
||
612 |
get_token(&tok); |
||
613 |
*typep = "u_short"; |
||
614 |
(void) peekscan(TOK_INT, &tok); |
||
615 |
break; |
||
616 |
case TOK_LONG: |
||
617 |
get_token(&tok); |
||
618 |
*typep = "u_long"; |
||
619 |
(void) peekscan(TOK_INT, &tok); |
||
620 |
break; |
||
621 |
case TOK_HYPER: |
||
622 |
get_token(&tok); |
||
623 |
*typep = "u_int64_t"; |
||
624 |
(void) peekscan(TOK_INT, &tok); |
||
625 |
break; |
||
626 |
case TOK_INT: |
||
627 |
135 |
get_token(&tok); |
|
628 |
135 |
*typep = "u_int"; |
|
629 |
135 |
break; |
|
630 |
default: |
||
631 |
141 |
*typep = "u_int"; |
|
632 |
141 |
break; |
|
633 |
} |
||
634 |
276 |
} |
Generated by: GCOVR (Version 3.3) |