3 #include <emacs_module.h>
5 int plugin_is_GPL_compatible
;
8 * Always return symbol 't'
10 static emacs_value
Fmod_test_return_t (emacs_env
*env
, int nargs
, emacs_value args
[], void *data
)
12 return env
->intern (env
, "t");
17 * Expose simple sum function
19 static int64_t sum (int64_t a
, int64_t b
)
24 static emacs_value
Fmod_test_sum (emacs_env
*env
, int nargs
, emacs_value args
[], void* data
)
26 int64_t a
= env
->extract_integer (env
, args
[0]);
27 int64_t b
= env
->extract_integer (env
, args
[1]);
29 int64_t r
= sum(a
, b
);
31 return env
->make_integer (env
, r
);
38 static emacs_value
Fmod_test_signal (emacs_env
*env
, int nargs
, emacs_value args
[], void* data
)
40 assert (env
->non_local_exit_check (env
) == emacs_funcall_exit_return
);
41 env
->non_local_exit_signal (env
, env
->intern (env
, "error"), env
->make_integer (env
, 56));
49 static emacs_value
Fmod_test_throw (emacs_env
*env
, int nargs
, emacs_value args
[], void* data
)
51 assert (env
->non_local_exit_check (env
) == emacs_funcall_exit_return
);
52 env
->non_local_exit_throw (env
, env
->intern (env
, "tag"), env
->make_integer (env
, 65));
58 * Call argument function, catch all non-local exists and return
59 * either normal result or a list describing the non-local exit.
61 static emacs_value
Fmod_test_non_local_exit_funcall (emacs_env
*env
, int nargs
, emacs_value args
[], void* data
)
64 const emacs_value result
= env
->funcall (env
, args
[0], 0, NULL
);
65 emacs_value non_local_exit_symbol
, non_local_exit_data
;
66 enum emacs_funcall_exit code
= env
->non_local_exit_get (env
, &non_local_exit_symbol
, &non_local_exit_data
);
69 case emacs_funcall_exit_return
:
71 case emacs_funcall_exit_signal
:
73 env
->non_local_exit_clear (env
);
74 const emacs_value Flist
= env
->intern (env
, "list");
75 emacs_value list_args
[] = {env
->intern (env
, "signal"), non_local_exit_symbol
, non_local_exit_data
};
76 return env
->funcall (env
, Flist
, 3, list_args
);
78 case emacs_funcall_exit_throw
:
80 env
->non_local_exit_clear (env
);
81 const emacs_value Flist
= env
->intern (env
, "list");
82 emacs_value list_args
[] = {env
->intern (env
, "throw"), non_local_exit_symbol
, non_local_exit_data
};
83 return env
->funcall (env
, Flist
, 3, list_args
);
87 return env
->intern (env
, "nil");;
92 * Return a global referrence
94 static emacs_value
Fmod_test_globref_make (emacs_env
*env
, int nargs
, emacs_value args
[], void* data
)
96 /* make a big string and make it global */
100 for (i
= 0; i
< sizeof (str
); i
++)
102 str
[i
] = 'a' + (i
% 26);
105 /* we don't need to null-terminate str */
106 emacs_value lisp_str
= env
->make_string (env
, str
, sizeof (str
));
107 return env
->make_global_ref (env
, lisp_str
);
112 * Return a copy of the argument string where every 'a' is replaced with 'b'.
114 static emacs_value
Fmod_test_string_a_to_b (emacs_env
*env
, int nargs
, emacs_value args
[], void* data
)
116 emacs_value lisp_str
= args
[0];
121 env
->copy_string_contents (env
, lisp_str
, buf
, &size
);
123 env
->copy_string_contents (env
, lisp_str
, buf
, &size
);
125 for (i
= 0; i
+1 < size
; i
++) {
130 return env
->make_string (env
, buf
, size
-1);
135 * Embedded pointers in lisp objects.
138 /* C struct (pointer to) that will be embedded */
142 char large_unused_buffer
[512];
145 /* Associated finalizer */
146 static void finalizer (void *p
)
153 * Return a new user-pointer to a super_struct, with amazing_int set
154 * to the passed parameter.
156 static emacs_value
Fmod_test_userptr_make (emacs_env
*env
, int nargs
, emacs_value args
[], void *data
)
158 struct super_struct
*p
= calloc (1, sizeof(*p
));
159 p
->amazing_int
= env
->extract_integer (env
, args
[0]);
160 return env
->make_user_ptr (env
, finalizer
, p
);
164 * Return the amazing_int of a passed 'user-pointer to a super_struct'.
166 static emacs_value
Fmod_test_userptr_get (emacs_env
*env
, int nargs
, emacs_value args
[], void *data
)
168 struct super_struct
*p
= env
->get_user_ptr (env
, args
[0]);
169 return env
->make_integer (env
, p
->amazing_int
);
174 * Fill vector in args[0] with value in args[1]
176 static emacs_value
Fmod_test_vector_fill (emacs_env
*env
, int nargs
, emacs_value args
[], void *data
)
179 emacs_value vec
= args
[0];
180 emacs_value val
= args
[1];
181 const size_t size
= env
->vec_size (env
, vec
);
182 for (i
= 0; i
< size
; i
++)
183 env
->vec_set (env
, vec
, i
, val
);
184 return env
->intern (env
, "t");
189 * Return whether all elements of vector in args[0] are 'eq' to value in args[1]
191 static emacs_value
Fmod_test_vector_eq (emacs_env
*env
, int nargs
, emacs_value args
[], void *data
)
194 emacs_value vec
= args
[0];
195 emacs_value val
= args
[1];
196 const size_t size
= env
->vec_size (env
, vec
);
197 for (i
= 0; i
< size
; i
++)
198 if (!env
->eq (env
, env
->vec_get (env
, vec
, i
), val
))
199 return env
->intern (env
, "nil");
200 return env
->intern (env
, "t");
205 * Lisp utilities for easier readability (simple wrappers)
208 /* Provide FEATURE to Emacs */
209 static void provide (emacs_env
*env
, const char *feature
)
211 emacs_value Qfeat
= env
->intern (env
, feature
);
212 emacs_value Qprovide
= env
->intern (env
, "provide");
213 emacs_value args
[] = { Qfeat
};
215 env
->funcall (env
, Qprovide
, 1, args
);
218 /* Binds NAME to FUN */
219 static void bind_function (emacs_env
*env
, const char *name
, emacs_value Sfun
)
221 emacs_value Qfset
= env
->intern (env
, "fset");
222 emacs_value Qsym
= env
->intern (env
, name
);
223 emacs_value args
[] = { Qsym
, Sfun
};
225 env
->funcall (env
, Qfset
, 2, args
);
229 * Module init function.
231 int emacs_module_init (struct emacs_runtime
*ert
)
233 emacs_env
*env
= ert
->get_environment (ert
);
235 #define DEFUN(lsym, csym, amin, amax, doc, data) \
236 bind_function (env, lsym, env->make_function (env, amin, amax, csym, doc, data))
238 DEFUN ("mod-test-return-t", Fmod_test_return_t
, 1, 1, NULL
, NULL
);
239 DEFUN ("mod-test-sum", Fmod_test_sum
, 2, 2, "Return A + B", NULL
);
240 DEFUN ("mod-test-signal", Fmod_test_signal
, 0, 0, NULL
, NULL
);
241 DEFUN ("mod-test-throw", Fmod_test_throw
, 0, 0, NULL
, NULL
);
242 DEFUN ("mod-test-non-local-exit-funcall", Fmod_test_non_local_exit_funcall
, 1, 1, NULL
, NULL
);
243 DEFUN ("mod-test-globref-make", Fmod_test_globref_make
, 0, 0, NULL
, NULL
);
244 DEFUN ("mod-test-string-a-to-b", Fmod_test_string_a_to_b
, 1, 1, NULL
, NULL
);
245 DEFUN ("mod-test-userptr-make", Fmod_test_userptr_make
, 1, 1, NULL
, NULL
);
246 DEFUN ("mod-test-userptr-get", Fmod_test_userptr_get
, 1, 1, NULL
, NULL
);
247 DEFUN ("mod-test-vector-fill", Fmod_test_vector_fill
, 2, 2, NULL
, NULL
);
248 DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq
, 2, 2, NULL
, NULL
);
252 provide (env
, "mod-test");