1*1f5207b7SJohn Levon /*
2*1f5207b7SJohn Levon  * sparse/token_store.c
3*1f5207b7SJohn Levon  *
4*1f5207b7SJohn Levon  * Copyright (C) 2012 Oracle.
5*1f5207b7SJohn Levon  *
6*1f5207b7SJohn Levon  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1f5207b7SJohn Levon  * of this software and associated documentation files (the "Software"), to deal
8*1f5207b7SJohn Levon  * in the Software without restriction, including without limitation the rights
9*1f5207b7SJohn Levon  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10*1f5207b7SJohn Levon  * copies of the Software, and to permit persons to whom the Software is
11*1f5207b7SJohn Levon  * furnished to do so, subject to the following conditions:
12*1f5207b7SJohn Levon  *
13*1f5207b7SJohn Levon  * The above copyright notice and this permission notice shall be included in
14*1f5207b7SJohn Levon  * all copies or substantial portions of the Software.
15*1f5207b7SJohn Levon  *
16*1f5207b7SJohn Levon  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1f5207b7SJohn Levon  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1f5207b7SJohn Levon  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1f5207b7SJohn Levon  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1f5207b7SJohn Levon  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*1f5207b7SJohn Levon  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22*1f5207b7SJohn Levon  * THE SOFTWARE.
23*1f5207b7SJohn Levon  */
24*1f5207b7SJohn Levon 
25*1f5207b7SJohn Levon #include <stdlib.h>
26*1f5207b7SJohn Levon #include <stdio.h>
27*1f5207b7SJohn Levon #include <string.h>
28*1f5207b7SJohn Levon #include "lib.h"
29*1f5207b7SJohn Levon #include "parse.h"
30*1f5207b7SJohn Levon #include "allocate.h"
31*1f5207b7SJohn Levon 
32*1f5207b7SJohn Levon struct line {
33*1f5207b7SJohn Levon 	struct position pos;
34*1f5207b7SJohn Levon 	struct line *prev;
35*1f5207b7SJohn Levon 	struct token *token;
36*1f5207b7SJohn Levon 	struct line *next;
37*1f5207b7SJohn Levon };
38*1f5207b7SJohn Levon 
39*1f5207b7SJohn Levon __ALLOCATOR(struct token, "token store", perm_token);
40*1f5207b7SJohn Levon ALLOCATOR(line, "line of tokens");
41*1f5207b7SJohn Levon 
copy_token(struct token * token)42*1f5207b7SJohn Levon static struct token *copy_token(struct token *token)
43*1f5207b7SJohn Levon {
44*1f5207b7SJohn Levon 	struct token *new;
45*1f5207b7SJohn Levon 
46*1f5207b7SJohn Levon 	new = __alloc_perm_token(0);
47*1f5207b7SJohn Levon 	memcpy(new, token, sizeof(*token));
48*1f5207b7SJohn Levon 	new->next = NULL;
49*1f5207b7SJohn Levon 	return new;
50*1f5207b7SJohn Levon }
51*1f5207b7SJohn Levon 
52*1f5207b7SJohn Levon static struct line *cursor;
53*1f5207b7SJohn Levon 
find_line(struct position pos)54*1f5207b7SJohn Levon static void find_line(struct position pos)
55*1f5207b7SJohn Levon {
56*1f5207b7SJohn Levon 	if (!cursor)
57*1f5207b7SJohn Levon 		return;
58*1f5207b7SJohn Levon 	if (pos.line == cursor->pos.line)
59*1f5207b7SJohn Levon 		return;
60*1f5207b7SJohn Levon 	if (pos.line < cursor->pos.line) {
61*1f5207b7SJohn Levon 		if (!cursor->prev)
62*1f5207b7SJohn Levon 			return;
63*1f5207b7SJohn Levon 		cursor = cursor->prev;
64*1f5207b7SJohn Levon 		find_line(pos);
65*1f5207b7SJohn Levon 		return;
66*1f5207b7SJohn Levon 	}
67*1f5207b7SJohn Levon 	if (!cursor->next)
68*1f5207b7SJohn Levon 		return;
69*1f5207b7SJohn Levon 	if (pos.line < cursor->next->pos.line)
70*1f5207b7SJohn Levon 		return;
71*1f5207b7SJohn Levon 	cursor = cursor->next;
72*1f5207b7SJohn Levon 	find_line(pos);
73*1f5207b7SJohn Levon }
74*1f5207b7SJohn Levon 
insert_into_line(struct token ** current,struct token * new)75*1f5207b7SJohn Levon static void insert_into_line(struct token **current, struct token *new)
76*1f5207b7SJohn Levon {
77*1f5207b7SJohn Levon 	if (!*current) {
78*1f5207b7SJohn Levon 		*current = new;
79*1f5207b7SJohn Levon 		return;
80*1f5207b7SJohn Levon 	}
81*1f5207b7SJohn Levon 
82*1f5207b7SJohn Levon 	if (new->pos.pos < (*current)->pos.pos) {
83*1f5207b7SJohn Levon 		new->next = *current;
84*1f5207b7SJohn Levon 		*current = new;
85*1f5207b7SJohn Levon 		return;
86*1f5207b7SJohn Levon 	}
87*1f5207b7SJohn Levon 
88*1f5207b7SJohn Levon 	if (new->pos.pos == (*current)->pos.pos)
89*1f5207b7SJohn Levon 		return;
90*1f5207b7SJohn Levon 
91*1f5207b7SJohn Levon 	insert_into_line(&(*current)->next, new);
92*1f5207b7SJohn Levon }
93*1f5207b7SJohn Levon 
store_token(struct token * token)94*1f5207b7SJohn Levon static void store_token(struct token *token)
95*1f5207b7SJohn Levon {
96*1f5207b7SJohn Levon 	token = copy_token(token);
97*1f5207b7SJohn Levon 
98*1f5207b7SJohn Levon 	find_line(token->pos);
99*1f5207b7SJohn Levon 
100*1f5207b7SJohn Levon 	if (!cursor) {
101*1f5207b7SJohn Levon 		cursor = __alloc_line(0);
102*1f5207b7SJohn Levon 		cursor->pos = token->pos;
103*1f5207b7SJohn Levon 		cursor->token = token;
104*1f5207b7SJohn Levon 		return;
105*1f5207b7SJohn Levon 	}
106*1f5207b7SJohn Levon 
107*1f5207b7SJohn Levon 	if (token->pos.line < cursor->pos.line) {
108*1f5207b7SJohn Levon 		cursor->prev = __alloc_line(0);
109*1f5207b7SJohn Levon 		cursor->prev->next = cursor;
110*1f5207b7SJohn Levon 		cursor = cursor->prev;
111*1f5207b7SJohn Levon 		cursor->pos = token->pos;
112*1f5207b7SJohn Levon 		cursor->token = token;
113*1f5207b7SJohn Levon 		return;
114*1f5207b7SJohn Levon 	}
115*1f5207b7SJohn Levon 
116*1f5207b7SJohn Levon 	if (token->pos.line == cursor->pos.line) {
117*1f5207b7SJohn Levon 		insert_into_line(&cursor->token, token);
118*1f5207b7SJohn Levon 		return;
119*1f5207b7SJohn Levon 	}
120*1f5207b7SJohn Levon 
121*1f5207b7SJohn Levon 	cursor->next = __alloc_line(0);
122*1f5207b7SJohn Levon 	cursor->next->prev = cursor;
123*1f5207b7SJohn Levon 	cursor = cursor->next;
124*1f5207b7SJohn Levon 	cursor->pos = token->pos;
125*1f5207b7SJohn Levon 	cursor->token = token;
126*1f5207b7SJohn Levon }
127*1f5207b7SJohn Levon 
store_all_tokens(struct token * token)128*1f5207b7SJohn Levon void store_all_tokens(struct token *token)
129*1f5207b7SJohn Levon {
130*1f5207b7SJohn Levon 	while (token_type(token) != TOKEN_STREAMEND) {
131*1f5207b7SJohn Levon 		store_token(token);
132*1f5207b7SJohn Levon 		token = token->next;
133*1f5207b7SJohn Levon 	}
134*1f5207b7SJohn Levon }
135*1f5207b7SJohn Levon 
first_token_from_line(struct position pos)136*1f5207b7SJohn Levon struct token *first_token_from_line(struct position pos)
137*1f5207b7SJohn Levon {
138*1f5207b7SJohn Levon 	find_line(pos);
139*1f5207b7SJohn Levon 
140*1f5207b7SJohn Levon 	if (!cursor)
141*1f5207b7SJohn Levon 		return NULL;
142*1f5207b7SJohn Levon 
143*1f5207b7SJohn Levon 	if (cursor->pos.stream != pos.stream)
144*1f5207b7SJohn Levon 		return NULL;
145*1f5207b7SJohn Levon 	if (cursor->pos.line != pos.line)
146*1f5207b7SJohn Levon 		return NULL;
147*1f5207b7SJohn Levon 
148*1f5207b7SJohn Levon 	return cursor->token;
149*1f5207b7SJohn Levon }
150*1f5207b7SJohn Levon 
pos_get_token(struct position pos)151*1f5207b7SJohn Levon struct token *pos_get_token(struct position pos)
152*1f5207b7SJohn Levon {
153*1f5207b7SJohn Levon 	struct token *token;
154*1f5207b7SJohn Levon 
155*1f5207b7SJohn Levon 	token = first_token_from_line(pos);
156*1f5207b7SJohn Levon 	while (token) {
157*1f5207b7SJohn Levon 		if (pos.pos == token->pos.pos)
158*1f5207b7SJohn Levon 			return token;
159*1f5207b7SJohn Levon 		if (pos.pos < token->pos.pos)
160*1f5207b7SJohn Levon 			return NULL;
161*1f5207b7SJohn Levon 		token = token->next;
162*1f5207b7SJohn Levon 	}
163*1f5207b7SJohn Levon 	return NULL;
164*1f5207b7SJohn Levon }
165*1f5207b7SJohn Levon 
pos_ident(struct position pos)166*1f5207b7SJohn Levon char *pos_ident(struct position pos)
167*1f5207b7SJohn Levon {
168*1f5207b7SJohn Levon 	struct token *token;
169*1f5207b7SJohn Levon 
170*1f5207b7SJohn Levon 	token = pos_get_token(pos);
171*1f5207b7SJohn Levon 	if (!token)
172*1f5207b7SJohn Levon 		return NULL;
173*1f5207b7SJohn Levon 	if (token_type(token) != TOKEN_IDENT)
174*1f5207b7SJohn Levon 		return NULL;
175*1f5207b7SJohn Levon 	return token->ident->name;
176*1f5207b7SJohn Levon }
177*1f5207b7SJohn Levon 
178