BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file ref.c
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * @section DESCRIPTION
30 *
31 * References module.
32 *
33 * Synopsis:
34 * refhere()
35 * Variables:
36 * Exposes variables and objects as seen from this refhere() statement.
37 *
38 * Synopsis:
39 * ref refhere::ref()
40 * ref ref::ref()
41 * Variables:
42 * Exposes variables and objects as seen from the corresponding refhere()
43 * statement.
44 */
45  
46 #include <stdlib.h>
47 #include <string.h>
48  
49 #include <misc/offset.h>
50 #include <structure/LinkedList0.h>
51  
52 #include <ncd/module_common.h>
53  
54 #include <generated/blog_channel_ncd_ref.h>
55  
56 struct refhere_instance {
57 NCDModuleInst *i;
58 LinkedList0 refs_list;
59 };
60  
61 struct ref_instance {
62 NCDModuleInst *i;
63 struct refhere_instance *rh;
64 LinkedList0Node refs_list_node;
65 };
66  
67 static void ref_instance_free (struct ref_instance *o);
68  
69 static void refhere_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
70 {
71 struct refhere_instance *o = vo;
72 o->i = i;
73  
74 // check arguments
75 if (!NCDVal_ListRead(params->args, 0)) {
76 ModuleLog(o->i, BLOG_ERROR, "wrong arity");
77 goto fail0;
78 }
79  
80 // init refs list
81 LinkedList0_Init(&o->refs_list);
82  
83 // signal up
84 NCDModuleInst_Backend_Up(o->i);
85 return;
86  
87 fail0:
88 NCDModuleInst_Backend_DeadError(i);
89 }
90  
91 static void refhere_func_die (void *vo)
92 {
93 struct refhere_instance *o = vo;
94  
95 // die refs
96 while (!LinkedList0_IsEmpty(&o->refs_list)) {
97 struct ref_instance *ref = UPPER_OBJECT(LinkedList0_GetFirst(&o->refs_list), struct ref_instance, refs_list_node);
98 ASSERT(ref->rh == o)
99 ref_instance_free(ref);
100 }
101  
102 NCDModuleInst_Backend_Dead(o->i);
103 }
104  
105 static int refhere_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object)
106 {
107 struct refhere_instance *o = vo;
108  
109 // We don't redirect methods, and there will never be an object
110 // with empty name. Fail here so we don't report non-errors.
111 if (objname == NCD_STRING_EMPTY) {
112 return 0;
113 }
114  
115 return NCDModuleInst_Backend_GetObj(o->i, objname, out_object);
116 }
117  
118 static void ref_func_new_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, struct refhere_instance *rh)
119 {
120 struct ref_instance *o = vo;
121 o->i = i;
122  
123 // check arguments
124 if (!NCDVal_ListRead(params->args, 0)) {
125 ModuleLog(o->i, BLOG_ERROR, "wrong arity");
126 goto fail0;
127 }
128  
129 // set refhere
130 o->rh = rh;
131  
132 // add to refhere's refs list
133 LinkedList0_Prepend(&o->rh->refs_list, &o->refs_list_node);
134  
135 // signal up
136 NCDModuleInst_Backend_Up(o->i);
137 return;
138  
139 fail0:
140 NCDModuleInst_Backend_DeadError(i);
141 }
142  
143 static void ref_func_new_from_refhere (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
144 {
145 struct refhere_instance *rh = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user);
146  
147 return ref_func_new_templ(vo, i, params, rh);
148 }
149  
150 static void ref_func_new_from_ref (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
151 {
152 struct ref_instance *ref = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user);
153  
154 return ref_func_new_templ(vo, i, params, ref->rh);
155 }
156  
157 static void ref_instance_free (struct ref_instance *o)
158 {
159 // remove from refhere's reft list
160 LinkedList0_Remove(&o->rh->refs_list, &o->refs_list_node);
161  
162 NCDModuleInst_Backend_Dead(o->i);
163 }
164  
165 static void ref_func_die (void *vo)
166 {
167 struct ref_instance *o = vo;
168  
169 ref_instance_free(o);
170 }
171  
172 static int ref_func_getobj (void *vo, NCD_string_id_t objname, NCDObject *out_object)
173 {
174 struct ref_instance *o = vo;
175  
176 // We don't redirect methods, and there will never be an object
177 // with empty name. Fail here so we don't report non-errors.
178 if (objname == NCD_STRING_EMPTY) {
179 return 0;
180 }
181  
182 return NCDModuleInst_Backend_GetObj(o->rh->i, objname, out_object);
183 }
184  
185 static struct NCDModule modules[] = {
186 {
187 .type = "refhere",
188 .func_new2 = refhere_func_new,
189 .func_die = refhere_func_die,
190 .func_getobj = refhere_func_getobj,
191 .alloc_size = sizeof(struct refhere_instance)
192 }, {
193 .type = "refhere::ref",
194 .base_type = "ref",
195 .func_new2 = ref_func_new_from_refhere,
196 .func_die = ref_func_die,
197 .func_getobj = ref_func_getobj,
198 .alloc_size = sizeof(struct ref_instance)
199 }, {
200 .type = "ref::ref",
201 .base_type = "ref",
202 .func_new2 = ref_func_new_from_ref,
203 .func_die = ref_func_die,
204 .func_getobj = ref_func_getobj,
205 .alloc_size = sizeof(struct ref_instance)
206 }, {
207 .type = NULL
208 }
209 };
210  
211 const struct NCDModuleGroup ncdmodule_ref = {
212 .modules = modules
213 };