MFC:
[dragonfly.git] / lib / libsys / genhooks / parse.c
blobd6b77fea82997d75f7e86f39cddd64f1395d711f
1 /*
2 * Copyright (c) 2005 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project 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.
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 HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
34 * $DragonFly: src/lib/libsys/genhooks/parse.c,v 1.1 2005/05/08 18:14:56 dillon Exp $
37 * PARSE.C
39 * Parse the system call configuration file.
42 #include "defs.h"
44 struct sys_info **sys_array;
45 int sys_count;
46 char *sys_sectname;
48 static int parse_base(lex_token *tok);
49 static int parse_add(lex_token *tok);
50 static int parse_int(lex_token *tok, int *ret_p);
51 static int parse_type(lex_token *tok, sys_type **type_pp);
53 void
54 parse_file(const char *path)
56 lex_token tok;
57 int t;
59 lex_open(path, &tok);
60 t = lex_gettoken(&tok);
61 while (t != TOK_EOF) {
62 switch(t) {
63 case TOK_BASE:
64 t = parse_base(&tok);
65 break;
66 case TOK_ADD:
67 t = parse_add(&tok);
68 break;
69 default:
70 lex_error(&tok, "Expected command directive");
71 exit(1);
74 lex_close(&tok);
77 int
78 parse_base(lex_token *tok)
80 int t;
82 t = lex_gettoken(tok);
83 if (t & TOK_SYMBOL) {
84 sys_sectname = lex_string(tok);
85 t = lex_gettoken(tok);
86 } else {
87 lex_error(tok, "Expected section extension symbol");
88 exit(1);
90 t = lex_skip_token(tok, TOK_SEMI);
91 return(t);
94 static int
95 parse_add(lex_token *tok)
97 sys_info *info;
98 sys_type *type;
99 int sysno;
100 int t;
102 lex_gettoken(tok);
103 info = zalloc(sizeof(sys_info));
105 parse_int(tok, &info->sysno);
107 t = lex_skip_token(tok, TOK_OBRACE);
109 while (t != TOK_CBRACE) {
110 switch(t) {
111 case TOK_FUNCTION:
112 t = lex_gettoken(tok);
113 parse_type(tok, &info->func_ret);
114 t = lex_skip_token(tok, TOK_OPAREN);
115 while (t != TOK_CPAREN) {
116 t = parse_type(tok, &type);
117 if (t != TOK_COMMA)
118 break;
119 t = lex_gettoken(tok);
120 info->func_args = realloc(info->func_args,
121 sizeof(sys_type) * (info->nargs + 1));
122 info->func_args[info->nargs++] = type;
126 * cleanup void
128 if (info->nargs == 1 &&
129 strcmp(info->func_args[0]->type_name, "void") == 0
131 info->nargs = 0;
132 /* XXX free/cleanup */
135 t = lex_skip_token(tok, TOK_CPAREN);
136 t = lex_skip_token(tok, TOK_SEMI);
137 break;
138 case TOK_IMPLEMENTATION:
139 t = lex_gettoken(tok);
140 switch(t) {
141 case TOK_DIRECT:
142 t = lex_gettoken(tok);
143 break;
144 default:
145 lex_error(tok, "Expected 'direct'");
146 exit(1);
148 t = lex_skip_token(tok, TOK_SEMI);
149 break;
150 default:
151 lex_error(tok, "Expected command directive");
152 exit(1);
155 t = lex_skip_token(tok, TOK_CBRACE);
156 if (sys_count <= info->sysno) {
157 sys_array = realloc(sys_array,
158 sizeof(sys_info *) * (info->sysno + 1));
159 while (sys_count <= info->sysno)
160 sys_array[sys_count++] = NULL;
162 sys_array[info->sysno] = info;
163 return(t);
166 static
168 parse_int(lex_token *tok, int *ret_p)
170 int t = tok->type;
172 if (t != TOK_INTEGER) {
173 lex_error(tok, "Expected integer");
174 exit(1);
176 *ret_p = tok->value;
177 return(lex_gettoken(tok));
180 static
182 parse_type(lex_token *tok, sys_type **type_pp)
184 int t = tok->type;
185 sys_type *type;
187 type = zalloc(sizeof(sys_type));
189 if ((t & TOK_SYMBOL) == 0) {
190 lex_error(tok, "Expected type identifier");
191 exit(1);
193 type->type_name = lex_string(tok);
194 t = lex_gettoken(tok);
195 if (t != TOK_COMMA && t != TOK_CPAREN) {
196 if ((t & TOK_SYMBOL) == 0) {
197 lex_error(tok, "Expected name identifier");
198 exit(1);
200 type->var_name = lex_string(tok);
201 t = lex_gettoken(tok);
202 } else {
203 type->var_name = NULL;
205 *type_pp = type;
206 return(t);