extra: type bug handling empty states in reset_struct_members()
[smatch.git] / token_store.c
blob1e0a597a6d16454ab5fda3ecd29d53f1eab4412e
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 *first_token_from_line(struct position pos)
123 find_line(pos);
125 if (!cursor)
126 return NULL;
128 if (cursor->pos.stream != pos.stream)
129 return NULL;
130 if (cursor->pos.line != pos.line)
131 return NULL;
133 return cursor->token;
136 struct token *pos_get_token(struct position pos)
138 struct token *token;
140 token = first_token_from_line(pos);
141 while (token) {
142 if (pos.pos == token->pos.pos)
143 return token;
144 if (pos.pos < token->pos.pos)
145 return NULL;
146 token = token->next;
148 return NULL;
151 char *pos_ident(struct position pos)
153 struct token *token;
155 token = pos_get_token(pos);
156 if (!token)
157 return NULL;
158 if (token_type(token) != TOKEN_IDENT)
159 return NULL;
160 return token->ident->name;