overflow: update validation test
[smatch.git] / token_store.c
blobf475b84ffcd7d357814c4552314938aedb3e3f74
1 /*
2 * smatch/token_store.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include "lib.h"
14 #include "parse.h"
15 #include "allocate.h"
17 struct line {
18 struct position pos;
19 struct line *prev;
20 struct token *token;
21 struct line *next;
24 __ALLOCATOR(struct token, "token store", perm_token);
25 ALLOCATOR(line, "line of tokens");
27 static struct token *copy_token(struct token *token)
29 struct token *new;
31 new = __alloc_perm_token(0);
32 memcpy(new, token, sizeof(*token));
33 new->next = NULL;
34 return new;
37 static struct line *cursor;
39 static void find_line(struct position pos)
41 if (!cursor)
42 return;
43 if (pos.line == cursor->pos.line)
44 return;
45 if (pos.line < cursor->pos.line) {
46 if (!cursor->prev)
47 return;
48 cursor = cursor->prev;
49 find_line(pos);
50 return;
52 if (!cursor->next)
53 return;
54 if (pos.line < cursor->next->pos.line)
55 return;
56 cursor = cursor->next;
57 find_line(pos);
60 static void insert_into_line(struct token **current, struct token *new)
62 if (!*current) {
63 *current = new;
64 return;
67 if (new->pos.pos < (*current)->pos.pos) {
68 new->next = *current;
69 *current = new;
70 return;
73 if (new->pos.pos == (*current)->pos.pos)
74 return;
76 insert_into_line(&(*current)->next, new);
79 static void store_token(struct token *token)
81 token = copy_token(token);
83 find_line(token->pos);
85 if (!cursor) {
86 cursor = __alloc_line(0);
87 cursor->pos = token->pos;
88 cursor->token = token;
89 return;
92 if (token->pos.line < cursor->pos.line) {
93 cursor->prev = __alloc_line(0);
94 cursor->prev->next = cursor;
95 cursor = cursor->prev;
96 cursor->pos = token->pos;
97 cursor->token = token;
98 return;
101 if (token->pos.line == cursor->pos.line) {
102 insert_into_line(&cursor->token, token);
103 return;
106 cursor->next = __alloc_line(0);
107 cursor->next->prev = cursor;
108 cursor = cursor->next;
109 cursor->pos = token->pos;
110 cursor->token = token;
113 void store_all_tokens(struct token *token)
115 while (token_type(token) != TOKEN_STREAMEND) {
116 store_token(token);
117 token = token->next;
121 struct token *pos_get_token(struct position pos)
123 struct token *token;
125 find_line(pos);
127 if (!cursor)
128 return NULL;
129 if (cursor->pos.stream != pos.stream)
130 return NULL;
132 if (cursor->pos.line != pos.line)
133 return NULL;
135 token = cursor->token;
136 while (token) {
137 if (pos.pos == token->pos.pos)
138 return token;
139 if (pos.pos < token->pos.pos)
140 return NULL;
141 token = token->next;
143 return NULL;
146 char *pos_ident(struct position pos)
148 struct token *token;
150 token = pos_get_token(pos);
151 if (!token)
152 return NULL;
153 if (token_type(token) != TOKEN_IDENT)
154 return NULL;
155 return token->ident->name;