1b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence/*
2b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * Copyright 2011 Tresys Technology, LLC. All rights reserved.
3b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *
4b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * Redistribution and use in source and binary forms, with or without
5b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * modification, are permitted provided that the following conditions are met:
6b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *
7b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *    1. Redistributions of source code must retain the above copyright notice,
8b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *       this list of conditions and the following disclaimer.
9b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *
10b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *    2. Redistributions in binary form must reproduce the above copyright notice,
11b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *       this list of conditions and the following disclaimer in the documentation
12b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *       and/or other materials provided with the distribution.
13b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *
14b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
15b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence *
25b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * The views and conclusions contained in the software and documentation are those
26b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * of the authors and should not be interpreted as representing official policies,
27b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence * either expressed or implied, of Tresys Technology, LLC.
28b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence */
29b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
30b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include <stdlib.h>
31b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include <stdio.h>
32b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include <string.h>
33b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include <stdint.h>
34b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include <sepol/errcodes.h>
35b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
36b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include "cil_internal.h"
37b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include "cil_log.h"
38b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include "cil_mem.h"
39875a6bcbe8885c927122c6931b3a01d821e04b10James Carter#include "cil_tree.h"
40b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include "cil_lexer.h"
41b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence#include "cil_strpool.h"
42875a6bcbe8885c927122c6931b3a01d821e04b10James Carter#include "cil_stack.h"
43875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
44875a6bcbe8885c927122c6931b3a01d821e04b10James Carterchar *CIL_KEY_HLL_LMS;
45875a6bcbe8885c927122c6931b3a01d821e04b10James Carterchar *CIL_KEY_HLL_LMX;
46875a6bcbe8885c927122c6931b3a01d821e04b10James Carterchar *CIL_KEY_HLL_LME;
47875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
48875a6bcbe8885c927122c6931b3a01d821e04b10James Carterstruct hll_info {
49875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	int hll_lineno;
50875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	int hll_expand;
51875a6bcbe8885c927122c6931b3a01d821e04b10James Carter};
52875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
53875a6bcbe8885c927122c6931b3a01d821e04b10James Carterstatic void push_hll_info(struct cil_stack *stack, int hll_lineno, int hll_expand)
54875a6bcbe8885c927122c6931b3a01d821e04b10James Carter{
55875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	struct hll_info *new = cil_malloc(sizeof(*new));
56875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
57875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	new->hll_lineno = hll_lineno;
58875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	new->hll_expand = hll_expand;
59875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
60875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_stack_push(stack, CIL_NONE, new);
61875a6bcbe8885c927122c6931b3a01d821e04b10James Carter}
62875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
63875a6bcbe8885c927122c6931b3a01d821e04b10James Carterstatic void pop_hll_info(struct cil_stack *stack, int *hll_lineno, int *hll_expand)
64875a6bcbe8885c927122c6931b3a01d821e04b10James Carter{
65875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	struct cil_stack_item *curr = cil_stack_pop(stack);
66875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	struct cil_stack_item *prev = cil_stack_peek(stack);
67875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	struct hll_info *old;
68875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
69875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	free(curr->data);
70875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
71875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	if (!prev) {
72875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		*hll_lineno = -1;
73875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		*hll_expand = -1;
74875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	} else {
75875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		old = prev->data;
76875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		*hll_lineno = old->hll_lineno;
77875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		*hll_expand = old->hll_expand;
78875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	}
79875a6bcbe8885c927122c6931b3a01d821e04b10James Carter}
80875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
8167560cc7ace8c2ba728735e839729ac97e8a51a6James Carterstatic void create_node(struct cil_tree_node **node, struct cil_tree_node *current, int line, int hll_line, void *value)
82875a6bcbe8885c927122c6931b3a01d821e04b10James Carter{
83875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_tree_node_init(node);
84875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	(*node)->parent = current;
85875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	(*node)->flavor = CIL_NODE;
86875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	(*node)->line = line;
87875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	(*node)->hll_line = hll_line;
88875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	(*node)->data = value;
89875a6bcbe8885c927122c6931b3a01d821e04b10James Carter}
90875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
91875a6bcbe8885c927122c6931b3a01d821e04b10James Carterstatic void insert_node(struct cil_tree_node *node, struct cil_tree_node *current)
92875a6bcbe8885c927122c6931b3a01d821e04b10James Carter{
93875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	if (current->cl_head == NULL) {
94875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		current->cl_head = node;
95875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	} else {
96875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		current->cl_tail->next = node;
97875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	}
98875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	current->cl_tail = node;
99875a6bcbe8885c927122c6931b3a01d821e04b10James Carter}
100875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
101875a6bcbe8885c927122c6931b3a01d821e04b10James Carterstatic int add_hll_linemark(struct cil_tree_node **current, int *hll_lineno, int *hll_expand, struct cil_stack *stack, char *path)
102875a6bcbe8885c927122c6931b3a01d821e04b10James Carter{
103875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	char *hll_type;
104875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	struct cil_tree_node *node;
105875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	struct token tok;
106875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	char *hll_file;
107875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	char *end = NULL;
108875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
109875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_lexer_next(&tok);
110875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	hll_type = cil_strpool_add(tok.value);
111875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	if (hll_type == CIL_KEY_HLL_LME) {
112875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		if (cil_stack_is_empty(stack)) {
113875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			cil_log(CIL_ERR, "Line mark end without start\n");
114875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			goto exit;
115875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		}
116875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		pop_hll_info(stack, hll_lineno, hll_expand);
117875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		*current = (*current)->parent;
118875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	} else {
11967560cc7ace8c2ba728735e839729ac97e8a51a6James Carter		create_node(&node, *current, tok.line, *hll_lineno, NULL);
120875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		insert_node(node, *current);
121875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		*current = node;
122875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
12367560cc7ace8c2ba728735e839729ac97e8a51a6James Carter		create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_INFO);
124875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		insert_node(node, *current);
125875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
12667560cc7ace8c2ba728735e839729ac97e8a51a6James Carter		create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_HLL);
127875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		insert_node(node, *current);
128875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
129875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		if (hll_type == CIL_KEY_HLL_LMS) {
130875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			*hll_expand = 0;
131875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		} else if (hll_type == CIL_KEY_HLL_LMX) {
132875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			*hll_expand = 1;
133875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		} else {
134875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			cil_log(CIL_ERR, "Invalid line mark syntax\n");
135875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			goto exit;
136875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		}
137875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
138875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		cil_lexer_next(&tok);
139875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		if (tok.type != SYMBOL) {
140875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			cil_log(CIL_ERR, "Invalid line mark syntax\n");
141875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			goto exit;
142875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		}
143875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		*hll_lineno = strtol(tok.value, &end, 10);
144875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		if (errno == ERANGE || *end != '\0') {
145875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			cil_log(CIL_ERR, "Problem parsing line number for line mark\n");
146875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			goto exit;
147875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		}
148875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
149875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		push_hll_info(stack, *hll_lineno, *hll_expand);
150875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
151875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		cil_lexer_next(&tok);
152875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		if (tok.type != SYMBOL && tok.type != QSTRING) {
153875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			cil_log(CIL_ERR, "Invalid line mark syntax\n");
154875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			goto exit;
155875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		}
156875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
157875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		if (tok.type == QSTRING) {
158875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			tok.value[strlen(tok.value) - 1] = '\0';
159875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			tok.value = tok.value+1;
160875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		}
161875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
162875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		hll_file = cil_strpool_add(tok.value);
163875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
16467560cc7ace8c2ba728735e839729ac97e8a51a6James Carter		create_node(&node, *current, tok.line, *hll_lineno, hll_file);
165875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		insert_node(node, *current);
166875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	}
167875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
168875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_lexer_next(&tok);
169875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	if (tok.type != NEWLINE) {
170875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		cil_log(CIL_ERR, "Invalid line mark syntax\n");
171875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		goto exit;
172875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	}
173875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
174875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	return SEPOL_OK;
175875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
176875a6bcbe8885c927122c6931b3a01d821e04b10James Carterexit:
177875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_log(CIL_ERR, "Problem with high-level line mark at line %d of %s\n", tok.line, path);
178875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	return SEPOL_ERR;
179875a6bcbe8885c927122c6931b3a01d821e04b10James Carter}
180b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
181681341f2f4172efc06a49bdda9c5ff03b055421eJames Carterstatic void add_cil_path(struct cil_tree_node **current, char *path)
182681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter{
183681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter	struct cil_tree_node *node;
184681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter
18567560cc7ace8c2ba728735e839729ac97e8a51a6James Carter	create_node(&node, *current, 0, 0, NULL);
186681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter	insert_node(node, *current);
187681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter	*current = node;
188681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter
18967560cc7ace8c2ba728735e839729ac97e8a51a6James Carter	create_node(&node, *current, 0, 0, CIL_KEY_SRC_INFO);
190681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter	insert_node(node, *current);
191681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter
19267560cc7ace8c2ba728735e839729ac97e8a51a6James Carter	create_node(&node, *current, 0, 0, CIL_KEY_SRC_CIL);
193681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter	insert_node(node, *current);
194681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter
19567560cc7ace8c2ba728735e839729ac97e8a51a6James Carter	create_node(&node, *current, 0, 0, path);
196681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter	insert_node(node, *current);
197681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter}
198681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter
19976ba6eaa7333483a8cc0c73a7880f7acf99c2656Steve Lawrenceint cil_parser(char *_path, char *buffer, uint32_t size, struct cil_tree **parse_tree)
200b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence{
201b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
202b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	int paren_count = 0;
203b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
204b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	struct cil_tree *tree = NULL;
205b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	struct cil_tree_node *node = NULL;
206b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	struct cil_tree_node *current = NULL;
20776ba6eaa7333483a8cc0c73a7880f7acf99c2656Steve Lawrence	char *path = cil_strpool_add(_path);
208875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	struct cil_stack *stack;
209875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	int hll_lineno = -1;
210875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	int hll_expand = -1;
211b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	struct token tok;
212875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	int rc = SEPOL_OK;
213875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
214875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	CIL_KEY_HLL_LMS = cil_strpool_add("lms");
215875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	CIL_KEY_HLL_LMX = cil_strpool_add("lmx");
216875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	CIL_KEY_HLL_LME = cil_strpool_add("lme");
217875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
218875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_stack_init(&stack);
219b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
220b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	cil_lexer_setup(buffer, size);
221b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
222b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	tree = *parse_tree;
223875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	current = tree->root;
224b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
225681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter	add_cil_path(&current, path);
226681341f2f4172efc06a49bdda9c5ff03b055421eJames Carter
227b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	do {
228b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		cil_lexer_next(&tok);
229b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		switch (tok.type) {
230875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		case HLL_LINEMARK:
231875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			rc = add_hll_linemark(&current, &hll_lineno, &hll_expand, stack, path);
232875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			if (rc != SEPOL_OK) {
233875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				goto exit;
234875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			}
235875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			break;
236b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		case OPAREN:
237b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			paren_count++;
238875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
23967560cc7ace8c2ba728735e839729ac97e8a51a6James Carter			create_node(&node, current, tok.line, hll_lineno, NULL);
240875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			insert_node(node, current);
241b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			current = node;
242b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			break;
243b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		case CPAREN:
244b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			paren_count--;
245b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			if (paren_count < 0) {
246b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence				cil_log(CIL_ERR, "Close parenthesis without matching open at line %d of %s\n", tok.line, path);
247875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				goto exit;
248b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			}
249b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			current = current->parent;
250b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			break;
251b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		case QSTRING:
252875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			tok.value[strlen(tok.value) - 1] = '\0';
253875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			tok.value = tok.value+1;
254e41ae676c253760621e81bc9745e8ecf8175f085Stephen Smalley			/* FALLTHRU */
255875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		case SYMBOL:
256b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			if (paren_count == 0) {
257b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence				cil_log(CIL_ERR, "Symbol not inside parenthesis at line %d of %s\n", tok.line, path);
258875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				goto exit;
259b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			}
260875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
26167560cc7ace8c2ba728735e839729ac97e8a51a6James Carter			create_node(&node, current, tok.line, hll_lineno, cil_strpool_add(tok.value));
262875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			insert_node(node, current);
263875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			break;
264875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		case NEWLINE :
265875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			if (!hll_expand) {
266875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				hll_lineno++;
267b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			}
268b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			break;
269875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		case COMMENT:
270875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			while (tok.type != NEWLINE && tok.type != END_OF_FILE) {
271875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				cil_lexer_next(&tok);
272875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			}
273875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			if (!hll_expand) {
274875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				hll_lineno++;
275875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			}
276875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			if (tok.type != END_OF_FILE) {
277875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				break;
278875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			}
279e41ae676c253760621e81bc9745e8ecf8175f085Stephen Smalley			/* FALLTHRU */
280875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			// Fall through if EOF
281b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		case END_OF_FILE:
282b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			if (paren_count > 0) {
283b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence				cil_log(CIL_ERR, "Open parenthesis without matching close at line %d of %s\n", tok.line, path);
284875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				goto exit;
285875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			}
286875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			if (!cil_stack_is_empty(stack)) {
287875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				cil_log(CIL_ERR, "High-level language line marker start without close at line %d of %s\n", tok.line, path);
288875a6bcbe8885c927122c6931b3a01d821e04b10James Carter				goto exit;
289b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			}
290b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			break;
291b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		case UNKNOWN:
292b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			cil_log(CIL_ERR, "Invalid token '%s' at line %d of %s\n", tok.value, tok.line, path);
293875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			goto exit;
294b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		default:
295b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence			cil_log(CIL_ERR, "Unknown token type '%d' at line %d of %s\n", tok.type, tok.line, path);
296875a6bcbe8885c927122c6931b3a01d821e04b10James Carter			goto exit;
297b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence		}
298b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	}
299b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	while (tok.type != END_OF_FILE);
300b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
301b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	cil_lexer_destroy();
302b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
303875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_stack_destroy(&stack);
304875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
305b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	*parse_tree = tree;
306b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence
307b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence	return SEPOL_OK;
308875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
309875a6bcbe8885c927122c6931b3a01d821e04b10James Carterexit:
310875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	while (!cil_stack_is_empty(stack)) {
311875a6bcbe8885c927122c6931b3a01d821e04b10James Carter		pop_hll_info(stack, &hll_lineno, &hll_expand);
312875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	}
313875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	cil_stack_destroy(&stack);
314875a6bcbe8885c927122c6931b3a01d821e04b10James Carter
315875a6bcbe8885c927122c6931b3a01d821e04b10James Carter	return SEPOL_ERR;
316b19eafb97feb6389d78e1693f276fc5b10e25bdSteve Lawrence}
317