RPA Toolkit
Build system cleanup...
[rpatk.git] / rvm / rvmscope.c
1 /*
2  *  Regular Pattern Analyzer (RPA)
3  *  Copyright (c) 2009-2010 Martin Stoilov
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  *  Martin Stoilov <martin@rpasearch.com>
19  */
20
21 #include "rvm/rvmscope.h"
22 #include "rlib/rstring.h"
23 #include "rlib/rmem.h"
24
25
26 rvm_scope_t *rvm_scope_create()
27 {
28         rvm_scope_t *scope;
29
30         scope = (rvm_scope_t*)r_malloc(sizeof(*scope));
31         if (!scope)
32                 return NULL;
33         r_memset(scope, 0, sizeof(*scope));
34         scope->names = r_array_create(sizeof(rstr_t*));
35         scope->nameshash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
36         scope->varstack = r_array_create(sizeof(rvm_varmap_t));
37         scope->scopestack = r_array_create(sizeof(scope->varstack->len));
38         return scope;
39 }
40
41
42 void rvm_scope_destroy(rvm_scope_t *scope)
43 {
44         int i;
45         int len = r_array_length(scope->names);
46
47         for (i = 0; i < len; i++)
48                 r_free(r_array_index(scope->names, i, char*));
49         r_object_destroy((robject_t*)scope->names);
50         r_object_destroy((robject_t*)scope->varstack);
51         r_object_destroy((robject_t*)scope->scopestack);
52         r_object_destroy((robject_t*)scope->nameshash);
53         r_free(scope);
54 }
55
56
57 char *rvm_scope_addname(rvm_scope_t *scope, const char* name, unsigned int namesize)
58 {
59         rstr_t namestr = {(char*)name, namesize};
60         rstr_t *dupname = r_hash_lookup(scope->nameshash, &namestr);
61
62         if (!dupname) {
63                 dupname = r_rstrdup(name, namesize);
64                 r_array_add(scope->names, (rconstpointer)&dupname);
65                 r_hash_insert(scope->nameshash, dupname, dupname);
66         }
67         return dupname->str;
68 }
69
70
71 char *rvm_scope_addstrname(rvm_scope_t *scope, const char *name)
72 {
73         return rvm_scope_addname(scope, name, r_strlen(name));
74 }
75
76
77 unsigned int rvm_scope_count(rvm_scope_t* scope)
78 {
79         return r_array_length(scope->scopestack);
80 }
81
82
83 void rvm_scope_push(rvm_scope_t* scope)
84 {
85         unsigned long scopelen = r_array_length(scope->varstack);
86 //      r_printf("SCOPE FRAME: %d, PUSH: %d\n", r_array_length(scope->scopestack), scopelen);
87         r_array_add(scope->scopestack, &scopelen);
88 }
89
90
91 void rvm_scope_pop(rvm_scope_t* scope)
92 {
93         unsigned long scopelen = r_array_index(scope->scopestack, r_array_length(scope->scopestack) - 1, unsigned long);
94         r_array_removelast(scope->scopestack);
95         r_array_setlength(scope->varstack, scopelen);
96 //      r_printf("SCOPE FRAME: %d, POP: %d\n", r_array_length(scope->scopestack), scopelen);
97 }
98
99
100 void rvm_scope_addoffset(rvm_scope_t *scope, const char *name, unsigned int namesize, ruint32 off)
101 {
102         rvm_varmap_t vmap;
103
104         vmap.name = rvm_scope_addname(scope, name, namesize);
105         vmap.data.offset = off;
106         vmap.datatype = VARMAP_DATATYPE_OFFSET;
107         r_array_add(scope->varstack, &vmap);
108 }
109
110
111 unsigned int rvm_scope_numentries(rvm_scope_t *scope)
112 {
113         return r_array_length(scope->varstack);
114 }
115
116
117 void rvm_scope_addpointer(rvm_scope_t *scope, const char *name, unsigned int namesize, rpointer ptr)
118 {
119         rvm_varmap_t vmap;
120
121         vmap.name = rvm_scope_addname(scope, name, namesize);
122         vmap.data.ptr = ptr;
123         vmap.datatype = VARMAP_DATATYPE_PTR;
124         r_array_add(scope->varstack, &vmap);
125 }
126
127
128 void rvm_scope_addoffset_s(rvm_scope_t *scope, const char *name, ruint32 off)
129 {
130         rvm_scope_addoffset(scope, name ,r_strlen(name), off);
131 }
132
133
134 void rvm_scope_addpointer_s(rvm_scope_t *scope, const char *name, rpointer ptr)
135 {
136         rvm_scope_addpointer(scope, name ,r_strlen(name), ptr);
137 }
138
139
140 rvm_varmap_t *rvm_scope_lookup(rvm_scope_t *scope, const char *name, unsigned int namesize)
141 {
142         unsigned long scopelen = r_array_length(scope->varstack);
143         rvm_varmap_t *varmap;
144         int i;
145
146         if (!scopelen)
147                 return NULL;
148
149         for (i = scopelen - 1; i >= 0; i--) {
150                 varmap = (rvm_varmap_t*)r_array_slot(scope->varstack, i);
151                 if (r_strlen(varmap->name) == namesize && r_strncmp(varmap->name, name, namesize) == 0)
152                         return varmap;
153         }
154         return NULL;
155 }
156
157
158 rvm_varmap_t *rvm_scope_tiplookup(rvm_scope_t *scope, const char *name, unsigned int namesize)
159 {
160         unsigned long scopelen = r_array_length(scope->varstack);
161         unsigned int tipstart = r_array_empty(scope->scopestack) ? 0 : r_array_last(scope->scopestack, unsigned int);
162         rvm_varmap_t *varmap;
163         int i;
164
165         if (!scopelen)
166                 return NULL;
167         for (i = scopelen - 1; i >= (int)tipstart; i--) {
168                 varmap = (rvm_varmap_t*)r_array_slot(scope->varstack, i);
169                 if (r_strlen(varmap->name) == namesize && r_strncmp(varmap->name, name, namesize) == 0)
170                         return varmap;
171         }
172         return NULL;
173 }
174
175
176 rvm_varmap_t *rvm_scope_lookup_s(rvm_scope_t *scope, const char *name)
177 {
178         return rvm_scope_lookup(scope, name, r_strlen(name));
179 }
180
181
182 rvm_varmap_t *rvm_scope_tiplookup_s(rvm_scope_t *scope, const char *name)
183 {
184         return rvm_scope_tiplookup(scope, name, r_strlen(name));
185 }